feat: 完善插件系统和功能;修复增强查找功能;增加可视化自定义标题;
This commit is contained in:
parent
3e21be134c
commit
b66f802c3a
|
@ -128,7 +128,7 @@ private:
|
||||||
signals:
|
signals:
|
||||||
void documentChanged(QHexDocument *doc);
|
void documentChanged(QHexDocument *doc);
|
||||||
void cursorLocationChanged();
|
void cursorLocationChanged();
|
||||||
void cursorSelectionChanged(); // TODO
|
void cursorSelectionChanged();
|
||||||
void canUndoChanged(bool canUndo);
|
void canUndoChanged(bool canUndo);
|
||||||
void canRedoChanged(bool canRedo);
|
void canRedoChanged(bool canRedo);
|
||||||
void documentSaved(bool saved);
|
void documentSaved(bool saved);
|
||||||
|
|
|
@ -287,28 +287,28 @@
|
||||||
<translation>数据可视化</translation>
|
<translation>数据可视化</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../testform.cpp" line="345"/>
|
<location filename="../testform.cpp" line="348"/>
|
||||||
<location filename="../testform.cpp" line="355"/>
|
<location filename="../testform.cpp" line="359"/>
|
||||||
<source>UpdateTextTreeError</source>
|
<source>UpdateTextTreeError</source>
|
||||||
<translation>更新文本树失败</translation>
|
<translation>更新文本树失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../testform.cpp" line="370"/>
|
<location filename="../testform.cpp" line="374"/>
|
||||||
<source>UpdateTextListByModelError</source>
|
<source>UpdateTextListByModelError</source>
|
||||||
<translation>通过模型更新文本列表失败</translation>
|
<translation>通过模型更新文本列表失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../testform.cpp" line="380"/>
|
<location filename="../testform.cpp" line="384"/>
|
||||||
<source>UpdateTextTableByModelError</source>
|
<source>UpdateTextTableByModelError</source>
|
||||||
<translation>通过模型更新文本表格失败</translation>
|
<translation>通过模型更新文本表格失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../testform.cpp" line="391"/>
|
<location filename="../testform.cpp" line="395"/>
|
||||||
<source>UpdateTextTreeByModelError</source>
|
<source>UpdateTextTreeByModelError</source>
|
||||||
<translation>通过模型更新文本树失败</translation>
|
<translation>通过模型更新文本树失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../testform.cpp" line="492"/>
|
<location filename="../testform.cpp" line="496"/>
|
||||||
<source>Choose</source>
|
<source>Choose</source>
|
||||||
<translation>选择</translation>
|
<translation>选择</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -329,16 +329,19 @@ void TestForm::on_btnGetColor_clicked() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestForm::on_btnText_2_clicked() {
|
void TestForm::on_btnText_2_clicked() {
|
||||||
emit _plg->visual.updateText(ui->teDataVisual->toPlainText());
|
emit _plg->visual.updateText(ui->teDataVisual->toPlainText(),
|
||||||
|
QStringLiteral("TestForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestForm::on_btnTextList_clicked() {
|
void TestForm::on_btnTextList_clicked() {
|
||||||
auto txts = ui->teDataVisual->toPlainText().split('\n');
|
auto txts = ui->teDataVisual->toPlainText().split('\n');
|
||||||
emit _plg->visual.updateTextList(txts, _click, _dblclick);
|
emit _plg->visual.updateTextList(txts, QStringLiteral("TestForm"), _click,
|
||||||
|
_dblclick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestForm::on_btnTextTree_clicked() {
|
void TestForm::on_btnTextTree_clicked() {
|
||||||
auto ret = emit _plg->visual.updateTextTree(ui->teDataVisual->toPlainText(),
|
auto ret = emit _plg->visual.updateTextTree(ui->teDataVisual->toPlainText(),
|
||||||
|
QStringLiteral("TestForm"),
|
||||||
_click, _dblclick);
|
_click, _dblclick);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
||||||
|
@ -349,7 +352,8 @@ void TestForm::on_btnTextTree_clicked() {
|
||||||
void TestForm::on_btnTextTable_clicked() {
|
void TestForm::on_btnTextTable_clicked() {
|
||||||
auto ret = emit _plg->visual.updateTextTable(
|
auto ret = emit _plg->visual.updateTextTable(
|
||||||
ui->teDataVisual->toPlainText(),
|
ui->teDataVisual->toPlainText(),
|
||||||
{WingHex::WINGSUMMER, WingHex::WINGSUMMER}, {}, _click, _dblclick);
|
{WingHex::WINGSUMMER, WingHex::WINGSUMMER}, {},
|
||||||
|
QStringLiteral("TestForm"), _click, _dblclick);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
||||||
tr("UpdateTextTreeError"));
|
tr("UpdateTextTreeError"));
|
||||||
|
@ -363,8 +367,8 @@ void TestForm::on_btnTextListByModel_clicked() {
|
||||||
buffer.append(WingHex::WINGSUMMER % QString::number(i));
|
buffer.append(WingHex::WINGSUMMER % QString::number(i));
|
||||||
}
|
}
|
||||||
model->setStringList(buffer);
|
model->setStringList(buffer);
|
||||||
auto ret =
|
auto ret = emit _plg->visual.updateTextListByModel(
|
||||||
emit _plg->visual.updateTextListByModel(model, _click, _dblclick);
|
model, QStringLiteral("TestForm"), _click, _dblclick);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
||||||
tr("UpdateTextListByModelError"));
|
tr("UpdateTextListByModelError"));
|
||||||
|
@ -373,8 +377,8 @@ void TestForm::on_btnTextListByModel_clicked() {
|
||||||
|
|
||||||
void TestForm::on_btnTextTableByModel_clicked() {
|
void TestForm::on_btnTextTableByModel_clicked() {
|
||||||
auto model = new TestTableModel;
|
auto model = new TestTableModel;
|
||||||
auto ret =
|
auto ret = emit _plg->visual.updateTextTableByModel(
|
||||||
emit _plg->visual.updateTextTableByModel(model, _click, _dblclick);
|
model, QStringLiteral("TestForm"), _click, _dblclick);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
||||||
tr("UpdateTextTableByModelError"));
|
tr("UpdateTextTableByModelError"));
|
||||||
|
@ -384,8 +388,8 @@ void TestForm::on_btnTextTableByModel_clicked() {
|
||||||
void TestForm::on_btnTextTreeByModel_clicked() {
|
void TestForm::on_btnTextTreeByModel_clicked() {
|
||||||
auto model = new QFileSystemModel;
|
auto model = new QFileSystemModel;
|
||||||
model->setRootPath(QDir::currentPath());
|
model->setRootPath(QDir::currentPath());
|
||||||
auto ret =
|
auto ret = emit _plg->visual.updateTextTreeByModel(
|
||||||
emit _plg->visual.updateTextTreeByModel(model, _click, _dblclick);
|
model, QStringLiteral("TestForm"), _click, _dblclick);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
|
||||||
tr("UpdateTextTreeByModelError"));
|
tr("UpdateTextTreeByModelError"));
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -186,7 +186,7 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (rbegin->content == DOT_TRIGGER) {
|
} else if (rbegin->content == DOT_TRIGGER) {
|
||||||
// TODO
|
// TODO only PR
|
||||||
} else {
|
} else {
|
||||||
applyEmptyNsNode(nodes);
|
applyEmptyNsNode(nodes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/*==============================================================================
|
||||||
|
** 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 "richtextitemdelegate.h"
|
#include "richtextitemdelegate.h"
|
||||||
|
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
@ -11,44 +28,64 @@ RichTextItemDelegate::RichTextItemDelegate(QObject *parent)
|
||||||
void RichTextItemDelegate::paint(QPainter *painter,
|
void RichTextItemDelegate::paint(QPainter *painter,
|
||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const {
|
const QModelIndex &index) const {
|
||||||
auto options = option;
|
if (!index.isValid())
|
||||||
initStyleOption(&options, index);
|
return;
|
||||||
|
|
||||||
painter->save();
|
// Get the rich text content
|
||||||
|
QString text = index.data(Qt::DisplayRole).toString();
|
||||||
|
if (text.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get alignment
|
||||||
|
QVariant alignmentVariant = index.data(Qt::TextAlignmentRole);
|
||||||
|
Qt::Alignment alignment = alignmentVariant.isValid()
|
||||||
|
? Qt::Alignment(alignmentVariant.toInt())
|
||||||
|
: Qt::AlignLeft;
|
||||||
|
|
||||||
|
// Set up a QTextDocument to render the HTML content
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
doc.setHtml(options.text);
|
doc.setHtml(text);
|
||||||
|
|
||||||
options.text.clear();
|
// Disable word wrapping
|
||||||
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options,
|
QTextOption textOption;
|
||||||
painter);
|
textOption.setWrapMode(QTextOption::NoWrap);
|
||||||
|
doc.setDefaultTextOption(textOption);
|
||||||
|
|
||||||
// shift text right to make icon visible
|
// Clip the painter to the cell rectangle
|
||||||
QSize iconSize = options.icon.actualSize(options.rect.size());
|
painter->save();
|
||||||
painter->translate(options.rect.left() + iconSize.width(),
|
painter->setClipRect(option.rect);
|
||||||
options.rect.top());
|
|
||||||
QRect clip(0, 0, options.rect.width() + iconSize.width(),
|
|
||||||
options.rect.height());
|
|
||||||
|
|
||||||
painter->setClipRect(clip);
|
// Calculate the rendering rectangle based on alignment
|
||||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
QRect rect = option.rect;
|
||||||
// set text color to red for selected item
|
QSize contentSize = doc.size().toSize();
|
||||||
if (option.state & QStyle::State_Selected)
|
if (alignment & Qt::AlignHCenter) {
|
||||||
ctx.palette.setColor(QPalette::Text, Qt::red);
|
rect.setLeft(rect.left() + (rect.width() - contentSize.width()) / 2);
|
||||||
|
} else if (alignment & Qt::AlignRight) {
|
||||||
|
rect.setLeft(rect.right() - contentSize.width());
|
||||||
|
}
|
||||||
|
|
||||||
ctx.clip = clip;
|
if (alignment & Qt::AlignVCenter) {
|
||||||
doc.documentLayout()->draw(painter, ctx);
|
rect.setTop(rect.top() + (rect.height() - contentSize.height()) / 2);
|
||||||
|
} else if (alignment & Qt::AlignBottom) {
|
||||||
|
rect.setTop(rect.bottom() - contentSize.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the document in the adjusted rectangle
|
||||||
|
painter->translate(rect.topLeft());
|
||||||
|
doc.setTextWidth(option.rect.width());
|
||||||
|
doc.drawContents(painter);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize RichTextItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
QSize RichTextItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const {
|
const QModelIndex &index) const {
|
||||||
auto options = option;
|
QString text = index.data(Qt::DisplayRole).toString();
|
||||||
initStyleOption(&options, index);
|
if (text.isEmpty())
|
||||||
|
return QStyledItemDelegate::sizeHint(option, index);
|
||||||
|
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
doc.setHtml(options.text);
|
doc.setHtml(text);
|
||||||
doc.setTextWidth(options.rect.width());
|
doc.setTextWidth(option.rect.width());
|
||||||
return QSize(doc.idealWidth(), doc.size().height());
|
return doc.size().toSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/*==============================================================================
|
||||||
|
** 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 RICHTEXTITEMDELEGATE_H
|
#ifndef RICHTEXTITEMDELEGATE_H
|
||||||
#define RICHTEXTITEMDELEGATE_H
|
#define RICHTEXTITEMDELEGATE_H
|
||||||
|
|
||||||
|
|
|
@ -186,9 +186,6 @@ bool ScriptConsoleMachine::execString(asIScriptEngine *engine,
|
||||||
info.message = str;
|
info.message = str;
|
||||||
emit onOutput(MessageType::Info, info);
|
emit onOutput(MessageType::Info, info);
|
||||||
return true;
|
return true;
|
||||||
} else if (code.startsWith(QStringLiteral("import "))) {
|
|
||||||
// TODO
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
return ExecuteString(engine, code.toUtf8(), mod, immediateContext()) >=
|
return ExecuteString(engine, code.toUtf8(), mod, immediateContext()) >=
|
||||||
0;
|
0;
|
||||||
|
|
|
@ -80,6 +80,17 @@ const QString WingAngelAPI::pluginComment() const {
|
||||||
"ability to call the host API.");
|
"ability to call the host API.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WingAngelAPI::registerScriptEnums(
|
||||||
|
const QString &ns, const QHash<QString, QList<QPair<QString, int>>> &objs) {
|
||||||
|
Q_ASSERT(!ns.isEmpty());
|
||||||
|
if (objs.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check it later
|
||||||
|
_objs.insert(ns, objs);
|
||||||
|
}
|
||||||
|
|
||||||
void WingAngelAPI::registerScriptFns(const QString &ns,
|
void WingAngelAPI::registerScriptFns(const QString &ns,
|
||||||
const QHash<QString, ScriptFnInfo> &rfns) {
|
const QHash<QString, ScriptFnInfo> &rfns) {
|
||||||
Q_ASSERT(!ns.isEmpty());
|
Q_ASSERT(!ns.isEmpty());
|
||||||
|
@ -115,6 +126,7 @@ void WingAngelAPI::installAPI(ScriptMachine *machine) {
|
||||||
installDataVisualAPI(engine, stringTypeID);
|
installDataVisualAPI(engine, stringTypeID);
|
||||||
|
|
||||||
installScriptFns(engine);
|
installScriptFns(engine);
|
||||||
|
installScriptEnums(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingAngelAPI::installLogAPI(asIScriptEngine *engine) {
|
void WingAngelAPI::installLogAPI(asIScriptEngine *engine) {
|
||||||
|
@ -1107,34 +1119,35 @@ void WingAngelAPI::installDataVisualAPI(asIScriptEngine *engine, int stringID) {
|
||||||
|
|
||||||
auto datavis = &this->visual;
|
auto datavis = &this->visual;
|
||||||
|
|
||||||
registerAPI<bool(const QString &)>(
|
registerAPI<bool(const QString &, const QString &)>(
|
||||||
engine,
|
engine,
|
||||||
std::bind(&WingHex::WingPlugin::DataVisual::updateText, datavis,
|
std::bind(&WingHex::WingPlugin::DataVisual::updateText, datavis,
|
||||||
std::placeholders::_1),
|
std::placeholders::_1, std::placeholders::_2),
|
||||||
"bool updateText(string &in data)");
|
"bool updateText(string &in data, string &in title=\"\")");
|
||||||
|
|
||||||
registerAPI<bool(const CScriptArray &)>(
|
registerAPI<bool(const CScriptArray &, const QString &)>(
|
||||||
engine,
|
engine,
|
||||||
std::bind(&WingAngelAPI::_DataVisual_updateTextList, this, stringID,
|
std::bind(&WingAngelAPI::_DataVisual_updateTextList, this, stringID,
|
||||||
std::placeholders::_1),
|
std::placeholders::_1, std::placeholders::_2),
|
||||||
"bool updateTextList(array<string> &in data)");
|
"bool updateTextList(array<string> &in data, string &in title=\"\")");
|
||||||
|
|
||||||
registerAPI<bool(const QString &)>(
|
registerAPI<bool(const QString &, const QString &)>(
|
||||||
engine,
|
engine,
|
||||||
std::bind(&WingHex::WingPlugin::DataVisual::updateTextTree, datavis,
|
std::bind(&WingHex::WingPlugin::DataVisual::updateTextTree, datavis,
|
||||||
std::placeholders::_1,
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack(),
|
WingHex::WingPlugin::DataVisual::ClickedCallBack(),
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack()),
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack()),
|
||||||
"bool updateTextTree(string &in json)");
|
"bool updateTextTree(string &in json, string &in title=\"\")");
|
||||||
|
|
||||||
registerAPI<bool(const QString &, const CScriptArray &,
|
registerAPI<bool(const QString &, const CScriptArray &,
|
||||||
const CScriptArray &)>(
|
const CScriptArray &, const QString &)>(
|
||||||
engine,
|
engine,
|
||||||
std::bind(&WingAngelAPI::_DataVisual_updateTextTable, this, stringID,
|
std::bind(&WingAngelAPI::_DataVisual_updateTextTable, this, stringID,
|
||||||
std::placeholders::_1, std::placeholders::_2,
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
std::placeholders::_3),
|
std::placeholders::_3, std::placeholders::_4),
|
||||||
"bool updateTextTable(string &in json, array<string> &in headers, "
|
"bool updateTextTable(string &in json, array<string> &in headers, "
|
||||||
"array<string> &in headerNames = array<string>())");
|
"array<string> &in headerNames = array<string>(), string &in "
|
||||||
|
"title=\"\")");
|
||||||
|
|
||||||
engine->SetDefaultNamespace("");
|
engine->SetDefaultNamespace("");
|
||||||
}
|
}
|
||||||
|
@ -1169,6 +1182,40 @@ void WingAngelAPI::installScriptFns(asIScriptEngine *engine) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WingAngelAPI::installScriptEnums(asIScriptEngine *engine) {
|
||||||
|
for (auto pobjs = _objs.constKeyValueBegin();
|
||||||
|
pobjs != _objs.constKeyValueEnd(); ++pobjs) {
|
||||||
|
auto ns = pobjs->first;
|
||||||
|
int r = engine->SetDefaultNamespace(ns.toUtf8());
|
||||||
|
Q_ASSERT(r >= 0);
|
||||||
|
Q_UNUSED(r);
|
||||||
|
|
||||||
|
auto &pobj = pobjs->second;
|
||||||
|
for (auto p = pobj.constKeyValueBegin(); p != pobj.constKeyValueEnd();
|
||||||
|
p++) {
|
||||||
|
auto en = p->first.toUtf8();
|
||||||
|
r = engine->RegisterEnum(en.data());
|
||||||
|
if (r < 0) {
|
||||||
|
emit warn(tr("InvalidEnumName:") + p->first);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e : p->second) {
|
||||||
|
auto ev = e.first.toUtf8();
|
||||||
|
r = engine->RegisterEnumValue(en.data(), ev.data(), e.second);
|
||||||
|
if (r < 0) {
|
||||||
|
emit warn(tr("InvalidEnumValue:") % p->first %
|
||||||
|
QStringLiteral("::") % e.first %
|
||||||
|
QStringLiteral(" (") % QString::number(e.second) %
|
||||||
|
QStringLiteral(")"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
engine->SetDefaultNamespace("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QStringList WingAngelAPI::cArray2QStringList(const CScriptArray &array,
|
QStringList WingAngelAPI::cArray2QStringList(const CScriptArray &array,
|
||||||
int stringID, bool *ok) {
|
int stringID, bool *ok) {
|
||||||
bool b = array.GetElementTypeId() == stringID;
|
bool b = array.GetElementTypeId() == stringID;
|
||||||
|
@ -1653,7 +1700,8 @@ void WingAngelAPI::script_call(asIScriptGeneric *gen) {
|
||||||
std::bind(op, gen, std::placeholders::_1, std::placeholders::_2));
|
std::bind(op, gen, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingAngelAPI::execScriptCode(const QString &code) {
|
bool WingAngelAPI::execScriptCode(const WingHex::SenderInfo &sender,
|
||||||
|
const QString &code) {
|
||||||
if (code.isEmpty()) {
|
if (code.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1666,9 +1714,7 @@ bool WingAngelAPI::execScriptCode(const QString &code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_console->setMode(ScriptingConsole::Output);
|
_console->setMode(ScriptingConsole::Output);
|
||||||
_console->write(QStringLiteral("(") %
|
_console->write(getSenderHeader(sender));
|
||||||
property("__LAST_CALLER__").toString() %
|
|
||||||
QStringLiteral(") "));
|
|
||||||
_console->machine()->executeScript(f.fileName());
|
_console->machine()->executeScript(f.fileName());
|
||||||
_console->appendCommandPrompt();
|
_console->appendCommandPrompt();
|
||||||
_console->setMode(ScriptingConsole::Input);
|
_console->setMode(ScriptingConsole::Input);
|
||||||
|
@ -1677,28 +1723,31 @@ bool WingAngelAPI::execScriptCode(const QString &code) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingAngelAPI::execScript(const QString &fileName) {
|
bool WingAngelAPI::execScript(const WingHex::SenderInfo &sender,
|
||||||
|
const QString &fileName) {
|
||||||
_console->setMode(ScriptingConsole::Output);
|
_console->setMode(ScriptingConsole::Output);
|
||||||
_console->write(QStringLiteral("(") %
|
_console->write(getSenderHeader(sender));
|
||||||
property("__LAST_CALLER__").toString() %
|
|
||||||
QStringLiteral(") "));
|
|
||||||
auto ret = _console->machine()->executeScript(fileName);
|
auto ret = _console->machine()->executeScript(fileName);
|
||||||
_console->appendCommandPrompt();
|
_console->appendCommandPrompt();
|
||||||
_console->setMode(ScriptingConsole::Input);
|
_console->setMode(ScriptingConsole::Input);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingAngelAPI::execCode(const QString &code) {
|
bool WingAngelAPI::execCode(const WingHex::SenderInfo &sender,
|
||||||
|
const QString &code) {
|
||||||
_console->setMode(ScriptingConsole::Output);
|
_console->setMode(ScriptingConsole::Output);
|
||||||
_console->write(QStringLiteral("(") %
|
_console->write(getSenderHeader(sender));
|
||||||
property("__LAST_CALLER__").toString() %
|
|
||||||
QStringLiteral(") "));
|
|
||||||
auto ret = _console->machine()->executeCode(code);
|
auto ret = _console->machine()->executeCode(code);
|
||||||
_console->appendCommandPrompt();
|
_console->appendCommandPrompt();
|
||||||
_console->setMode(ScriptingConsole::Input);
|
_console->setMode(ScriptingConsole::Input);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WingAngelAPI::getSenderHeader(const WingHex::SenderInfo &sender) {
|
||||||
|
return QStringLiteral("(") % sender.puid % QStringLiteral("::") %
|
||||||
|
sender.plgcls % QStringLiteral(") ");
|
||||||
|
}
|
||||||
|
|
||||||
QString WingAngelAPI::_InputBox_getItem(int stringID, const QString &title,
|
QString WingAngelAPI::_InputBox_getItem(int stringID, const QString &title,
|
||||||
const QString &label,
|
const QString &label,
|
||||||
const CScriptArray &items, int current,
|
const CScriptArray &items, int current,
|
||||||
|
@ -1923,25 +1972,28 @@ bool WingAngelAPI::_HexController_appendBytes(const CScriptArray &ba) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingAngelAPI::_DataVisual_updateTextList(int stringID,
|
bool WingAngelAPI::_DataVisual_updateTextList(int stringID,
|
||||||
const CScriptArray &data) {
|
const CScriptArray &data,
|
||||||
|
const QString &title) {
|
||||||
bool o = false;
|
bool o = false;
|
||||||
auto ret = cArray2QStringList(data, stringID, &o);
|
auto ret = cArray2QStringList(data, stringID, &o);
|
||||||
if (o) {
|
if (o) {
|
||||||
return emit visual.updateTextList(ret);
|
return emit visual.updateTextList(ret, title);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WingAngelAPI::_DataVisual_updateTextTable(
|
bool WingAngelAPI::_DataVisual_updateTextTable(int stringID,
|
||||||
int stringID, const QString &json, const CScriptArray &headers,
|
const QString &json,
|
||||||
const CScriptArray &headerNames) {
|
const CScriptArray &headers,
|
||||||
|
const CScriptArray &headerNames,
|
||||||
|
const QString &title) {
|
||||||
bool o = false;
|
bool o = false;
|
||||||
auto h = cArray2QStringList(headers, stringID, &o);
|
auto h = cArray2QStringList(headers, stringID, &o);
|
||||||
if (o) {
|
if (o) {
|
||||||
auto hn = cArray2QStringList(headerNames, stringID, &o);
|
auto hn = cArray2QStringList(headerNames, stringID, &o);
|
||||||
if (o) {
|
if (o) {
|
||||||
return emit visual.updateTextTable(json, h, hn);
|
return emit visual.updateTextTable(json, h, hn, title);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,10 @@ public:
|
||||||
registerScriptFns(const QString &ns,
|
registerScriptFns(const QString &ns,
|
||||||
const QHash<QString, IWingPlugin::ScriptFnInfo> &rfns);
|
const QHash<QString, IWingPlugin::ScriptFnInfo> &rfns);
|
||||||
|
|
||||||
|
void
|
||||||
|
registerScriptEnums(const QString &ns,
|
||||||
|
const QHash<QString, QList<QPair<QString, int>>> &objs);
|
||||||
|
|
||||||
void installAPI(ScriptMachine *machine);
|
void installAPI(ScriptMachine *machine);
|
||||||
|
|
||||||
ScriptingConsole *bindingConsole() const;
|
ScriptingConsole *bindingConsole() const;
|
||||||
|
@ -69,6 +73,7 @@ private:
|
||||||
void installHexControllerAPI(asIScriptEngine *engine);
|
void installHexControllerAPI(asIScriptEngine *engine);
|
||||||
void installDataVisualAPI(asIScriptEngine *engine, int stringID);
|
void installDataVisualAPI(asIScriptEngine *engine, int stringID);
|
||||||
void installScriptFns(asIScriptEngine *engine);
|
void installScriptFns(asIScriptEngine *engine);
|
||||||
|
void installScriptEnums(asIScriptEngine *engine);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -122,9 +127,14 @@ private:
|
||||||
static void script_call(asIScriptGeneric *gen);
|
static void script_call(asIScriptGeneric *gen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WING_SERVICE bool execScriptCode(const QString &code);
|
WING_SERVICE bool execScriptCode(const WingHex::SenderInfo &sender,
|
||||||
WING_SERVICE bool execScript(const QString &fileName);
|
const QString &code);
|
||||||
WING_SERVICE bool execCode(const QString &code);
|
WING_SERVICE bool execScript(const WingHex::SenderInfo &sender,
|
||||||
|
const QString &fileName);
|
||||||
|
WING_SERVICE bool execCode(const WingHex::SenderInfo &sender,
|
||||||
|
const QString &code);
|
||||||
|
|
||||||
|
QString getSenderHeader(const WingHex::SenderInfo &sender);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _InputBox_getItem(int stringID, const QString &title,
|
QString _InputBox_getItem(int stringID, const QString &title,
|
||||||
|
@ -164,11 +174,13 @@ private:
|
||||||
|
|
||||||
bool _HexController_appendBytes(const CScriptArray &ba);
|
bool _HexController_appendBytes(const CScriptArray &ba);
|
||||||
|
|
||||||
bool _DataVisual_updateTextList(int stringID, const CScriptArray &data);
|
bool _DataVisual_updateTextList(int stringID, const CScriptArray &data,
|
||||||
|
const QString &title);
|
||||||
|
|
||||||
bool _DataVisual_updateTextTable(int stringID, const QString &json,
|
bool _DataVisual_updateTextTable(int stringID, const QString &json,
|
||||||
const CScriptArray &headers,
|
const CScriptArray &headers,
|
||||||
const CScriptArray &headerNames);
|
const CScriptArray &headerNames,
|
||||||
|
const QString &title);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::any> _fnbuffer;
|
std::vector<std::any> _fnbuffer;
|
||||||
|
@ -177,6 +189,7 @@ private:
|
||||||
ScriptingConsole *_console = nullptr;
|
ScriptingConsole *_console = nullptr;
|
||||||
|
|
||||||
QHash<QString, QHash<QString, qsizetype>> _rfns;
|
QHash<QString, QHash<QString, qsizetype>> _rfns;
|
||||||
|
QHash<QString, QHash<QString, QList<QPair<QString, int>>>> _objs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINGANGELAPI_H
|
#endif // WINGANGELAPI_H
|
||||||
|
|
|
@ -210,26 +210,20 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
|
||||||
m_findResults->clear();
|
m_findResults->clear();
|
||||||
|
|
||||||
auto lineWidth = m_hex->renderer()->hexLineWidth();
|
auto lineWidth = m_hex->renderer()->hexLineWidth();
|
||||||
|
auto docLen = d->length();
|
||||||
for (auto &ritem : results) {
|
for (auto &ritem : results) {
|
||||||
FindResult r;
|
FindResult r;
|
||||||
r.offset = ritem;
|
r.offset = ritem;
|
||||||
r.line = r.offset / lineWidth;
|
r.line = r.offset / lineWidth;
|
||||||
r.col = r.offset % lineWidth;
|
r.col = r.offset % lineWidth;
|
||||||
m_findResults->results().append(r);
|
m_findResults->results().append(r);
|
||||||
|
m_findResults->findData().append(
|
||||||
QString content;
|
readContextFinding(ritem, data.size(), FIND_CONTEXT_SIZE,
|
||||||
QByteArray buffer;
|
FIND_MAX_DISPLAY_FIND_CHARS));
|
||||||
// TODO
|
|
||||||
FindResultModel::FindInfo info;
|
|
||||||
|
|
||||||
// default show lineWidth count
|
|
||||||
if (data.size() > lineWidth - 4) {
|
|
||||||
}
|
|
||||||
|
|
||||||
info.decoding = Utilities::decodingString(buffer, result.encoding);
|
|
||||||
m_findResults->lastFindData().append(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_findResults->lastFindData() = data;
|
||||||
|
|
||||||
m_findResults->endUpdate();
|
m_findResults->endUpdate();
|
||||||
|
|
||||||
if (m_findResults->size() ==
|
if (m_findResults->size() ==
|
||||||
|
@ -612,6 +606,37 @@ QHash<QString, QByteArray> EditorView::savePluginData() {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FindResultModel::FindInfo EditorView::readContextFinding(qsizetype offset,
|
||||||
|
qsizetype findSize,
|
||||||
|
int contextSize,
|
||||||
|
int maxDisplayBytes) {
|
||||||
|
auto doc = m_hex->document();
|
||||||
|
|
||||||
|
qsizetype halfSize = maxDisplayBytes / 2;
|
||||||
|
auto header = doc->read(offset, qMin(findSize, halfSize));
|
||||||
|
QByteArray tailer;
|
||||||
|
if (header.size() < findSize) {
|
||||||
|
tailer = doc->read(
|
||||||
|
offset, qMin(findSize, qsizetype(maxDisplayBytes) - halfSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto left = qsizetype(maxDisplayBytes) - header.size() - tailer.size();
|
||||||
|
|
||||||
|
// append to contextSize
|
||||||
|
contextSize += (left / 2);
|
||||||
|
|
||||||
|
auto cheader = doc->read(offset - contextSize, contextSize);
|
||||||
|
auto ctailer = doc->read(offset + findSize, contextSize);
|
||||||
|
|
||||||
|
FindResultModel::FindInfo info;
|
||||||
|
info.cheader = cheader;
|
||||||
|
info.hbuffer = header;
|
||||||
|
info.tbuffer = tailer;
|
||||||
|
info.ctailer = ctailer;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
EditorView *EditorView::cloneParent() const { return m_cloneParent; }
|
EditorView *EditorView::cloneParent() const { return m_cloneParent; }
|
||||||
|
|
||||||
bool EditorView::isCloned() const { return m_cloneParent != nullptr; }
|
bool EditorView::isCloned() const { return m_cloneParent != nullptr; }
|
||||||
|
|
|
@ -125,6 +125,11 @@ private:
|
||||||
void applyPluginData(const QHash<QString, QByteArray> &data);
|
void applyPluginData(const QHash<QString, QByteArray> &data);
|
||||||
QHash<QString, QByteArray> savePluginData();
|
QHash<QString, QByteArray> savePluginData();
|
||||||
|
|
||||||
|
FindResultModel::FindInfo readContextFinding(qsizetype offset,
|
||||||
|
qsizetype findSize,
|
||||||
|
int contextSize,
|
||||||
|
int maxDisplayBytes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
inline void newAction(QWidget *parent, const QString &icon,
|
inline void newAction(QWidget *parent, const QString &icon,
|
||||||
|
|
|
@ -67,14 +67,14 @@ FindDialog::FindDialog(const FindInfo &info, QWidget *parent)
|
||||||
if (info.isStringFind) {
|
if (info.isStringFind) {
|
||||||
m_string->setChecked(true);
|
m_string->setChecked(true);
|
||||||
m_lineeditor->setEnabled(true);
|
m_lineeditor->setEnabled(true);
|
||||||
m_hex->setEnabled(false);
|
m_hexeditor->setEnabled(false);
|
||||||
if (!info.encoding.isEmpty()) {
|
if (!info.encoding.isEmpty()) {
|
||||||
m_encodings->setCurrentText(info.encoding);
|
m_encodings->setCurrentText(info.encoding);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_hex->setChecked(true);
|
m_hex->setChecked(true);
|
||||||
m_lineeditor->setEnabled(false);
|
m_lineeditor->setEnabled(false);
|
||||||
m_hex->setEnabled(true);
|
m_hexeditor->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_lineeditor->setText(info.str);
|
m_lineeditor->setText(info.str);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "aboutsoftwaredialog.h"
|
#include "aboutsoftwaredialog.h"
|
||||||
#include "checksumdialog.h"
|
#include "checksumdialog.h"
|
||||||
#include "class/appmanager.h"
|
#include "class/appmanager.h"
|
||||||
|
#include "class/eventfilter.h"
|
||||||
#include "class/langservice.h"
|
#include "class/langservice.h"
|
||||||
#include "class/languagemanager.h"
|
#include "class/languagemanager.h"
|
||||||
#include "class/layoutmanager.h"
|
#include "class/layoutmanager.h"
|
||||||
|
@ -480,6 +481,7 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
|
||||||
m_findresult->setProperty("EditorView", quintptr(0));
|
m_findresult->setProperty("EditorView", quintptr(0));
|
||||||
|
|
||||||
Utilities::applyTableViewProperty(m_findresult);
|
Utilities::applyTableViewProperty(m_findresult);
|
||||||
|
auto header = m_findresult->horizontalHeader();
|
||||||
|
|
||||||
m_findresult->setContextMenuPolicy(
|
m_findresult->setContextMenuPolicy(
|
||||||
Qt::ContextMenuPolicy::ActionsContextMenu);
|
Qt::ContextMenuPolicy::ActionsContextMenu);
|
||||||
|
@ -494,6 +496,9 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
|
||||||
|
|
||||||
m_findresult->setModel(_findEmptyResult);
|
m_findresult->setModel(_findEmptyResult);
|
||||||
|
|
||||||
|
header->setSectionResizeMode(3, QHeaderView::Stretch);
|
||||||
|
header->setSectionResizeMode(4, QHeaderView::Stretch);
|
||||||
|
|
||||||
connect(m_findresult, &QTableView::doubleClicked, this,
|
connect(m_findresult, &QTableView::doubleClicked, this,
|
||||||
[=](const QModelIndex &index) {
|
[=](const QModelIndex &index) {
|
||||||
auto editor =
|
auto editor =
|
||||||
|
@ -779,6 +784,29 @@ MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
|
||||||
ads::CDockAreaWidget *areaw) {
|
ads::CDockAreaWidget *areaw) {
|
||||||
using namespace ads;
|
using namespace ads;
|
||||||
|
|
||||||
|
auto efilter = new EventFilter(QEvent::DynamicPropertyChange, this);
|
||||||
|
connect(efilter, &EventFilter::eventTriggered, this,
|
||||||
|
[this](QObject *obj, QEvent *event) {
|
||||||
|
auto e = static_cast<QDynamicPropertyChangeEvent *>(event);
|
||||||
|
constexpr auto ppname = "__TITLE__";
|
||||||
|
if (e->propertyName() == QByteArray(ppname)) {
|
||||||
|
auto title = obj->property(ppname).toString();
|
||||||
|
auto display = obj->property("__DISPLAY__").toString();
|
||||||
|
auto dock = reinterpret_cast<QDockWidget *>(
|
||||||
|
obj->property("__DOCK__").value<quintptr>());
|
||||||
|
if (dock) {
|
||||||
|
if (!title.isEmpty()) {
|
||||||
|
display += QStringLiteral("(") % title %
|
||||||
|
QStringLiteral(")");
|
||||||
|
}
|
||||||
|
dock->setWindowTitle(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
constexpr auto dpname = "__DISPLAY__";
|
||||||
|
constexpr auto dockpname = "__DOCK__";
|
||||||
|
|
||||||
m_infolist = new QListView(this);
|
m_infolist = new QListView(this);
|
||||||
m_infolist->setEditTriggers(QListView::EditTrigger::NoEditTriggers);
|
m_infolist->setEditTriggers(QListView::EditTrigger::NoEditTriggers);
|
||||||
connect(m_infolist, &QListView::clicked, this,
|
connect(m_infolist, &QListView::clicked, this,
|
||||||
|
@ -795,6 +823,10 @@ MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
|
||||||
});
|
});
|
||||||
auto dw = buildDockWidget(dock, QStringLiteral("DVList"), tr("DVList"),
|
auto dw = buildDockWidget(dock, QStringLiteral("DVList"), tr("DVList"),
|
||||||
m_infolist);
|
m_infolist);
|
||||||
|
m_infolist->setProperty(dpname, tr("DVList"));
|
||||||
|
m_infolist->setProperty(dockpname, quintptr(dw));
|
||||||
|
m_infolist->installEventFilter(efilter);
|
||||||
|
|
||||||
auto ar = dock->addDockWidget(area, dw, areaw);
|
auto ar = dock->addDockWidget(area, dw, areaw);
|
||||||
|
|
||||||
m_infotree = new QTreeView(this);
|
m_infotree = new QTreeView(this);
|
||||||
|
@ -813,6 +845,9 @@ MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
|
||||||
});
|
});
|
||||||
dw = buildDockWidget(dock, QStringLiteral("DVTree"), tr("DVTree"),
|
dw = buildDockWidget(dock, QStringLiteral("DVTree"), tr("DVTree"),
|
||||||
m_infotree);
|
m_infotree);
|
||||||
|
m_infotree->setProperty(dpname, tr("DVTree"));
|
||||||
|
m_infotree->setProperty(dockpname, quintptr(dw));
|
||||||
|
m_infotree->installEventFilter(efilter);
|
||||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||||
|
|
||||||
m_infotable = new QTableView(this);
|
m_infotable = new QTableView(this);
|
||||||
|
@ -831,11 +866,17 @@ MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
|
||||||
});
|
});
|
||||||
dw = buildDockWidget(dock, QStringLiteral("DVTable"), tr("DVTable"),
|
dw = buildDockWidget(dock, QStringLiteral("DVTable"), tr("DVTable"),
|
||||||
m_infotable);
|
m_infotable);
|
||||||
|
m_infotable->setProperty(dpname, tr("DVTable"));
|
||||||
|
m_infotable->setProperty(dockpname, quintptr(dw));
|
||||||
|
m_infotable->installEventFilter(efilter);
|
||||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||||
|
|
||||||
m_infotxt = new QTextBrowser(this);
|
m_infotxt = new QTextBrowser(this);
|
||||||
dw = buildDockWidget(dock, QStringLiteral("DVText"), tr("DVText"),
|
dw = buildDockWidget(dock, QStringLiteral("DVText"), tr("DVText"),
|
||||||
m_infotxt);
|
m_infotxt);
|
||||||
|
m_infotxt->setProperty(dpname, tr("DVText"));
|
||||||
|
m_infotxt->setProperty(dockpname, quintptr(dw));
|
||||||
|
m_infotxt->installEventFilter(efilter);
|
||||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||||
|
|
||||||
return ar;
|
return ar;
|
||||||
|
@ -2270,8 +2311,8 @@ void MainWindow::on_exportfindresult() {
|
||||||
tr("EmptyFindResult"));
|
tr("EmptyFindResult"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto filename = WingFileDialog::getSaveFileName(this, tr("ChooseSaveFile"),
|
auto filename = WingFileDialog::getSaveFileName(
|
||||||
m_lastusedpath);
|
this, tr("ChooseSaveFile"), m_lastusedpath, {"Json (*.json)"});
|
||||||
if (filename.isEmpty())
|
if (filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
m_lastusedpath = QFileInfo(filename).absoluteDir().absolutePath();
|
m_lastusedpath = QFileInfo(filename).absoluteDir().absolutePath();
|
||||||
|
@ -2281,9 +2322,10 @@ void MainWindow::on_exportfindresult() {
|
||||||
QJsonObject fobj;
|
QJsonObject fobj;
|
||||||
fobj.insert(QStringLiteral("file"), editor->fileName());
|
fobj.insert(QStringLiteral("file"), editor->fileName());
|
||||||
|
|
||||||
// auto d= findresitem->lastFindData();
|
auto d = findresitem->lastFindData();
|
||||||
|
|
||||||
// fobj.insert(QStringLiteral("data"), findresitem->lastFindData());
|
fobj.insert(QStringLiteral("find"),
|
||||||
|
QString::fromLatin1(d.toHex(' ').toUpper()));
|
||||||
QJsonArray arr;
|
QJsonArray arr;
|
||||||
for (int i = 0; i < c; i++) {
|
for (int i = 0; i < c; i++) {
|
||||||
auto data = findresitem->resultAt(i);
|
auto data = findresitem->resultAt(i);
|
||||||
|
@ -2291,6 +2333,18 @@ void MainWindow::on_exportfindresult() {
|
||||||
jobj.insert(QStringLiteral("line"), QString::number(data.line));
|
jobj.insert(QStringLiteral("line"), QString::number(data.line));
|
||||||
jobj.insert(QStringLiteral("col"), QString::number(data.col));
|
jobj.insert(QStringLiteral("col"), QString::number(data.col));
|
||||||
jobj.insert(QStringLiteral("offset"), QString::number(data.offset));
|
jobj.insert(QStringLiteral("offset"), QString::number(data.offset));
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml(
|
||||||
|
findresitem->data(findresitem->index(i, 3), Qt::DisplayRole)
|
||||||
|
.toString());
|
||||||
|
jobj.insert(QStringLiteral("range"), doc.toPlainText());
|
||||||
|
|
||||||
|
doc.setHtml(
|
||||||
|
findresitem->data(findresitem->index(i, 4), Qt::DisplayRole)
|
||||||
|
.toString());
|
||||||
|
jobj.insert(QStringLiteral("encoding"), doc.toPlainText());
|
||||||
|
|
||||||
arr.append(jobj);
|
arr.append(jobj);
|
||||||
}
|
}
|
||||||
fobj.insert(QStringLiteral("data"), arr);
|
fobj.insert(QStringLiteral("data"), arr);
|
||||||
|
|
|
@ -629,6 +629,7 @@ ScriptingDialog::buildSymbolShowDock(ads::CDockManager *dock,
|
||||||
ads::CDockAreaWidget *areaw) {
|
ads::CDockAreaWidget *areaw) {
|
||||||
Q_ASSERT(m_consoleout);
|
Q_ASSERT(m_consoleout);
|
||||||
m_sym = new ASObjTreeWidget(this);
|
m_sym = new ASObjTreeWidget(this);
|
||||||
|
m_sym->header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
auto dw =
|
auto dw =
|
||||||
buildDockWidget(dock, QStringLiteral("Symbol"), tr("Symbol"), m_sym);
|
buildDockWidget(dock, QStringLiteral("Symbol"), tr("Symbol"), m_sym);
|
||||||
return dock->addDockWidget(area, dw, areaw);
|
return dock->addDockWidget(area, dw, areaw);
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "findresultmodel.h"
|
#include "findresultmodel.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
FindResultModel::FindResultModel(QObject *parent)
|
FindResultModel::FindResultModel(QObject *parent)
|
||||||
: QAbstractTableModel(parent) {}
|
: QAbstractTableModel(parent), m_encoding(QStringLiteral("ASCII")) {}
|
||||||
|
|
||||||
int FindResultModel::rowCount(const QModelIndex &parent) const {
|
int FindResultModel::rowCount(const QModelIndex &parent) const {
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
|
@ -43,15 +44,53 @@ QVariant FindResultModel::data(const QModelIndex &index, int role) const {
|
||||||
case 2: // offset
|
case 2: // offset
|
||||||
return QStringLiteral("0x") +
|
return QStringLiteral("0x") +
|
||||||
QString::number(r.offset, 16).toUpper();
|
QString::number(r.offset, 16).toUpper();
|
||||||
case 3: // range
|
case 3: {
|
||||||
return m_lastFindData.at(row).findRange;
|
// range
|
||||||
case 4: // decoding
|
auto data = m_findData.at(row);
|
||||||
return m_lastFindData.at(row).decoding;
|
QString buffer =
|
||||||
|
data.cheader.toHex(' ').toUpper() % QStringLiteral(" <b>");
|
||||||
|
if (!data.hbuffer.isEmpty()) {
|
||||||
|
buffer += data.hbuffer.toHex(' ').toUpper();
|
||||||
|
if (!data.tbuffer.isEmpty()) {
|
||||||
|
buffer += QStringLiteral(" .. ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer += data.tbuffer.toHex(' ').toUpper() %
|
||||||
|
QStringLiteral("</b> ") %
|
||||||
|
data.ctailer.toHex(' ').toUpper();
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
case 4: { // decoding
|
||||||
|
auto data = m_findData.at(row);
|
||||||
|
QString buffer =
|
||||||
|
Utilities::decodingString(data.cheader, m_encoding) %
|
||||||
|
QStringLiteral(" <b>");
|
||||||
|
if (!data.hbuffer.isEmpty()) {
|
||||||
|
buffer += Utilities::decodingString(data.hbuffer);
|
||||||
|
if (!data.tbuffer.isEmpty()) {
|
||||||
|
buffer += QStringLiteral(" ... ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer += Utilities::decodingString(data.tbuffer) %
|
||||||
|
QStringLiteral("</b> ") %
|
||||||
|
Utilities::decodingString(data.ctailer);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
case Qt::TextAlignmentRole:
|
case Qt::TextAlignmentRole:
|
||||||
return Qt::AlignCenter;
|
switch (index.column()) {
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
return Qt::AlignLeft;
|
||||||
|
default:
|
||||||
|
return Qt::AlignCenter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -79,12 +118,20 @@ QVariant FindResultModel::headerData(int section, Qt::Orientation orientation,
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FindResultModel::encoding() const { return m_encoding; }
|
||||||
|
|
||||||
|
void FindResultModel::setEncoding(const QString &newEncoding) {
|
||||||
|
m_encoding = newEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
QList<WingHex::FindResult> &FindResultModel::results() { return m_results; }
|
QList<WingHex::FindResult> &FindResultModel::results() { return m_results; }
|
||||||
|
|
||||||
QList<FindResultModel::FindInfo> &FindResultModel::lastFindData() {
|
QList<FindResultModel::FindInfo> &FindResultModel::findData() {
|
||||||
return m_lastFindData;
|
return m_findData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray &FindResultModel::lastFindData() { return m_lastFindData; }
|
||||||
|
|
||||||
void FindResultModel::beginUpdate() { this->beginResetModel(); }
|
void FindResultModel::beginUpdate() { this->beginResetModel(); }
|
||||||
|
|
||||||
void FindResultModel::endUpdate() { this->endResetModel(); }
|
void FindResultModel::endUpdate() { this->endResetModel(); }
|
||||||
|
@ -95,7 +142,7 @@ WingHex::FindResult FindResultModel::resultAt(qsizetype index) const {
|
||||||
|
|
||||||
void FindResultModel::clear() {
|
void FindResultModel::clear() {
|
||||||
m_results.clear();
|
m_results.clear();
|
||||||
m_lastFindData.clear();
|
m_findData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<WingHex::FindResult>::size_type FindResultModel::size() const {
|
QList<WingHex::FindResult>::size_type FindResultModel::size() const {
|
||||||
|
|
|
@ -24,17 +24,21 @@
|
||||||
|
|
||||||
class FindResultModel : public QAbstractTableModel {
|
class FindResultModel : public QAbstractTableModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct FindInfo {
|
struct FindInfo {
|
||||||
QString findRange;
|
QByteArray cheader;
|
||||||
QString decoding;
|
QByteArray hbuffer;
|
||||||
|
QByteArray tbuffer;
|
||||||
|
QByteArray ctailer;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FindResultModel(QObject *parent = nullptr);
|
explicit FindResultModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
QList<WingHex::FindResult> &results();
|
QList<WingHex::FindResult> &results();
|
||||||
QList<FindInfo> &lastFindData();
|
QList<FindInfo> &findData();
|
||||||
|
QByteArray &lastFindData();
|
||||||
|
|
||||||
void beginUpdate();
|
void beginUpdate();
|
||||||
void endUpdate();
|
void endUpdate();
|
||||||
|
@ -51,9 +55,15 @@ public:
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
int role) const override;
|
int role) const override;
|
||||||
|
|
||||||
|
QString encoding() const;
|
||||||
|
void setEncoding(const QString &newEncoding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<WingHex::FindResult> m_results;
|
QList<WingHex::FindResult> m_results;
|
||||||
QList<FindInfo> m_lastFindData;
|
QList<FindInfo> m_findData;
|
||||||
|
QByteArray m_lastFindData;
|
||||||
|
|
||||||
|
QString m_encoding;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FINDRESULTMODEL_H
|
#endif // FINDRESULTMODEL_H
|
||||||
|
|
|
@ -401,30 +401,32 @@ public:
|
||||||
typedef ClickedCallBack DoubleClickedCallBack;
|
typedef ClickedCallBack DoubleClickedCallBack;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
bool updateText(const QString &data);
|
bool updateText(const QString &data, const QString &title = {});
|
||||||
bool updateTextList(const QStringList &data, ClickedCallBack clicked = {},
|
bool updateTextList(const QStringList &data, const QString &title = {},
|
||||||
|
ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
|
|
||||||
Q_REQUIRED_RESULT bool
|
Q_REQUIRED_RESULT bool
|
||||||
updateTextTree(const QString &json, ClickedCallBack clicked = {},
|
updateTextTree(const QString &json, const QString &title = {},
|
||||||
|
ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
Q_REQUIRED_RESULT bool
|
Q_REQUIRED_RESULT bool
|
||||||
updateTextTable(const QString &json, const QStringList &headers,
|
updateTextTable(const QString &json, const QStringList &headers,
|
||||||
const QStringList &headerNames = {},
|
const QStringList &headerNames = {},
|
||||||
ClickedCallBack clicked = {},
|
const QString &title = {}, ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
|
|
||||||
// API for Qt Plugin Only
|
// API for Qt Plugin Only
|
||||||
Q_REQUIRED_RESULT bool
|
Q_REQUIRED_RESULT bool
|
||||||
updateTextListByModel(QAbstractItemModel *model,
|
updateTextListByModel(QAbstractItemModel *model, const QString &title = {},
|
||||||
ClickedCallBack clicked = {},
|
ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
Q_REQUIRED_RESULT bool
|
Q_REQUIRED_RESULT bool
|
||||||
updateTextTableByModel(QAbstractItemModel *model,
|
updateTextTableByModel(QAbstractItemModel *model, const QString &title = {},
|
||||||
ClickedCallBack clicked = {},
|
ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
Q_REQUIRED_RESULT bool
|
Q_REQUIRED_RESULT bool
|
||||||
updateTextTreeByModel(QAbstractItemModel *model,
|
updateTextTreeByModel(QAbstractItemModel *model, const QString &title = {},
|
||||||
ClickedCallBack clicked = {},
|
ClickedCallBack clicked = {},
|
||||||
DoubleClickedCallBack dblClicked = {});
|
DoubleClickedCallBack dblClicked = {});
|
||||||
};
|
};
|
||||||
|
@ -494,7 +496,13 @@ signals:
|
||||||
struct WingDependency {
|
struct WingDependency {
|
||||||
QString puid;
|
QString puid;
|
||||||
uint version;
|
uint version;
|
||||||
QString md5; // optional, but recommend
|
QByteArray md5; // optional, but recommend
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SenderInfo {
|
||||||
|
QString plgcls;
|
||||||
|
QString puid;
|
||||||
|
QVariant meta;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WING_SERVICE
|
#ifdef WING_SERVICE
|
||||||
|
@ -602,8 +610,9 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// QHash< obj-names, decl-members >
|
// QHash< enum , members >
|
||||||
virtual QHash<QString, QStringList> registeredScriptObjs() const {
|
virtual QHash<QString, QList<QPair<QString, int>>>
|
||||||
|
registeredScriptEnums() const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,8 +664,7 @@ signals:
|
||||||
QGenericArgument val5 = QGenericArgument(),
|
QGenericArgument val5 = QGenericArgument(),
|
||||||
QGenericArgument val6 = QGenericArgument(),
|
QGenericArgument val6 = QGenericArgument(),
|
||||||
QGenericArgument val7 = QGenericArgument(),
|
QGenericArgument val7 = QGenericArgument(),
|
||||||
QGenericArgument val8 = QGenericArgument(),
|
QGenericArgument val8 = QGenericArgument());
|
||||||
QGenericArgument val9 = QGenericArgument());
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool invokeService(const QString &puid, const char *member,
|
inline bool invokeService(const QString &puid, const char *member,
|
||||||
|
@ -669,11 +677,10 @@ public:
|
||||||
QGenericArgument val5 = QGenericArgument(),
|
QGenericArgument val5 = QGenericArgument(),
|
||||||
QGenericArgument val6 = QGenericArgument(),
|
QGenericArgument val6 = QGenericArgument(),
|
||||||
QGenericArgument val7 = QGenericArgument(),
|
QGenericArgument val7 = QGenericArgument(),
|
||||||
QGenericArgument val8 = QGenericArgument(),
|
QGenericArgument val8 = QGenericArgument()) {
|
||||||
QGenericArgument val9 = QGenericArgument()) {
|
|
||||||
return emit invokeService(puid, member, Qt::AutoConnection, ret, val0,
|
return emit invokeService(puid, member, Qt::AutoConnection, ret, val0,
|
||||||
val1, val2, val3, val4, val5, val6, val7,
|
val1, val2, val3, val4, val5, val6, val7,
|
||||||
val8, val9);
|
val8);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool invokeService(const QString &puid, const char *member,
|
inline bool invokeService(const QString &puid, const char *member,
|
||||||
|
@ -685,11 +692,10 @@ public:
|
||||||
QGenericArgument val5 = QGenericArgument(),
|
QGenericArgument val5 = QGenericArgument(),
|
||||||
QGenericArgument val6 = QGenericArgument(),
|
QGenericArgument val6 = QGenericArgument(),
|
||||||
QGenericArgument val7 = QGenericArgument(),
|
QGenericArgument val7 = QGenericArgument(),
|
||||||
QGenericArgument val8 = QGenericArgument(),
|
QGenericArgument val8 = QGenericArgument()) {
|
||||||
QGenericArgument val9 = QGenericArgument()) {
|
|
||||||
return emit invokeService(puid, member, type, QGenericReturnArgument(),
|
return emit invokeService(puid, member, type, QGenericReturnArgument(),
|
||||||
val0, val1, val2, val3, val4, val5, val6,
|
val0, val1, val2, val3, val4, val5, val6,
|
||||||
val7, val8, val9);
|
val7, val8);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool invokeService(const QString &puid, const char *member,
|
inline bool invokeService(const QString &puid, const char *member,
|
||||||
|
@ -701,11 +707,10 @@ public:
|
||||||
QGenericArgument val5 = QGenericArgument(),
|
QGenericArgument val5 = QGenericArgument(),
|
||||||
QGenericArgument val6 = QGenericArgument(),
|
QGenericArgument val6 = QGenericArgument(),
|
||||||
QGenericArgument val7 = QGenericArgument(),
|
QGenericArgument val7 = QGenericArgument(),
|
||||||
QGenericArgument val8 = QGenericArgument(),
|
QGenericArgument val8 = QGenericArgument()) {
|
||||||
QGenericArgument val9 = QGenericArgument()) {
|
|
||||||
return emit invokeService(puid, member, Qt::AutoConnection,
|
return emit invokeService(puid, member, Qt::AutoConnection,
|
||||||
QGenericReturnArgument(), val0, val1, val2,
|
QGenericReturnArgument(), val0, val1, val2,
|
||||||
val3, val4, val5, val6, val7, val8, val9);
|
val3, val4, val5, val6, val7, val8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -720,6 +725,7 @@ public:
|
||||||
|
|
||||||
} // namespace WingHex
|
} // namespace WingHex
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(WingHex::SenderInfo)
|
||||||
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, "com.wingsummer.iwingplugin")
|
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, "com.wingsummer.iwingplugin")
|
||||||
|
|
||||||
#endif // IWINGPLUGIN_H
|
#endif // IWINGPLUGIN_H
|
||||||
|
|
|
@ -68,15 +68,14 @@ void PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) {
|
||||||
Q_ASSERT(_win);
|
Q_ASSERT(_win);
|
||||||
|
|
||||||
if (fileinfo.exists()) {
|
if (fileinfo.exists()) {
|
||||||
QPluginLoader loader(fileinfo.absoluteFilePath(), this);
|
auto fileName = fileinfo.absoluteFilePath();
|
||||||
|
QPluginLoader loader(fileName, this);
|
||||||
Logger::info(tr("LoadingPlugin") + fileinfo.fileName());
|
Logger::info(tr("LoadingPlugin") + fileinfo.fileName());
|
||||||
auto p = qobject_cast<IWingPlugin *>(loader.instance());
|
auto p = qobject_cast<IWingPlugin *>(loader.instance());
|
||||||
if (Q_UNLIKELY(p == nullptr)) {
|
if (Q_UNLIKELY(p == nullptr)) {
|
||||||
Logger::critical(loader.errorString());
|
Logger::critical(loader.errorString());
|
||||||
} else {
|
} else {
|
||||||
if (!loadPlugin(p, setdir)) {
|
loadPlugin(p, fileName, setdir);
|
||||||
loader.unload();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Logger::_log("");
|
Logger::_log("");
|
||||||
}
|
}
|
||||||
|
@ -299,6 +298,17 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
|
||||||
_angelplg->registerScriptFns(plg->metaObject()->className(), rfns);
|
_angelplg->registerScriptFns(plg->metaObject()->className(), rfns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PluginSystem::registerEnums(IWingPlugin *plg) {
|
||||||
|
Q_ASSERT(plg);
|
||||||
|
auto objs = plg->registeredScriptEnums();
|
||||||
|
if (objs.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(_angelplg);
|
||||||
|
_angelplg->registerScriptEnums(plg->metaObject()->className(), objs);
|
||||||
|
}
|
||||||
|
|
||||||
void PluginSystem::registerEvents(IWingPlugin *plg) {
|
void PluginSystem::registerEvents(IWingPlugin *plg) {
|
||||||
Q_ASSERT(plg);
|
Q_ASSERT(plg);
|
||||||
auto evs = plg->registeredEvents();
|
auto evs = plg->registeredEvents();
|
||||||
|
@ -445,15 +455,35 @@ QString PluginSystem::getScriptFnSig(const QString &fnName,
|
||||||
|
|
||||||
QString PluginSystem::getPUID(IWingPlugin *p) {
|
QString PluginSystem::getPUID(IWingPlugin *p) {
|
||||||
if (p) {
|
if (p) {
|
||||||
|
constexpr auto puid_limit = 36; // same as uuid length, so enough
|
||||||
auto prop = p->property("puid").toString().trimmed();
|
auto prop = p->property("puid").toString().trimmed();
|
||||||
|
if (prop.length() > puid_limit) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
auto pid = QString(p->metaObject()->className());
|
auto pid = QString(p->metaObject()->className());
|
||||||
|
if (pid.length() > puid_limit) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
return prop.isEmpty() ? pid : prop;
|
return prop.isEmpty() ? pid : prop;
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginSystem::loadPlugin(IWingPlugin *p,
|
bool PluginSystem::isPluginLoaded(const WingDependency &d) {
|
||||||
|
for (auto &info : _loadedplginfo) {
|
||||||
|
if (info.version >= d.version && info.puid == d.puid) {
|
||||||
|
if (d.md5.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return d.md5.compare(info.md5, Qt::CaseInsensitive) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginSystem::loadPlugin(IWingPlugin *p, const QString &fileName,
|
||||||
const std::optional<QDir> &setdir) {
|
const std::optional<QDir> &setdir) {
|
||||||
QTranslator *p_tr = nullptr;
|
QTranslator *p_tr = nullptr;
|
||||||
|
|
||||||
|
@ -471,8 +501,25 @@ bool PluginSystem::loadPlugin(IWingPlugin *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto puid = getPUID(p);
|
auto puid = getPUID(p);
|
||||||
if (_loadedpuid.contains(puid)) {
|
if (puid.isEmpty()) {
|
||||||
throw tr("ErrLoadLoadedPlugin");
|
throw tr("ErrLoadInvalidPUID");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &uid : _loadedplginfo) {
|
||||||
|
if (uid.puid == puid) {
|
||||||
|
throw tr("ErrLoadLoadedPlugin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check dependencise
|
||||||
|
auto dps = p->dependencies();
|
||||||
|
if (!dps.isEmpty()) {
|
||||||
|
for (auto &d : dps) {
|
||||||
|
if (!isPluginLoaded(d)) {
|
||||||
|
_lazyplgs.append(qMakePair(p, fileName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit pluginLoading(p->pluginName());
|
emit pluginLoading(p->pluginName());
|
||||||
|
@ -496,8 +543,14 @@ bool PluginSystem::loadPlugin(IWingPlugin *p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadedplgs.push_back(p);
|
_loadedplgs.append(p);
|
||||||
_loadedpuid << puid;
|
|
||||||
|
WingDependency de;
|
||||||
|
de.puid = puid;
|
||||||
|
de.version = p->pluginVersion();
|
||||||
|
de.md5 = Utilities::getMd5(fileName);
|
||||||
|
|
||||||
|
_loadedplginfo.append(de);
|
||||||
|
|
||||||
Logger::warning(tr("PluginName :") + p->pluginName());
|
Logger::warning(tr("PluginName :") + p->pluginName());
|
||||||
Logger::warning(tr("PluginAuthor :") + p->pluginAuthor());
|
Logger::warning(tr("PluginAuthor :") + p->pluginAuthor());
|
||||||
|
@ -665,6 +718,7 @@ bool PluginSystem::loadPlugin(IWingPlugin *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
registerFns(p);
|
registerFns(p);
|
||||||
|
registerEnums(p);
|
||||||
registerEvents(p);
|
registerEvents(p);
|
||||||
connectInterface(p);
|
connectInterface(p);
|
||||||
|
|
||||||
|
@ -674,9 +728,7 @@ bool PluginSystem::loadPlugin(IWingPlugin *p,
|
||||||
if (p_tr) {
|
if (p_tr) {
|
||||||
p_tr->deleteLater();
|
p_tr->deleteLater();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginSystem::connectInterface(IWingPlugin *plg) {
|
void PluginSystem::connectInterface(IWingPlugin *plg) {
|
||||||
|
@ -738,22 +790,22 @@ void PluginSystem::connectBaseInterface(IWingPlugin *plg) {
|
||||||
QGenericReturnArgument, QGenericArgument, QGenericArgument,
|
QGenericReturnArgument, QGenericArgument, QGenericArgument,
|
||||||
QGenericArgument, QGenericArgument, QGenericArgument,
|
QGenericArgument, QGenericArgument, QGenericArgument,
|
||||||
QGenericArgument, QGenericArgument, QGenericArgument,
|
QGenericArgument, QGenericArgument, QGenericArgument,
|
||||||
QGenericArgument,
|
|
||||||
QGenericArgument>::of(&IWingPlugin::invokeService),
|
QGenericArgument>::of(&IWingPlugin::invokeService),
|
||||||
this,
|
this,
|
||||||
[=](const QString &puid, const char *method, Qt::ConnectionType type,
|
[=](const QString &puid, const char *method, Qt::ConnectionType type,
|
||||||
QGenericReturnArgument ret, QGenericArgument val0,
|
QGenericReturnArgument ret, QGenericArgument val0,
|
||||||
QGenericArgument val1, QGenericArgument val2, QGenericArgument val3,
|
QGenericArgument val1, QGenericArgument val2, QGenericArgument val3,
|
||||||
QGenericArgument val4, QGenericArgument val5, QGenericArgument val6,
|
QGenericArgument val4, QGenericArgument val5, QGenericArgument val6,
|
||||||
QGenericArgument val7, QGenericArgument val8,
|
QGenericArgument val7, QGenericArgument val8) -> bool {
|
||||||
QGenericArgument val9) -> bool {
|
|
||||||
auto r = std::find_if(
|
auto r = std::find_if(
|
||||||
_loadedplgs.begin(), _loadedplgs.end(),
|
_loadedplgs.begin(), _loadedplgs.end(),
|
||||||
[=](IWingPlugin *plg) { return getPUID(plg) == puid; });
|
[=](IWingPlugin *plg) { return getPUID(plg) == puid; });
|
||||||
if (r == _loadedplgs.end()) {
|
if (r == _loadedplgs.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto meta = (*r)->metaObject();
|
|
||||||
|
auto obj = *r;
|
||||||
|
auto meta = obj->metaObject();
|
||||||
|
|
||||||
// filter the evil call and report to log
|
// filter the evil call and report to log
|
||||||
QVarLengthArray<char, 512> sig;
|
QVarLengthArray<char, 512> sig;
|
||||||
|
@ -762,10 +814,13 @@ void PluginSystem::connectBaseInterface(IWingPlugin *plg) {
|
||||||
return false;
|
return false;
|
||||||
sig.append(method, len);
|
sig.append(method, len);
|
||||||
sig.append('(');
|
sig.append('(');
|
||||||
const char *typeNames[] = {ret.name(), val0.name(), val1.name(),
|
|
||||||
val2.name(), val3.name(), val4.name(),
|
auto sname = QMetaType::fromType<WingHex::SenderInfo>().name();
|
||||||
val5.name(), val6.name(), val7.name(),
|
|
||||||
val8.name(), val9.name()};
|
const char *typeNames[] = {ret.name(), sname, val0.name(),
|
||||||
|
val1.name(), val2.name(), val3.name(),
|
||||||
|
val4.name(), val5.name(), val6.name(),
|
||||||
|
val7.name(), val8.name()};
|
||||||
size_t paramCount;
|
size_t paramCount;
|
||||||
constexpr auto maxParamCount =
|
constexpr auto maxParamCount =
|
||||||
sizeof(typeNames) / sizeof(const char *);
|
sizeof(typeNames) / sizeof(const char *);
|
||||||
|
@ -803,10 +858,26 @@ void PluginSystem::connectBaseInterface(IWingPlugin *plg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto obj = *r;
|
meta = plg->metaObject();
|
||||||
obj->setProperty("__LAST_CALLER__", plg->metaObject()->className());
|
SenderInfo info;
|
||||||
return m.invoke(obj, type, ret, val0, val1, val2, val3, val4, val5,
|
info.plgcls = meta->className();
|
||||||
val6, val7, val8, val9);
|
info.puid = getPUID(plg);
|
||||||
|
|
||||||
|
auto meta_name = "WING_META";
|
||||||
|
// property first
|
||||||
|
auto var = plg->property(meta_name);
|
||||||
|
if (var.isValid()) {
|
||||||
|
info.meta = var;
|
||||||
|
} else {
|
||||||
|
auto iidx = meta->indexOfClassInfo(meta_name);
|
||||||
|
if (iidx >= 0) {
|
||||||
|
info.meta = QString(meta->classInfo(iidx).value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.invoke(obj, type, ret,
|
||||||
|
WINGAPI_ARG(WingHex::SenderInfo, info), val0, val1,
|
||||||
|
val2, val3, val4, val5, val6, val7, val8);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,13 +2223,14 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
|
|
||||||
auto visual = &plg->visual;
|
auto visual = &plg->visual;
|
||||||
connect(visual, &WingPlugin::DataVisual::updateText, _win,
|
connect(visual, &WingPlugin::DataVisual::updateText, _win,
|
||||||
[=](const QString &txt) -> bool {
|
[=](const QString &txt, const QString &title) -> bool {
|
||||||
|
_win->m_infotxt->setProperty("__TITLE__", title);
|
||||||
_win->m_infotxt->setText(txt);
|
_win->m_infotxt->setText(txt);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextList, _win,
|
visual, &WingPlugin::DataVisual::updateTextList, _win,
|
||||||
[=](const QStringList &data,
|
[=](const QStringList &data, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2166,6 +2238,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
if (oldmodel) {
|
if (oldmodel) {
|
||||||
oldmodel->deleteLater();
|
oldmodel->deleteLater();
|
||||||
}
|
}
|
||||||
|
_win->m_infolist->setProperty("__TITLE__", title);
|
||||||
auto model = new QStringListModel(data);
|
auto model = new QStringListModel(data);
|
||||||
_win->m_infolist->setModel(model);
|
_win->m_infolist->setModel(model);
|
||||||
_win->m_infoclickfn = clicked;
|
_win->m_infoclickfn = clicked;
|
||||||
|
@ -2174,7 +2247,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextListByModel, _win,
|
visual, &WingPlugin::DataVisual::updateTextListByModel, _win,
|
||||||
[=](QAbstractItemModel *model,
|
[=](QAbstractItemModel *model, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2183,6 +2256,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
if (oldmodel) {
|
if (oldmodel) {
|
||||||
oldmodel->deleteLater();
|
oldmodel->deleteLater();
|
||||||
}
|
}
|
||||||
|
_win->m_infolist->setProperty("__TITLE__", title);
|
||||||
_win->m_infolist->setModel(model);
|
_win->m_infolist->setModel(model);
|
||||||
_win->m_infoclickfn = clicked;
|
_win->m_infoclickfn = clicked;
|
||||||
_win->m_infodblclickfn = dblClicked;
|
_win->m_infodblclickfn = dblClicked;
|
||||||
|
@ -2192,7 +2266,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextTree, _win,
|
visual, &WingPlugin::DataVisual::updateTextTree, _win,
|
||||||
[=](const QString &json,
|
[=](const QString &json, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2200,6 +2274,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
if (oldmodel) {
|
if (oldmodel) {
|
||||||
oldmodel->deleteLater();
|
oldmodel->deleteLater();
|
||||||
}
|
}
|
||||||
|
_win->m_infotree->setProperty("__TITLE__", title);
|
||||||
auto model = new QJsonModel;
|
auto model = new QJsonModel;
|
||||||
if (model->loadJson(json.toUtf8())) {
|
if (model->loadJson(json.toUtf8())) {
|
||||||
_win->m_infotree->setModel(model);
|
_win->m_infotree->setModel(model);
|
||||||
|
@ -2211,7 +2286,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextTreeByModel, _win,
|
visual, &WingPlugin::DataVisual::updateTextTreeByModel, _win,
|
||||||
[=](QAbstractItemModel *model,
|
[=](QAbstractItemModel *model, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2220,6 +2295,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
if (oldmodel) {
|
if (oldmodel) {
|
||||||
oldmodel->deleteLater();
|
oldmodel->deleteLater();
|
||||||
}
|
}
|
||||||
|
_win->m_infotree->setProperty("__TITLE__", title);
|
||||||
_win->m_infotree->setModel(model);
|
_win->m_infotree->setModel(model);
|
||||||
_win->m_infotreeclickfn = clicked;
|
_win->m_infotreeclickfn = clicked;
|
||||||
_win->m_infotreedblclickfn = dblClicked;
|
_win->m_infotreedblclickfn = dblClicked;
|
||||||
|
@ -2230,7 +2306,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextTable, _win,
|
visual, &WingPlugin::DataVisual::updateTextTable, _win,
|
||||||
[=](const QString &json, const QStringList &headers,
|
[=](const QString &json, const QStringList &headers,
|
||||||
const QStringList &headerNames,
|
const QStringList &headerNames, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2257,7 +2333,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
header.append(heading);
|
header.append(heading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_win->m_infotable->setProperty("__TITLE__", title);
|
||||||
auto model = new QJsonTableModel(header);
|
auto model = new QJsonTableModel(header);
|
||||||
model->setJson(QJsonDocument::fromJson(json.toUtf8()));
|
model->setJson(QJsonDocument::fromJson(json.toUtf8()));
|
||||||
_win->m_infotable->setModel(model);
|
_win->m_infotable->setModel(model);
|
||||||
|
@ -2267,7 +2343,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
visual, &WingPlugin::DataVisual::updateTextTableByModel, _win,
|
visual, &WingPlugin::DataVisual::updateTextTableByModel, _win,
|
||||||
[=](QAbstractItemModel *model,
|
[=](QAbstractItemModel *model, const QString &title,
|
||||||
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
WingHex::WingPlugin::DataVisual::ClickedCallBack clicked,
|
||||||
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack dblClicked)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -2276,6 +2352,7 @@ void PluginSystem::connectUIInterface(IWingPlugin *plg) {
|
||||||
if (oldmodel) {
|
if (oldmodel) {
|
||||||
oldmodel->deleteLater();
|
oldmodel->deleteLater();
|
||||||
}
|
}
|
||||||
|
_win->m_infotable->setProperty("__TITLE__", title);
|
||||||
_win->m_infotable->setModel(model);
|
_win->m_infotable->setModel(model);
|
||||||
_win->m_infotableclickfn = clicked;
|
_win->m_infotableclickfn = clicked;
|
||||||
_win->m_infotabledblclickfn = dblClicked;
|
_win->m_infotabledblclickfn = dblClicked;
|
||||||
|
@ -2313,9 +2390,7 @@ void PluginSystem::LoadPlugin() {
|
||||||
if (set.scriptEnabled()) {
|
if (set.scriptEnabled()) {
|
||||||
_angelplg = new WingAngelAPI;
|
_angelplg = new WingAngelAPI;
|
||||||
|
|
||||||
auto ret = loadPlugin(_angelplg, std::nullopt);
|
loadPlugin(_angelplg, {}, std::nullopt);
|
||||||
Q_ASSERT(ret);
|
|
||||||
Q_UNUSED(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
|
@ -2370,6 +2445,33 @@ void PluginSystem::LoadPlugin() {
|
||||||
loadPlugin(item, udir);
|
loadPlugin(item, udir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_lazyplgs.isEmpty()) {
|
||||||
|
decltype(_lazyplgs) lazyplgs;
|
||||||
|
lazyplgs.swap(_lazyplgs);
|
||||||
|
|
||||||
|
for (auto &item : lazyplgs) {
|
||||||
|
loadPlugin(item.first, item.second, udir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_lazyplgs.isEmpty()) {
|
||||||
|
Logger::critical(tr("PluginLoadingFailedSummary"));
|
||||||
|
Logger::_log({});
|
||||||
|
for (auto &lplg : _lazyplgs) {
|
||||||
|
auto plg = lplg.first;
|
||||||
|
Logger::critical(tr("- PluginName:") + plg->pluginName());
|
||||||
|
Logger::critical(tr("- Dependencies:"));
|
||||||
|
for (auto &d : plg->dependencies()) {
|
||||||
|
Logger::critical(QString(4, ' ') + tr("PUID:") + d.puid);
|
||||||
|
Logger::critical(QString(4, ' ') + tr("Version:") +
|
||||||
|
QString::number(d.version));
|
||||||
|
Logger::critical(QString(4, ' ') + tr("MD5:") + d.md5);
|
||||||
|
}
|
||||||
|
plg->deleteLater();
|
||||||
|
}
|
||||||
|
_lazyplgs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Logger::info(tr("PluginLoadingFinished"));
|
Logger::info(tr("PluginLoadingFinished"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void registerFns(IWingPlugin *plg);
|
void registerFns(IWingPlugin *plg);
|
||||||
|
void registerEnums(IWingPlugin *plg);
|
||||||
void registerEvents(IWingPlugin *plg);
|
void registerEvents(IWingPlugin *plg);
|
||||||
|
|
||||||
QString type2AngelScriptString(IWingPlugin::MetaType type, bool isArg);
|
QString type2AngelScriptString(IWingPlugin::MetaType type, bool isArg);
|
||||||
|
@ -135,8 +136,11 @@ private:
|
||||||
|
|
||||||
QString getPUID(IWingPlugin *p);
|
QString getPUID(IWingPlugin *p);
|
||||||
|
|
||||||
|
bool isPluginLoaded(const WingDependency &d);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loadPlugin(IWingPlugin *p, const std::optional<QDir> &setdir);
|
void loadPlugin(IWingPlugin *p, const QString &fileName,
|
||||||
|
const std::optional<QDir> &setdir);
|
||||||
|
|
||||||
void connectInterface(IWingPlugin *plg);
|
void connectInterface(IWingPlugin *plg);
|
||||||
void connectLoadingInterface(IWingPlugin *plg);
|
void connectLoadingInterface(IWingPlugin *plg);
|
||||||
|
@ -230,8 +234,9 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MainWindow *_win = nullptr;
|
MainWindow *_win = nullptr;
|
||||||
QStringList _loadedpuid;
|
QList<WingDependency> _loadedplginfo;
|
||||||
QList<IWingPlugin *> _loadedplgs;
|
QList<IWingPlugin *> _loadedplgs;
|
||||||
|
QList<QPair<IWingPlugin *, QString>> _lazyplgs;
|
||||||
|
|
||||||
QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs;
|
QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
|
|
||||||
#define PROEXT ".wingpro"
|
#define PROEXT ".wingpro"
|
||||||
|
|
||||||
|
constexpr auto FIND_CONTEXT_SIZE = 3;
|
||||||
|
constexpr auto FIND_MAX_DISPLAY_FIND_CHARS = 8;
|
||||||
|
|
||||||
Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) {
|
Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) {
|
||||||
return ":/com.wingsummer.winghex/images/" + name + ".png";
|
return ":/com.wingsummer.winghex/images/" + name + ".png";
|
||||||
}
|
}
|
||||||
|
@ -156,6 +159,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray getMd5(QString filename) {
|
static QByteArray getMd5(QString filename) {
|
||||||
|
if (filename.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
QFile sourceFile(filename);
|
QFile sourceFile(filename);
|
||||||
if (sourceFile.open(QIODevice::ReadOnly)) {
|
if (sourceFile.open(QIODevice::ReadOnly)) {
|
||||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||||
|
@ -163,7 +170,7 @@ public:
|
||||||
return hash.result();
|
return hash.result();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QByteArray();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkIsLittleEndian() {
|
static bool checkIsLittleEndian() {
|
||||||
|
|
Loading…
Reference in New Issue