feat: 移除数据可视化功能以轻量化;优化 WingAngelAPI 脚本注册;
This commit is contained in:
parent
d6680e3f11
commit
f51630c6f0
|
@ -1,155 +0,0 @@
|
|||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file commonly created by Windows Explorer
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares and remote volumes
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# Thumbnail cache files created by Windows
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
|
||||
# Windows Desktop Search
|
||||
*.pst
|
||||
*.ost
|
||||
*.log
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.class
|
||||
*.so
|
||||
*.lib
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
# Java
|
||||
*.class
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
.vscodium/
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints/
|
||||
|
||||
# Thumbnails
|
||||
Thumbs/
|
||||
Thumbs.db
|
||||
|
||||
# macOS metadata
|
||||
._*
|
||||
|
||||
# TextMate
|
||||
*.tmproj
|
||||
*.tmproject
|
||||
.tmtags
|
||||
|
||||
# Sublime Text
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
|
||||
# VS Code directories
|
||||
.vscode/
|
||||
|
||||
# CodeKit
|
||||
.codekit-config.json
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Compiled files
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
# Logs and databases
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
*.xml
|
||||
|
||||
# Binary and source packages
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.tar
|
||||
*.zip
|
||||
*.rar
|
||||
*.bin
|
||||
*.war
|
||||
*.ear
|
||||
*.sar
|
||||
*.bbl
|
||||
*.pdf
|
||||
*.xls
|
||||
*.xlsx
|
||||
*.ppt
|
||||
*.pptx
|
||||
|
||||
# Virtual environment
|
||||
venv/
|
||||
env/
|
||||
|
||||
### Manually Entered
|
||||
vim-debug/
|
||||
**/out/bin
|
||||
**/out/lib
|
||||
**/out/share
|
||||
_deps
|
||||
.cache/
|
||||
compile_commands.json
|
||||
*.bak
|
||||
docs/
|
||||
*.old
|
||||
|
||||
# clangd cache
|
||||
.cache/
|
||||
.vim/
|
||||
build/
|
||||
debug/
|
||||
realease/
|
||||
Release/
|
||||
Debug
|
|
@ -1,25 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.26)
|
||||
|
||||
project(
|
||||
QJsonModel
|
||||
VERSION 0.0.2
|
||||
LANGUAGES C CXX
|
||||
# Save this for later: HOMEPAGE_URL <URL>
|
||||
DESCRIPTION
|
||||
"QJsonModel is a json tree model class for Qt6/C++17 based on QAbstractItemModel. MIT License."
|
||||
)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
|
||||
if(MSVC)
|
||||
string(APPEND CMAKE_CXX_FLAGS " /utf-8")
|
||||
string(APPEND CMAKE_C_FLAGS " /utf-8")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
add_library(QJsonModel STATIC include/details/QUtf8.hpp include/QJsonModel.hpp
|
||||
QJsonModel.cpp)
|
||||
|
||||
target_link_libraries(QJsonModel PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 sacha schutz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,518 +0,0 @@
|
|||
/* QJsonModel.cpp
|
||||
* Copyright (c) 2011 SCHUTZ Sacha
|
||||
* Copyright © 2024 Saul D. Beniquez
|
||||
*
|
||||
* License:
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// NOLINTBEGIN
|
||||
|
||||
#include "QJsonModel.hpp"
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFont>
|
||||
|
||||
inline bool contains(const QStringList &list, const QString &value) {
|
||||
for (auto val : list)
|
||||
if (value.contains(val, Qt::CaseInsensitive))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent) { mParent = parent; }
|
||||
|
||||
QJsonTreeItem::~QJsonTreeItem() { qDeleteAll(mChilds); }
|
||||
|
||||
void QJsonTreeItem::appendChild(QJsonTreeItem *item) { mChilds.append(item); }
|
||||
|
||||
QJsonTreeItem *QJsonTreeItem::child(int row) { return mChilds.value(row); }
|
||||
|
||||
QJsonTreeItem *QJsonTreeItem::parent() { return mParent; }
|
||||
|
||||
int QJsonTreeItem::childCount() const { return mChilds.count(); }
|
||||
|
||||
int QJsonTreeItem::row() const {
|
||||
if (mParent)
|
||||
return mParent->mChilds.indexOf(const_cast<QJsonTreeItem *>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QJsonTreeItem::setKey(const QString &key) { mKey = key; }
|
||||
|
||||
void QJsonTreeItem::setValue(const QVariant &value) { mValue = value; }
|
||||
|
||||
void QJsonTreeItem::setType(const QJsonValue::Type &type) { mType = type; }
|
||||
|
||||
QString QJsonTreeItem::key() const { return mKey; }
|
||||
|
||||
QVariant QJsonTreeItem::value() const { return mValue; }
|
||||
|
||||
QJsonValue::Type QJsonTreeItem::type() const { return mType; }
|
||||
|
||||
QJsonTreeItem *QJsonTreeItem::load(const QJsonValue &value,
|
||||
const QStringList &exceptions,
|
||||
QJsonTreeItem *parent) {
|
||||
QJsonTreeItem *rootItem = new QJsonTreeItem(parent);
|
||||
rootItem->setKey("root");
|
||||
|
||||
if (value.isObject()) {
|
||||
// Get all QJsonValue childs
|
||||
const QStringList keys =
|
||||
value.toObject().keys(); // To prevent clazy-range warning
|
||||
for (const QString &key : keys) {
|
||||
if (contains(exceptions, key)) {
|
||||
continue;
|
||||
}
|
||||
QJsonValue v = value.toObject().value(key);
|
||||
QJsonTreeItem *child = load(v, exceptions, rootItem);
|
||||
child->setKey(key);
|
||||
child->setType(v.type());
|
||||
rootItem->appendChild(child);
|
||||
}
|
||||
} else if (value.isArray()) {
|
||||
// Get all QJsonValue childs
|
||||
int index = 0;
|
||||
const QJsonArray array =
|
||||
value.toArray(); // To prevent clazy-range warning
|
||||
for (const QJsonValue &v : array) {
|
||||
QJsonTreeItem *child = load(v, exceptions, rootItem);
|
||||
child->setKey(QString::number(index));
|
||||
child->setType(v.type());
|
||||
rootItem->appendChild(child);
|
||||
++index;
|
||||
}
|
||||
} else {
|
||||
rootItem->setValue(value.toVariant());
|
||||
rootItem->setType(value.type());
|
||||
}
|
||||
|
||||
return rootItem;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
inline uchar hexdig(uint u) { return (u < 0xa ? '0' + u : 'a' + u - 0xa); }
|
||||
|
||||
QByteArray escapedString(const QString &s) {
|
||||
QByteArray ba(s.length(), Qt::Uninitialized);
|
||||
uchar *cursor =
|
||||
reinterpret_cast<uchar *>(const_cast<char *>(ba.constData()));
|
||||
const uchar *ba_end = cursor + ba.length();
|
||||
const ushort *src = reinterpret_cast<const ushort *>(s.constBegin());
|
||||
const ushort *const end = reinterpret_cast<const ushort *>(s.constEnd());
|
||||
while (src != end) {
|
||||
if (cursor >= ba_end - 6) {
|
||||
// ensure we have enough space
|
||||
int pos = cursor - reinterpret_cast<const uchar *>(ba.constData());
|
||||
ba.resize(ba.size() * 2);
|
||||
cursor = reinterpret_cast<uchar *>(ba.data()) + pos;
|
||||
ba_end =
|
||||
reinterpret_cast<const uchar *>(ba.constData()) + ba.length();
|
||||
}
|
||||
uint u = *src++;
|
||||
if (u < 0x80) {
|
||||
if (u < 0x20 || u == 0x22 || u == 0x5c) {
|
||||
*cursor++ = '\\';
|
||||
switch (u) {
|
||||
case 0x22:
|
||||
*cursor++ = '"';
|
||||
break;
|
||||
case 0x5c:
|
||||
*cursor++ = '\\';
|
||||
break;
|
||||
case 0x8:
|
||||
*cursor++ = 'b';
|
||||
break;
|
||||
case 0xc:
|
||||
*cursor++ = 'f';
|
||||
break;
|
||||
case 0xa:
|
||||
*cursor++ = 'n';
|
||||
break;
|
||||
case 0xd:
|
||||
*cursor++ = 'r';
|
||||
break;
|
||||
case 0x9:
|
||||
*cursor++ = 't';
|
||||
break;
|
||||
default:
|
||||
*cursor++ = 'u';
|
||||
*cursor++ = '0';
|
||||
*cursor++ = '0';
|
||||
*cursor++ = hexdig(u >> 4);
|
||||
*cursor++ = hexdig(u & 0xf);
|
||||
}
|
||||
} else {
|
||||
*cursor++ = (uchar)u;
|
||||
}
|
||||
} else if (QUtf8Functions::toUtf8<QUtf8BaseTraits>(u, cursor, src,
|
||||
end) < 0) {
|
||||
// failed to get valid utf8 use JSON escape sequence
|
||||
*cursor++ = '\\';
|
||||
*cursor++ = 'u';
|
||||
*cursor++ = hexdig(u >> 12 & 0x0f);
|
||||
*cursor++ = hexdig(u >> 8 & 0x0f);
|
||||
*cursor++ = hexdig(u >> 4 & 0x0f);
|
||||
*cursor++ = hexdig(u & 0x0f);
|
||||
}
|
||||
}
|
||||
ba.resize(cursor - reinterpret_cast<const uchar *>(ba.constData()));
|
||||
return ba;
|
||||
}
|
||||
|
||||
QJsonModel::QJsonModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), mRootItem{new QJsonTreeItem} {
|
||||
mHeaders.append(tr("key"));
|
||||
mHeaders.append(tr("value"));
|
||||
}
|
||||
|
||||
QJsonModel::QJsonModel(const QString &fileName, QObject *parent)
|
||||
: QAbstractItemModel(parent), mRootItem{new QJsonTreeItem} {
|
||||
mHeaders.append(tr("key"));
|
||||
mHeaders.append(tr("value"));
|
||||
load(fileName);
|
||||
}
|
||||
|
||||
QJsonModel::QJsonModel(QIODevice *device, QObject *parent)
|
||||
: QAbstractItemModel(parent), mRootItem{new QJsonTreeItem} {
|
||||
mHeaders.append(tr("key"));
|
||||
mHeaders.append(tr("value"));
|
||||
load(device);
|
||||
}
|
||||
|
||||
QJsonModel::QJsonModel(const QByteArray &json, QObject *parent)
|
||||
: QAbstractItemModel(parent), mRootItem{new QJsonTreeItem} {
|
||||
mHeaders.append(tr("key"));
|
||||
mHeaders.append(tr("value"));
|
||||
loadJson(json);
|
||||
}
|
||||
|
||||
QJsonModel::~QJsonModel() { delete mRootItem; }
|
||||
|
||||
bool QJsonModel::load(const QString &fileName) {
|
||||
QFile file(fileName);
|
||||
bool success = false;
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
success = load(&file);
|
||||
file.close();
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool QJsonModel::load(QIODevice *device) { return loadJson(device->readAll()); }
|
||||
|
||||
bool QJsonModel::loadJson(const QByteArray &json) {
|
||||
QJsonParseError error;
|
||||
auto const &jdoc = QJsonDocument::fromJson(json, &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jdoc.isNull()) {
|
||||
beginResetModel();
|
||||
delete mRootItem;
|
||||
if (jdoc.isArray()) {
|
||||
mRootItem =
|
||||
QJsonTreeItem::load(QJsonValue(jdoc.array()), mExceptions);
|
||||
mRootItem->setType(QJsonValue::Array);
|
||||
|
||||
} else {
|
||||
mRootItem =
|
||||
QJsonTreeItem::load(QJsonValue(jdoc.object()), mExceptions);
|
||||
mRootItem->setType(QJsonValue::Object);
|
||||
}
|
||||
endResetModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "cannot load json";
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant QJsonModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
QJsonTreeItem *item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (index.column() == 0)
|
||||
return QString("%1").arg(item->key());
|
||||
|
||||
if (index.column() == 1)
|
||||
return item->value();
|
||||
} else if (Qt::EditRole == role) {
|
||||
if (index.column() == 1)
|
||||
return item->value();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QJsonModel::setData(const QModelIndex &index, const QVariant &value,
|
||||
int role) {
|
||||
int col = index.column();
|
||||
if (Qt::EditRole == role) {
|
||||
if (col == 1) {
|
||||
QJsonTreeItem *item =
|
||||
static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||
item->setValue(value);
|
||||
emit dataChanged(index, index, {Qt::EditRole});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant QJsonModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role != Qt::DisplayRole)
|
||||
return {};
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
return mHeaders.value(section);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex QJsonModel::index(int row, int column,
|
||||
const QModelIndex &parent) const {
|
||||
if (!hasIndex(row, column, parent))
|
||||
return {};
|
||||
|
||||
QJsonTreeItem *parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = mRootItem;
|
||||
else
|
||||
parentItem = static_cast<QJsonTreeItem *>(parent.internalPointer());
|
||||
|
||||
QJsonTreeItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex QJsonModel::parent(const QModelIndex &index) const {
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
QJsonTreeItem *childItem =
|
||||
static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||
QJsonTreeItem *parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == mRootItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
int QJsonModel::rowCount(const QModelIndex &parent) const {
|
||||
QJsonTreeItem *parentItem;
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = mRootItem;
|
||||
else
|
||||
parentItem = static_cast<QJsonTreeItem *>(parent.internalPointer());
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
||||
int QJsonModel::columnCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent)
|
||||
return 2;
|
||||
}
|
||||
|
||||
Qt::ItemFlags QJsonModel::flags(const QModelIndex &index) const {
|
||||
int col = index.column();
|
||||
auto item = static_cast<QJsonTreeItem *>(index.internalPointer());
|
||||
|
||||
auto isArray = QJsonValue::Array == item->type();
|
||||
auto isObject = QJsonValue::Object == item->type();
|
||||
|
||||
if ((col == 1) && !(isArray || isObject))
|
||||
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
|
||||
else
|
||||
return QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
QByteArray QJsonModel::json(bool compact) {
|
||||
auto jsonValue = genJson(mRootItem);
|
||||
QByteArray json;
|
||||
if (jsonValue.isNull())
|
||||
return json;
|
||||
|
||||
if (jsonValue.isArray())
|
||||
arrayToJson(jsonValue.toArray(), json, 0, compact);
|
||||
else
|
||||
objectToJson(jsonValue.toObject(), json, 0, compact);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void QJsonModel::objectToJson(QJsonObject jsonObject, QByteArray &json,
|
||||
int indent, bool compact) {
|
||||
json += compact ? "{" : "{\n";
|
||||
objectContentToJson(jsonObject, json, indent + (compact ? 0 : 1), compact);
|
||||
json += QByteArray(4 * indent, ' ');
|
||||
json += compact ? "}" : "}\n";
|
||||
}
|
||||
void QJsonModel::arrayToJson(QJsonArray jsonArray, QByteArray &json, int indent,
|
||||
bool compact) {
|
||||
json += compact ? "[" : "[\n";
|
||||
arrayContentToJson(jsonArray, json, indent + (compact ? 0 : 1), compact);
|
||||
json += QByteArray(4 * indent, ' ');
|
||||
json += compact ? "]" : "]\n";
|
||||
}
|
||||
|
||||
void QJsonModel::arrayContentToJson(QJsonArray jsonArray, QByteArray &json,
|
||||
int indent, bool compact) {
|
||||
if (jsonArray.size() <= 0)
|
||||
return;
|
||||
|
||||
QByteArray indentString(4 * indent, ' ');
|
||||
int i = 0;
|
||||
while (1) {
|
||||
json += indentString;
|
||||
valueToJson(jsonArray.at(i), json, indent, compact);
|
||||
if (++i == jsonArray.size()) {
|
||||
if (!compact)
|
||||
json += '\n';
|
||||
break;
|
||||
}
|
||||
json += compact ? "," : ",\n";
|
||||
}
|
||||
}
|
||||
void QJsonModel::objectContentToJson(QJsonObject jsonObject, QByteArray &json,
|
||||
int indent, bool compact) {
|
||||
if (jsonObject.size() <= 0)
|
||||
return;
|
||||
|
||||
QByteArray indentString(4 * indent, ' ');
|
||||
int i = 0;
|
||||
while (1) {
|
||||
QString key = jsonObject.keys().at(i);
|
||||
json += indentString;
|
||||
json += '"';
|
||||
json += escapedString(key);
|
||||
json += compact ? "\":" : "\": ";
|
||||
valueToJson(jsonObject.value(key), json, indent, compact);
|
||||
if (++i == jsonObject.size()) {
|
||||
if (!compact)
|
||||
json += '\n';
|
||||
break;
|
||||
}
|
||||
json += compact ? "," : ",\n";
|
||||
}
|
||||
}
|
||||
|
||||
void QJsonModel::valueToJson(QJsonValue jsonValue, QByteArray &json, int indent,
|
||||
bool compact) {
|
||||
QJsonValue::Type type = jsonValue.type();
|
||||
switch (type) {
|
||||
case QJsonValue::Bool:
|
||||
json += jsonValue.toBool() ? "true" : "false";
|
||||
break;
|
||||
case QJsonValue::Double: {
|
||||
const double d = jsonValue.toDouble();
|
||||
if (qIsFinite(d)) {
|
||||
json += QByteArray::number(d, 'f', QLocale::FloatingPointShortest);
|
||||
} else {
|
||||
json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QJsonValue::String:
|
||||
json += '"';
|
||||
json += escapedString(jsonValue.toString());
|
||||
json += '"';
|
||||
break;
|
||||
case QJsonValue::Array:
|
||||
json += compact ? "[" : "[\n";
|
||||
arrayContentToJson(jsonValue.toArray(), json,
|
||||
indent + (compact ? 0 : 1), compact);
|
||||
json += QByteArray(4 * indent, ' ');
|
||||
json += ']';
|
||||
break;
|
||||
case QJsonValue::Object:
|
||||
json += compact ? "{" : "{\n";
|
||||
objectContentToJson(jsonValue.toObject(), json,
|
||||
indent + (compact ? 0 : 1), compact);
|
||||
json += QByteArray(4 * indent, ' ');
|
||||
json += '}';
|
||||
break;
|
||||
case QJsonValue::Null:
|
||||
default:
|
||||
json += "null";
|
||||
}
|
||||
}
|
||||
|
||||
void QJsonModel::addException(const QStringList &exceptions) {
|
||||
mExceptions = exceptions;
|
||||
}
|
||||
|
||||
QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const {
|
||||
auto type = item->type();
|
||||
int nchild = item->childCount();
|
||||
|
||||
if (QJsonValue::Object == type) {
|
||||
QJsonObject jo;
|
||||
for (int i = 0; i < nchild; ++i) {
|
||||
auto ch = item->child(i);
|
||||
auto key = ch->key();
|
||||
jo.insert(key, genJson(ch));
|
||||
}
|
||||
return jo;
|
||||
} else if (QJsonValue::Array == type) {
|
||||
QJsonArray arr;
|
||||
for (int i = 0; i < nchild; ++i) {
|
||||
auto ch = item->child(i);
|
||||
arr.append(genJson(ch));
|
||||
}
|
||||
return arr;
|
||||
} else {
|
||||
QJsonValue va;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
switch (item->value().typeId()) {
|
||||
#else
|
||||
switch (item->value().userType()) {
|
||||
#endif
|
||||
case QMetaType::Bool: {
|
||||
va = item->value().toBool();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
va = item->value().toString();
|
||||
break;
|
||||
}
|
||||
return va;
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
# QJsonModel
|
||||
QJsonModel is a JSON tree model class for Qt6/C++17 based on QAbstractItemModel.
|
||||
|
||||
QJsonModel was originally written by Sacha Shutz (https://github.com/dridk).
|
||||
|
||||
This fork is also released under the MIT License.
|
||||
|
||||
|
||||

|
||||
|
||||
## Build Instructions
|
||||
|
||||
### Build Tools
|
||||
- CMake (version 3.21 or higher)
|
||||
- C++17-compatible compiler
|
||||
|
||||
### Building the Project
|
||||
1. Clone the repository:
|
||||
```
|
||||
git clone <URL>
|
||||
```
|
||||
|
||||
2. Navigate to the project directory:
|
||||
```
|
||||
cd elemental-game
|
||||
```
|
||||
3. Configure your build system:
|
||||
```bash
|
||||
cmake -B debug -G Unix Makefiles
|
||||
# or
|
||||
cmake -B debug -G Ninja # this is faster and more modern
|
||||
```
|
||||
4. Invoke your build system
|
||||
```
|
||||
cmake --build debug
|
||||
```
|
||||
### Usage - CMake
|
||||
|
||||
You can add this library to your CMake projects using FetchContent()
|
||||
or CPM_AddPackage().
|
||||
|
||||
Here's how to do it with CPM_AddPackage:
|
||||
|
||||
```
|
||||
COMING SOON
|
||||
```
|
||||
|
||||
### Usage - C++
|
||||
|
||||
####
|
||||
```cpp
|
||||
QJsonModel * model = new QJsonModel;
|
||||
QTreeView * view = new QTreeView;
|
||||
view->setModel(model);
|
||||
model->load("example.json")
|
||||
```
|
|
@ -1,115 +0,0 @@
|
|||
/* QJsonModel.hpp
|
||||
* Copyright (c) 2011 SCHUTZ Sacha
|
||||
* Copyright © 2024 Saul D. Beniquez
|
||||
*
|
||||
* License:
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QIcon>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "details/QUtf8.hpp"
|
||||
|
||||
class QJsonModel;
|
||||
class QJsonItem;
|
||||
|
||||
class QJsonTreeItem {
|
||||
public:
|
||||
QJsonTreeItem(QJsonTreeItem *parent = nullptr);
|
||||
~QJsonTreeItem();
|
||||
void appendChild(QJsonTreeItem *item);
|
||||
QJsonTreeItem *child(int row);
|
||||
QJsonTreeItem *parent();
|
||||
int childCount() const;
|
||||
int row() const;
|
||||
void setKey(const QString &key);
|
||||
void setValue(const QVariant &value);
|
||||
void setType(const QJsonValue::Type &type);
|
||||
QString key() const;
|
||||
QVariant value() const;
|
||||
QJsonValue::Type type() const;
|
||||
|
||||
static QJsonTreeItem *load(const QJsonValue &value,
|
||||
const QStringList &exceptions = {},
|
||||
QJsonTreeItem *parent = nullptr);
|
||||
|
||||
protected:
|
||||
private:
|
||||
QString mKey;
|
||||
QVariant mValue;
|
||||
QJsonValue::Type mType;
|
||||
QList<QJsonTreeItem *> mChilds;
|
||||
QJsonTreeItem *mParent = nullptr;
|
||||
};
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
class QJsonModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QJsonModel(QObject *parent = nullptr);
|
||||
QJsonModel(const QString &fileName, QObject *parent = nullptr);
|
||||
QJsonModel(QIODevice *device, QObject *parent = nullptr);
|
||||
QJsonModel(const QByteArray &json, QObject *parent = nullptr);
|
||||
~QJsonModel();
|
||||
bool load(const QString &fileName);
|
||||
bool load(QIODevice *device);
|
||||
bool loadJson(const QByteArray &json);
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role) const override;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QByteArray json(bool compact = false);
|
||||
QByteArray jsonToByte(QJsonValue jsonValue);
|
||||
void objectToJson(QJsonObject jsonObject, QByteArray &json, int indent,
|
||||
bool compact);
|
||||
void arrayToJson(QJsonArray jsonArray, QByteArray &json, int indent,
|
||||
bool compact);
|
||||
void arrayContentToJson(QJsonArray jsonArray, QByteArray &json, int indent,
|
||||
bool compact);
|
||||
void objectContentToJson(QJsonObject jsonObject, QByteArray &json,
|
||||
int indent, bool compact);
|
||||
void valueToJson(QJsonValue jsonValue, QByteArray &json, int indent,
|
||||
bool compact);
|
||||
//! List of tags to skip during JSON parsing
|
||||
void addException(const QStringList &exceptions);
|
||||
|
||||
private:
|
||||
QJsonValue genJson(QJsonTreeItem *) const;
|
||||
QJsonTreeItem *mRootItem = nullptr;
|
||||
QStringList mHeaders;
|
||||
//! List of exceptions (e.g. comments). Case insensitive, compairs on
|
||||
//! "contains".
|
||||
QStringList mExceptions;
|
||||
};
|
|
@ -1,194 +0,0 @@
|
|||
/* QUtf8.hpp
|
||||
* Copyright © 2024 Saul D. Beniquez
|
||||
* License:
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <QJsonValue>
|
||||
|
||||
namespace QUtf8Functions {
|
||||
/// returns 0 on success; errors can only happen if \a u is a surrogate:
|
||||
/// Error if \a u is a low surrogate;
|
||||
/// if \a u is a high surrogate, Error if the next isn't a low one,
|
||||
/// EndOfString if we run into the end of the string.
|
||||
template <typename Traits, typename OutputPtr, typename InputPtr>
|
||||
inline int toUtf8(ushort u, OutputPtr &dst, InputPtr &src, InputPtr end) {
|
||||
if (!Traits::skipAsciiHandling && u < 0x80) {
|
||||
// U+0000 to U+007F (US-ASCII) - one byte
|
||||
Traits::appendByte(dst, uchar(u));
|
||||
return 0;
|
||||
} else if (u < 0x0800) {
|
||||
// U+0080 to U+07FF - two bytes
|
||||
// first of two bytes
|
||||
Traits::appendByte(dst, 0xc0 | uchar(u >> 6));
|
||||
} else {
|
||||
if (!QChar::isSurrogate(u)) {
|
||||
// U+0800 to U+FFFF (except U+D800-U+DFFF) - three bytes
|
||||
if (!Traits::allowNonCharacters && QChar::isNonCharacter(u))
|
||||
return Traits::Error;
|
||||
// first of three bytes
|
||||
Traits::appendByte(dst, 0xe0 | uchar(u >> 12));
|
||||
} else {
|
||||
// U+10000 to U+10FFFF - four bytes
|
||||
// need to get one extra codepoint
|
||||
if (Traits::availableUtf16(src, end) == 0)
|
||||
return Traits::EndOfString;
|
||||
ushort low = Traits::peekUtf16(src);
|
||||
if (!QChar::isHighSurrogate(u))
|
||||
return Traits::Error;
|
||||
if (!QChar::isLowSurrogate(low))
|
||||
return Traits::Error;
|
||||
Traits::advanceUtf16(src);
|
||||
uint ucs4 = QChar::surrogateToUcs4(u, low);
|
||||
if (!Traits::allowNonCharacters && QChar::isNonCharacter(ucs4))
|
||||
return Traits::Error;
|
||||
// first byte
|
||||
Traits::appendByte(dst, 0xf0 | (uchar(ucs4 >> 18) & 0xf));
|
||||
// second of four bytes
|
||||
Traits::appendByte(dst, 0x80 | (uchar(ucs4 >> 12) & 0x3f));
|
||||
// for the rest of the bytes
|
||||
u = ushort(ucs4);
|
||||
}
|
||||
// second to last byte
|
||||
Traits::appendByte(dst, 0x80 | (uchar(u >> 6) & 0x3f));
|
||||
}
|
||||
// last byte
|
||||
Traits::appendByte(dst, 0x80 | (u & 0x3f));
|
||||
return 0;
|
||||
}
|
||||
inline bool isContinuationByte(uchar b) { return (b & 0xc0) == 0x80; }
|
||||
/// returns the number of characters consumed (including \a b) in case of
|
||||
/// success; returns negative in case of error: Traits::Error or
|
||||
/// Traits::EndOfString
|
||||
template <typename Traits, typename OutputPtr, typename InputPtr>
|
||||
inline int fromUtf8(uchar b, OutputPtr &dst, InputPtr &src, InputPtr end) {
|
||||
int charsNeeded;
|
||||
uint min_uc;
|
||||
uint uc;
|
||||
if (!Traits::skipAsciiHandling && b < 0x80) {
|
||||
// US-ASCII
|
||||
Traits::appendUtf16(dst, b);
|
||||
return 1;
|
||||
}
|
||||
if (!Traits::isTrusted && Q_UNLIKELY(b <= 0xC1)) {
|
||||
// an UTF-8 first character must be at least 0xC0
|
||||
// however, all 0xC0 and 0xC1 first bytes can only produce overlong
|
||||
// sequences
|
||||
return Traits::Error;
|
||||
} else if (b < 0xe0) {
|
||||
charsNeeded = 2;
|
||||
min_uc = 0x80;
|
||||
uc = b & 0x1f;
|
||||
} else if (b < 0xf0) {
|
||||
charsNeeded = 3;
|
||||
min_uc = 0x800;
|
||||
uc = b & 0x0f;
|
||||
} else if (b < 0xf5) {
|
||||
charsNeeded = 4;
|
||||
min_uc = 0x10000;
|
||||
uc = b & 0x07;
|
||||
} else {
|
||||
// the last Unicode character is U+10FFFF
|
||||
// it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF"
|
||||
// therefore, a byte higher than 0xF4 is not the UTF-8 first byte
|
||||
return Traits::Error;
|
||||
}
|
||||
int bytesAvailable = Traits::availableBytes(src, end);
|
||||
if (Q_UNLIKELY(bytesAvailable < charsNeeded - 1)) {
|
||||
// it's possible that we have an error instead of just unfinished bytes
|
||||
if (bytesAvailable > 0 && !isContinuationByte(Traits::peekByte(src, 0)))
|
||||
return Traits::Error;
|
||||
if (bytesAvailable > 1 && !isContinuationByte(Traits::peekByte(src, 1)))
|
||||
return Traits::Error;
|
||||
return Traits::EndOfString;
|
||||
}
|
||||
// first continuation character
|
||||
b = Traits::peekByte(src, 0);
|
||||
if (!isContinuationByte(b))
|
||||
return Traits::Error;
|
||||
uc <<= 6;
|
||||
uc |= b & 0x3f;
|
||||
if (charsNeeded > 2) {
|
||||
// second continuation character
|
||||
b = Traits::peekByte(src, 1);
|
||||
if (!isContinuationByte(b))
|
||||
return Traits::Error;
|
||||
uc <<= 6;
|
||||
uc |= b & 0x3f;
|
||||
if (charsNeeded > 3) {
|
||||
// third continuation character
|
||||
b = Traits::peekByte(src, 2);
|
||||
if (!isContinuationByte(b))
|
||||
return Traits::Error;
|
||||
uc <<= 6;
|
||||
uc |= b & 0x3f;
|
||||
}
|
||||
}
|
||||
// we've decoded something; safety-check it
|
||||
if (!Traits::isTrusted) {
|
||||
if (uc < min_uc)
|
||||
return Traits::Error;
|
||||
if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
|
||||
return Traits::Error;
|
||||
if (!Traits::allowNonCharacters && QChar::isNonCharacter(uc))
|
||||
return Traits::Error;
|
||||
}
|
||||
// write the UTF-16 sequence
|
||||
if (!QChar::requiresSurrogates(uc)) {
|
||||
// UTF-8 decoded and no surrogates are required
|
||||
// detach if necessary
|
||||
Traits::appendUtf16(dst, ushort(uc));
|
||||
} else {
|
||||
// UTF-8 decoded to something that requires a surrogate pair
|
||||
Traits::appendUcs4(dst, uc);
|
||||
}
|
||||
Traits::advanceByte(src, charsNeeded - 1);
|
||||
return charsNeeded;
|
||||
}
|
||||
} // namespace QUtf8Functions
|
||||
|
||||
struct QUtf8BaseTraits {
|
||||
static const bool isTrusted = false;
|
||||
static const bool allowNonCharacters = true;
|
||||
static const bool skipAsciiHandling = false;
|
||||
static const int Error = -1;
|
||||
static const int EndOfString = -2;
|
||||
static bool isValidCharacter(uint u) { return int(u) >= 0; }
|
||||
static void appendByte(uchar *&ptr, uchar b) { *ptr++ = b; }
|
||||
static uchar peekByte(const uchar *ptr, int n = 0) { return ptr[n]; }
|
||||
static qptrdiff availableBytes(const uchar *ptr, const uchar *end) {
|
||||
return end - ptr;
|
||||
}
|
||||
static void advanceByte(const uchar *&ptr, int n = 1) { ptr += n; }
|
||||
static void appendUtf16(ushort *&ptr, ushort uc) { *ptr++ = uc; }
|
||||
static void appendUcs4(ushort *&ptr, uint uc) {
|
||||
appendUtf16(ptr, QChar::highSurrogate(uc));
|
||||
appendUtf16(ptr, QChar::lowSurrogate(uc));
|
||||
}
|
||||
static ushort peekUtf16(const ushort *ptr, int n = 0) { return ptr[n]; }
|
||||
static qptrdiff availableUtf16(const ushort *ptr, const ushort *end) {
|
||||
return end - ptr;
|
||||
}
|
||||
static void advanceUtf16(const ushort *&ptr, int n = 1) { ptr += n; }
|
||||
// it's possible to output to UCS-4 too
|
||||
static void appendUtf16(uint *&ptr, ushort uc) { *ptr++ = uc; }
|
||||
static void appendUcs4(uint *&ptr, uint uc) { *ptr++ = uc; }
|
||||
};
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB |
|
@ -79,7 +79,6 @@ add_subdirectory(3rdparty/QHexView)
|
|||
add_subdirectory(3rdparty/WingCodeEdit)
|
||||
add_subdirectory(3rdparty/Qt-Advanced-Docking-System)
|
||||
add_subdirectory(3rdparty/AngelScript/sdk/angelscript/projects/cmake)
|
||||
add_subdirectory(3rdparty/QJsonModel)
|
||||
|
||||
set(ANGEL_SCRIPT_ADDON_ROOT
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/AngelScript/sdk/add_on")
|
||||
|
@ -272,7 +271,6 @@ set(CLASS_SRC
|
|||
src/class/dockcomponentsfactory.cpp
|
||||
src/class/diffutil.h
|
||||
src/class/diffutil.cpp
|
||||
src/class/clickcallback.h
|
||||
src/class/crashhandler.h
|
||||
src/class/crashhandler.cpp
|
||||
src/class/pluginsystem.h
|
||||
|
@ -315,8 +313,6 @@ set(MODEL_SRC
|
|||
src/model/metadatamodel.cpp
|
||||
src/model/checksummodel.h
|
||||
src/model/checksummodel.cpp
|
||||
src/model/qjsontablemodel.h
|
||||
src/model/qjsontablemodel.cpp
|
||||
src/model/dbgcallstackmodel.h
|
||||
src/model/dbgcallstackmodel.cpp
|
||||
src/model/dbgvarshowmodel.h
|
||||
|
@ -380,7 +376,6 @@ endforeach()
|
|||
set(TRANSLATION_PATH
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QConsoleWidget
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QHexView
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QJsonModel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Qt-Advanced-Docking-System/src
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QWingRibbon
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
@ -514,7 +509,6 @@ target_link_libraries(
|
|||
WingPlugin
|
||||
QHexView
|
||||
WingCodeEdit
|
||||
QJsonModel
|
||||
angelscript
|
||||
qtadvanceddocking-qt${QT_VERSION_MAJOR})
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ add_library(
|
|||
ctltestform.h
|
||||
ctltestform.cpp
|
||||
ctltestform.ui
|
||||
testtablemodel.h
|
||||
testtablemodel.cpp
|
||||
testsettingpage.h
|
||||
testsettingpage.cpp
|
||||
testwingeditorviewwidget.h
|
||||
|
@ -91,4 +89,5 @@ if(TEST_MODE)
|
|||
${WINGHEX_PLUGIN_PATH})
|
||||
endif()
|
||||
|
||||
target_link_libraries(TestPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets WingPlugin)
|
||||
target_link_libraries(TestPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||
WingPlugin)
|
||||
|
|
|
@ -185,12 +185,12 @@
|
|||
<translation>控制器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="1184"/>
|
||||
<location filename="../testform.ui" line="1055"/>
|
||||
<source>Others</source>
|
||||
<translation>其他</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="1245"/>
|
||||
<location filename="../testform.ui" line="1116"/>
|
||||
<source>Other APIs should be Test With Script</source>
|
||||
<translation>其他 API 应该用脚本测试,不提供可视化方式</translation>
|
||||
</message>
|
||||
|
@ -231,7 +231,6 @@
|
|||
<location filename="../testform.ui" line="311"/>
|
||||
<location filename="../testform.ui" line="707"/>
|
||||
<location filename="../testform.ui" line="881"/>
|
||||
<location filename="../testform.ui" line="1070"/>
|
||||
<source>Type</source>
|
||||
<translation>类型</translation>
|
||||
</message>
|
||||
|
@ -266,32 +265,6 @@
|
|||
<source>Color</source>
|
||||
<translation>颜色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.ui" line="1055"/>
|
||||
<source>DataVisual</source>
|
||||
<translation>数据可视化</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.cpp" line="340"/>
|
||||
<location filename="../testform.cpp" line="349"/>
|
||||
<source>UpdateTextTreeError</source>
|
||||
<translation>更新文本树失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.cpp" line="364"/>
|
||||
<source>UpdateTextListByModelError</source>
|
||||
<translation>通过模型更新文本列表失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.cpp" line="374"/>
|
||||
<source>UpdateTextTableByModelError</source>
|
||||
<translation>通过模型更新文本表格失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../testform.cpp" line="385"/>
|
||||
<source>UpdateTextTreeByModelError</source>
|
||||
<translation>通过模型更新文本树失败</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TestPlugin</name>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "ctltestform.h"
|
||||
#include "readertestform.h"
|
||||
#include "testtablemodel.h"
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QFileSystemModel>
|
||||
|
@ -37,8 +36,6 @@ TestForm::TestForm(WingHex::IWingPlugin *plg, QWidget *parent)
|
|||
: WingHex::WingPluginWidget(plg, parent), ui(new Ui::TestForm) {
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->teDataVisual->setAcceptRichText(false);
|
||||
|
||||
ui->saReader->widget()->layout()->addWidget(
|
||||
new ReaderTestForm(plg, ui->tbReaderLogger, this));
|
||||
ui->saCtl->widget()->layout()->addWidget(
|
||||
|
@ -56,10 +53,6 @@ TestForm::TestForm(WingHex::IWingPlugin *plg, QWidget *parent)
|
|||
|
||||
ui->lblauthor->setPixmap(
|
||||
WingHex::HOSTRESPIMG(QStringLiteral("author"), QStringLiteral(".jpg")));
|
||||
|
||||
_click = std::bind(&TestForm::onDVClicked, this, std::placeholders::_1);
|
||||
_dblclick =
|
||||
std::bind(&TestForm::onDVDoubleClicked, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
TestForm::~TestForm() { delete ui; }
|
||||
|
@ -153,16 +146,6 @@ QFileDialog::Options TestForm::getFileDialogOptions() const {
|
|||
return options;
|
||||
}
|
||||
|
||||
void TestForm::onDVClicked(const QModelIndex &index) {
|
||||
logWarn(QStringLiteral("[Test - Click] ") +
|
||||
index.model()->data(index).toString());
|
||||
}
|
||||
|
||||
void TestForm::onDVDoubleClicked(const QModelIndex &index) {
|
||||
msgWarning(this, QStringLiteral("Test - DoubleClick"),
|
||||
index.model()->data(index).toString());
|
||||
}
|
||||
|
||||
void TestForm::on_btnSendLog_clicked() {
|
||||
auto txt = ui->leLogText->text();
|
||||
switch (Level(ui->cbLogLevel->currentIndex())) {
|
||||
|
@ -323,69 +306,6 @@ void TestForm::on_btnGetColor_clicked() {
|
|||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnText_2_clicked() {
|
||||
dataVisualText(ui->teDataVisual->toPlainText(), QStringLiteral("TestForm"));
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextList_clicked() {
|
||||
auto txts = ui->teDataVisual->toPlainText().split('\n');
|
||||
dataVisualTextList(txts, QStringLiteral("TestForm"), _click, _dblclick);
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextTree_clicked() {
|
||||
auto ret =
|
||||
dataVisualTextTree(ui->teDataVisual->toPlainText(),
|
||||
QStringLiteral("TestForm"), _click, _dblclick);
|
||||
if (!ret) {
|
||||
msgCritical(this, QStringLiteral("Test"), tr("UpdateTextTreeError"));
|
||||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextTable_clicked() {
|
||||
auto ret = dataVisualTextTable(
|
||||
ui->teDataVisual->toPlainText(), {"wingsummer", "wingsummer"}, {},
|
||||
QStringLiteral("TestForm"), _click, _dblclick);
|
||||
if (!ret) {
|
||||
msgCritical(this, QStringLiteral("Test"), tr("UpdateTextTreeError"));
|
||||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextListByModel_clicked() {
|
||||
auto model = new QStringListModel;
|
||||
QStringList buffer;
|
||||
for (int i = 0; i < WingHex::SDKVERSION; ++i) {
|
||||
buffer.append("wingsummer" % QString::number(i));
|
||||
}
|
||||
model->setStringList(buffer);
|
||||
auto ret = dataVisualTextListByModel(model, QStringLiteral("TestForm"),
|
||||
_click, _dblclick);
|
||||
if (!ret) {
|
||||
msgCritical(this, QStringLiteral("Test"),
|
||||
tr("UpdateTextListByModelError"));
|
||||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextTableByModel_clicked() {
|
||||
auto model = new TestTableModel;
|
||||
auto ret = dataVisualTextTableByModel(model, QStringLiteral("TestForm"),
|
||||
_click, _dblclick);
|
||||
if (!ret) {
|
||||
msgCritical(this, QStringLiteral("Test"),
|
||||
tr("UpdateTextTableByModelError"));
|
||||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnTextTreeByModel_clicked() {
|
||||
auto model = new QFileSystemModel;
|
||||
model->setRootPath(QDir::currentPath());
|
||||
auto ret = dataVisualTextTreeByModel(model, QStringLiteral("TestForm"),
|
||||
_click, _dblclick);
|
||||
if (!ret) {
|
||||
msgCritical(this, QStringLiteral("Test"),
|
||||
tr("UpdateTextTreeByModelError"));
|
||||
}
|
||||
}
|
||||
|
||||
void TestForm::on_btnStatusVisible_clicked() {
|
||||
if (ui->rbLockedFile->isChecked()) {
|
||||
Q_UNUSED(setLockedFile(true));
|
||||
|
|
|
@ -85,20 +85,6 @@ private slots:
|
|||
|
||||
void on_btnGetColor_clicked();
|
||||
|
||||
void on_btnText_2_clicked();
|
||||
|
||||
void on_btnTextList_clicked();
|
||||
|
||||
void on_btnTextTree_clicked();
|
||||
|
||||
void on_btnTextTable_clicked();
|
||||
|
||||
void on_btnTextListByModel_clicked();
|
||||
|
||||
void on_btnTextTableByModel_clicked();
|
||||
|
||||
void on_btnTextTreeByModel_clicked();
|
||||
|
||||
void on_btnStatusVisible_clicked();
|
||||
|
||||
void on_btnStatusInvisible_clicked();
|
||||
|
@ -121,15 +107,8 @@ private:
|
|||
|
||||
QFileDialog::Options getFileDialogOptions() const;
|
||||
|
||||
void onDVClicked(const QModelIndex &index);
|
||||
|
||||
void onDVDoubleClicked(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
Ui::TestForm *ui;
|
||||
|
||||
WingHex::ClickedCallBack _click;
|
||||
WingHex::ClickedCallBack _dblclick;
|
||||
};
|
||||
|
||||
#endif // TESTFORM_H
|
||||
|
|
|
@ -1050,135 +1050,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_8">
|
||||
<attribute name="title">
|
||||
<string>DataVisual</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_20">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="teDataVisual"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SizeConstraint::SetMinAndMaxSize</enum>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="btnTextList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextList (LineByLine)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="btnTextTree">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextTree (Json)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="btnTextTable">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextTable (Json)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="btnTextListByModel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextListByModel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="btnText_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateText</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="btnTextTableByModel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextTableByModel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="btnTextTreeByModel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">updateTextTreeByModel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string notr="true">WingSummer</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_9">
|
||||
<attribute name="title">
|
||||
<string>Others</string>
|
||||
|
@ -1278,18 +1149,18 @@
|
|||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>btnClearCtl</sender>
|
||||
<sender>btnClearFile</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tbCtlLogger</receiver>
|
||||
<receiver>tbFileLogger</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>271</x>
|
||||
<y>387</y>
|
||||
<x>239</x>
|
||||
<y>388</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>318</x>
|
||||
<y>264</y>
|
||||
<x>290</x>
|
||||
<y>328</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
@ -1310,34 +1181,34 @@
|
|||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>btnClearInput</sender>
|
||||
<sender>btnClearCtl</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tbInputLogger</receiver>
|
||||
<receiver>tbCtlLogger</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>210</x>
|
||||
<y>388</y>
|
||||
<x>271</x>
|
||||
<y>387</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>236</x>
|
||||
<y>332</y>
|
||||
<x>318</x>
|
||||
<y>264</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>btnClearFile</sender>
|
||||
<sender>btnClearText</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tbFileLogger</receiver>
|
||||
<receiver>leToastText</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>239</x>
|
||||
<y>388</y>
|
||||
<x>569</x>
|
||||
<y>271</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>290</x>
|
||||
<y>328</y>
|
||||
<x>468</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
@ -1358,18 +1229,18 @@
|
|||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>btnClearText</sender>
|
||||
<sender>btnClearInput</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>leToastText</receiver>
|
||||
<receiver>tbInputLogger</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>569</x>
|
||||
<y>271</y>
|
||||
<x>210</x>
|
||||
<y>388</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>229</y>
|
||||
<x>236</x>
|
||||
<y>332</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "testtablemodel.h"
|
||||
#include "WingPlugin/iwingpluginbase.h"
|
||||
|
||||
TestTableModel::TestTableModel(QObject *parent) : QAbstractTableModel(parent) {}
|
||||
|
||||
int TestTableModel::rowCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return WingHex::SDKVERSION;
|
||||
}
|
||||
|
||||
int TestTableModel::columnCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return 5;
|
||||
}
|
||||
|
||||
QVariant TestTableModel::data(const QModelIndex &index, int role) const {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::ToolTipRole: {
|
||||
return QStringLiteral("(%1, %2)").arg(index.row()).arg(index.column());
|
||||
}
|
||||
case Qt::TextAlignmentRole:
|
||||
return Qt::AlignCenter;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant TestTableModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
Q_UNUSED(orientation);
|
||||
if (role == Qt::DisplayRole) {
|
||||
return section + 1;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and associated documentation files (the "Software"), to deal
|
||||
** in the Software without restriction, including without limitation the rights
|
||||
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
** copies of the Software, and to permit persons to whom the Software is
|
||||
** furnished to do so.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
** THE SOFTWARE.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef TESTTABLEMODEL_H
|
||||
#define TESTTABLEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
class TestTableModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TestTableModel(QObject *parent = nullptr);
|
||||
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
virtual int rowCount(const QModelIndex &parent) const override;
|
||||
virtual int columnCount(const QModelIndex &parent) const override;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role) const override;
|
||||
};
|
||||
|
||||
#endif // TESTTABLEMODEL_H
|
|
@ -1 +1 @@
|
|||
Subproject commit 95b3250011d0bf76ebd77f9905dc77fd04a46ce7
|
||||
Subproject commit 8d86c185041572bd4735b272669d4117765c2176
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef CLICKCALLBACK_H
|
||||
#define CLICKCALLBACK_H
|
||||
|
||||
#include "WingPlugin/iwingplugin.h"
|
||||
#include "angelscript.h"
|
||||
|
||||
class ClickCallBack {
|
||||
public:
|
||||
ClickCallBack() {}
|
||||
|
||||
ClickCallBack(const WingHex::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::ClickedCallBack &_Right) {
|
||||
*this = ClickCallBack(_Right);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClickCallBack &operator=(WingHex::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::ClickedCallBack _call;
|
||||
asIScriptEngine *_engine = nullptr;
|
||||
asIScriptFunction *_func = nullptr;
|
||||
};
|
||||
|
||||
#endif // CLICKCALLBACK_H
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "pluginsystem.h"
|
||||
#include "AngelScript/sdk/angelscript/source/as_builder.h"
|
||||
#include "QJsonModel/include/QJsonModel.hpp"
|
||||
#include "Qt-Advanced-Docking-System/src/DockAreaWidget.h"
|
||||
#include "class/languagemanager.h"
|
||||
#include "class/logger.h"
|
||||
|
@ -33,10 +32,11 @@
|
|||
#include "dialog/colorpickerdialog.h"
|
||||
#include "dialog/framelessdialogbase.h"
|
||||
#include "dialog/mainwindow.h"
|
||||
#include "model/qjsontablemodel.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfoList>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QMessageBox>
|
||||
#include <QPluginLoader>
|
||||
#include <QScopeGuard>
|
||||
|
@ -1787,99 +1787,6 @@ bool PluginSystem::closeAllFiles(QObject *sender) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualText(QObject *sender, const QString &data,
|
||||
const QString &title) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
_win->m_infotxt->setProperty("__TITLE__", title);
|
||||
_win->m_infotxt->setText(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextList(QObject *sender, const QStringList &data,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
return updateTextList_API(data, title, clicked, dblClicked);
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextTree(QObject *sender, const QString &json,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
return updateTextTree_API(json, title, clicked, dblClicked);
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextTable(QObject *sender, const QString &json,
|
||||
const QStringList &headers,
|
||||
const QStringList &headerNames,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
return updateTextTable_API(json, headers, headerNames, title, clicked,
|
||||
dblClicked);
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextListByModel(QObject *sender,
|
||||
QAbstractItemModel *model,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
if (model) {
|
||||
auto oldmodel = _win->m_infolist->model();
|
||||
if (oldmodel) {
|
||||
oldmodel->deleteLater();
|
||||
}
|
||||
_win->m_infolist->setProperty("__TITLE__", title);
|
||||
_win->m_infolist->setModel(model);
|
||||
_win->m_infoclickfn = clicked;
|
||||
_win->m_infodblclickfn = dblClicked;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextTreeByModel(QObject *sender,
|
||||
QAbstractItemModel *model,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
if (model) {
|
||||
auto oldmodel = _win->m_infotree->model();
|
||||
if (oldmodel) {
|
||||
oldmodel->deleteLater();
|
||||
}
|
||||
_win->m_infotree->setProperty("__TITLE__", title);
|
||||
_win->m_infotree->setModel(model);
|
||||
_win->m_infotreeclickfn = clicked;
|
||||
_win->m_infotreedblclickfn = dblClicked;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PluginSystem::checkErrAllAllowAndReport(QObject *sender,
|
||||
const char *func) {
|
||||
auto p = qobject_cast<WingHex::IWingPlugin *>(sender);
|
||||
|
@ -1904,29 +1811,6 @@ IWingPlugin *PluginSystem::checkPluginAndReport(QObject *sender,
|
|||
return p;
|
||||
}
|
||||
|
||||
bool PluginSystem::dataVisualTextTableByModel(QObject *sender,
|
||||
QAbstractItemModel *model,
|
||||
const QString &title,
|
||||
ClickedCallBack clicked,
|
||||
ClickedCallBack dblClicked) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr || !checkThreadAff()) {
|
||||
return false;
|
||||
}
|
||||
if (model) {
|
||||
auto oldmodel = _win->m_infotable->model();
|
||||
if (oldmodel) {
|
||||
oldmodel->deleteLater();
|
||||
}
|
||||
_win->m_infotable->setProperty("__TITLE__", title);
|
||||
_win->m_infotable->setModel(model);
|
||||
_win->m_infotableclickfn = clicked;
|
||||
_win->m_infotabledblclickfn = dblClicked;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::saveAsCurrent(QObject *sender, const QString &savename) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr) {
|
||||
|
@ -3716,77 +3600,6 @@ void PluginSystem::registerMarcoDevice(IWingDevice *plg) {
|
|||
_scriptMarcos.append(sep + id + sep);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool PluginSystem::checkThreadAff() {
|
||||
if (QThread::currentThread() != qApp->thread()) {
|
||||
Logger::warning(tr("Not allowed operation in non-UI thread"));
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <QVariant>
|
||||
|
||||
#include "WingPlugin/iwingdevice.h"
|
||||
#include "class/clickcallback.h"
|
||||
#include "class/wingangelapi.h"
|
||||
#include "control/editorview.h"
|
||||
|
||||
|
@ -258,18 +257,6 @@ 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);
|
||||
|
||||
public:
|
||||
// fpr crash checking
|
||||
QString currentLoadingPlugin() const;
|
||||
|
@ -735,41 +722,6 @@ public:
|
|||
// extension
|
||||
WING_SERVICE bool closeAllFiles(QObject *sender);
|
||||
|
||||
public:
|
||||
WING_SERVICE bool dataVisualText(QObject *sender, const QString &data,
|
||||
const QString &title);
|
||||
|
||||
WING_SERVICE bool dataVisualTextList(QObject *sender,
|
||||
const QStringList &data,
|
||||
const QString &title,
|
||||
WingHex::ClickedCallBack clicked,
|
||||
WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
WING_SERVICE bool dataVisualTextTree(QObject *sender, const QString &json,
|
||||
const QString &title,
|
||||
WingHex::ClickedCallBack clicked,
|
||||
WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
WING_SERVICE bool dataVisualTextTable(QObject *sender, const QString &json,
|
||||
const QStringList &headers,
|
||||
const QStringList &headerNames,
|
||||
const QString &title,
|
||||
WingHex::ClickedCallBack clicked,
|
||||
WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
// API for Qt Plugin Only
|
||||
WING_SERVICE bool dataVisualTextListByModel(
|
||||
QObject *sender, QAbstractItemModel *model, const QString &title,
|
||||
WingHex::ClickedCallBack clicked, WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
WING_SERVICE bool dataVisualTextTableByModel(
|
||||
QObject *sender, QAbstractItemModel *model, const QString &title,
|
||||
WingHex::ClickedCallBack clicked, WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
WING_SERVICE bool dataVisualTextTreeByModel(
|
||||
QObject *sender, QAbstractItemModel *model, const QString &title,
|
||||
WingHex::ClickedCallBack clicked, WingHex::ClickedCallBack dblClicked);
|
||||
|
||||
private:
|
||||
WingHex::IWingPlugin *checkPluginAndReport(QObject *sender,
|
||||
const char *func);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,9 +23,7 @@
|
|||
|
||||
#include <QFileDialog>
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
class asIScriptEngine;
|
||||
class ScriptMachine;
|
||||
|
@ -97,25 +95,13 @@ private:
|
|||
void installHexBaseType(asIScriptEngine *engine);
|
||||
void installHexReaderAPI(asIScriptEngine *engine);
|
||||
void installHexControllerAPI(asIScriptEngine *engine);
|
||||
void installDataVisualAPI(asIScriptEngine *engine);
|
||||
void installScriptFns(asIScriptEngine *engine);
|
||||
void installScriptUnSafeFns(asIScriptEngine *engine);
|
||||
void installScriptEnums(asIScriptEngine *engine);
|
||||
|
||||
private:
|
||||
template <class T>
|
||||
void registerAPI(asIScriptEngine *engine, const std::function<T> &fn,
|
||||
const char *sig) {
|
||||
_fnbuffer.push_back(fn);
|
||||
auto r = engine->RegisterGlobalFunction(
|
||||
sig, asMETHOD(std::function<T>, operator()),
|
||||
asCALL_THISCALL_ASGLOBAL,
|
||||
std::any_cast<std::function<T>>(&_fnbuffer.back()));
|
||||
Q_ASSERT(r >= 0);
|
||||
Q_UNUSED(r);
|
||||
}
|
||||
|
||||
using WrapperFn = std::function<void(asIScriptGeneric *)>;
|
||||
void registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn,
|
||||
const char *sig);
|
||||
|
||||
private:
|
||||
QStringList cArray2QStringList(const CScriptArray &array, int stringID,
|
||||
|
@ -203,17 +189,6 @@ private:
|
|||
void cleanUpHandles(const QVector<int> &handles);
|
||||
|
||||
private:
|
||||
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,
|
||||
const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options);
|
||||
|
||||
CScriptArray *_HexReader_selectedBytes(qsizetype index);
|
||||
|
||||
CScriptArray *_HexReader_selectionBytes();
|
||||
|
@ -230,26 +205,86 @@ private:
|
|||
|
||||
bool _HexController_appendBytes(const CScriptArray &ba);
|
||||
|
||||
private:
|
||||
bool _DataVisual_updateTextList(const CScriptArray &data,
|
||||
const QString &title,
|
||||
asIScriptFunction *click,
|
||||
asIScriptFunction *dblclick);
|
||||
void _UI_Toast(const QString &message, const QString &icon);
|
||||
|
||||
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,
|
||||
asIScriptFunction *click,
|
||||
asIScriptFunction *dblclick);
|
||||
QColor _Color_get(const QString &caption);
|
||||
|
||||
private:
|
||||
std::vector<std::any> _fnbuffer;
|
||||
void _MSG_AboutQt(const QString &title);
|
||||
|
||||
QMessageBox::StandardButton
|
||||
_MSG_Information(const QString &title, const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton);
|
||||
|
||||
QMessageBox::StandardButton
|
||||
_MSG_Question(const QString &title, const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton);
|
||||
|
||||
QMessageBox::StandardButton
|
||||
_MSG_Warning(const QString &title, const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton);
|
||||
|
||||
QMessageBox::StandardButton
|
||||
_MSG_Critical(const QString &title, const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton);
|
||||
|
||||
void _MSG_About(const QString &title, const QString &text);
|
||||
|
||||
QMessageBox::StandardButton
|
||||
_MSG_msgbox(QMessageBox::Icon icon, const QString &title,
|
||||
const QString &text, QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton);
|
||||
|
||||
private:
|
||||
QString _InputBox_GetText(const QString &title, const QString &label,
|
||||
QLineEdit::EchoMode echo, const QString &text,
|
||||
bool *ok, Qt::InputMethodHints inputMethodHints);
|
||||
|
||||
QString _InputBox_GetMultiLineText(const QString &title,
|
||||
const QString &label,
|
||||
const QString &text, bool *ok,
|
||||
Qt::InputMethodHints inputMethodHints);
|
||||
|
||||
QString _InputBox_getItem(const QString &title, const QString &label,
|
||||
const CScriptArray &items, int current,
|
||||
bool editable, bool *ok,
|
||||
Qt::InputMethodHints inputMethodHints);
|
||||
|
||||
int _InputBox_GetInt(const QString &title, const QString &label, int value,
|
||||
int minValue, int maxValue, int step, bool *ok);
|
||||
|
||||
double _InputBox_GetDouble(const QString &title, const QString &label,
|
||||
double value, double minValue, double maxValue,
|
||||
int decimals, bool *ok, double step);
|
||||
|
||||
private:
|
||||
QString _FileDialog_GetExistingDirectory(const QString &caption,
|
||||
const QString &dir,
|
||||
QFileDialog::Options options);
|
||||
|
||||
QString _FileDialog_GetOpenFileName(const QString &caption,
|
||||
const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options);
|
||||
|
||||
CScriptArray *_FileDialog_getOpenFileNames(const QString &caption,
|
||||
const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options);
|
||||
|
||||
QString _FileDialog_GetSaveFileName(const QString &caption,
|
||||
const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options);
|
||||
|
||||
private:
|
||||
QVector<IWingPlugin::ScriptFnInfo> _sfns;
|
||||
QHash<QString, QHash<QString, qsizetype>> _rfns;
|
||||
|
||||
|
|
|
@ -13,5 +13,4 @@ The following components are all third-party components used by the software. Th
|
|||
* [cpptrace](https://github.com/jeremy-rifkin/cpptrace) (MIT)
|
||||
* [QConsoleWidget](https://github.com/gapost/qconsolewidget) (MIT, **FORK** -> AGPL-3.0)
|
||||
* [QColorPicker](https://github.com/arsdever/qcolorpicker) (MIT)
|
||||
* [QtJsonModel](https://github.com/dridk/QJsonmodel) (MIT)
|
||||
* [Qt](https://www.qt.io/) (LGPL)
|
||||
|
|
|
@ -565,7 +565,6 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
|
|||
qApp->processEvents();
|
||||
}
|
||||
|
||||
buildUpVisualDataDock(m_dock, ads::CenterDockWidgetArea, bottomLeftArea);
|
||||
qApp->processEvents();
|
||||
|
||||
m_bottomViewArea = bottomRightArea;
|
||||
|
@ -1029,265 +1028,6 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
|
|||
return dock->addDockWidget(area, dw, areaw);
|
||||
}
|
||||
|
||||
ads::CDockAreaWidget *
|
||||
MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
|
||||
ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw) {
|
||||
using namespace ads;
|
||||
|
||||
auto efilter = new EventFilter(QEvent::DynamicPropertyChange, this);
|
||||
connect(efilter, &EventFilter::eventTriggered, 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->setEditTriggers(QListView::EditTrigger::NoEditTriggers);
|
||||
connect(m_infolist, &QListView::clicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infoclickfn) {
|
||||
m_infoclickfn(index);
|
||||
}
|
||||
});
|
||||
connect(m_infolist, &QListView::doubleClicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infodblclickfn) {
|
||||
m_infodblclickfn(index);
|
||||
}
|
||||
});
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("DVList"), tr("DVList"),
|
||||
m_infolist);
|
||||
m_infolist->setProperty(dpname, tr("DVList"));
|
||||
m_infolist->setProperty(dockpname, quintptr(dw));
|
||||
m_infolist->installEventFilter(efilter);
|
||||
m_infolist->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
m_infolist->addAction(
|
||||
newAction(QStringLiteral("copy"), tr("Copy"), [this]() {
|
||||
auto idx = m_infolist->currentIndex();
|
||||
if (idx.isValid()) {
|
||||
qApp->clipboard()->setText(
|
||||
m_infolist->model()->data(idx).toString());
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("copy")),
|
||||
tr("CopyToClipBoard"));
|
||||
}
|
||||
}));
|
||||
m_infolist->addAction(
|
||||
newAction(QStringLiteral("export"), tr("ExportResult"), [this]() {
|
||||
auto model = m_infotable->model();
|
||||
if (!model) {
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("NothingToSave"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto filename = WingFileDialog::getSaveFileName(
|
||||
this, tr("ChooseSaveFile"), m_lastusedpath,
|
||||
QStringLiteral("TXT (*.txt)"));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFile f(filename);
|
||||
if (!f.open(QFile::WriteOnly | QFile::Text)) {
|
||||
WingMessageBox::critical(this, tr("Error"),
|
||||
tr("FilePermission"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto total = model->rowCount();
|
||||
for (int i = 0; i < total; ++i) {
|
||||
f.write(model->data(model->index(i, 0)).toString().toUtf8());
|
||||
f.write("\n");
|
||||
}
|
||||
f.close();
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("SaveSuccessfully"));
|
||||
}));
|
||||
m_infolist->addAction(
|
||||
newAction(QStringLiteral("del"), tr("ClearResult"), [this]() {
|
||||
auto model = m_infolist->model();
|
||||
model->removeRows(0, model->rowCount());
|
||||
m_infolist->setProperty("__TITLE__", {});
|
||||
}));
|
||||
auto ar = dock->addDockWidget(area, dw, areaw);
|
||||
|
||||
m_infotree = new QTreeView(this);
|
||||
m_infotree->setEditTriggers(QTreeView::EditTrigger::NoEditTriggers);
|
||||
connect(m_infotree, &QTreeView::clicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infotreeclickfn) {
|
||||
m_infotreeclickfn(index);
|
||||
}
|
||||
});
|
||||
connect(m_infotree, &QTreeView::doubleClicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infotreedblclickfn) {
|
||||
m_infotreedblclickfn(index);
|
||||
}
|
||||
});
|
||||
dw = buildDockWidget(dock, QStringLiteral("DVTree"), tr("DVTree"),
|
||||
m_infotree);
|
||||
m_infotree->setProperty(dpname, tr("DVTree"));
|
||||
m_infotree->setProperty(dockpname, quintptr(dw));
|
||||
m_infotree->installEventFilter(efilter);
|
||||
m_infotree->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
m_infotree->addAction(
|
||||
newAction(QStringLiteral("copy"), tr("Copy"), [this]() {
|
||||
auto idx = m_infotree->currentIndex();
|
||||
if (idx.isValid()) {
|
||||
qApp->clipboard()->setText(
|
||||
m_infotree->model()->data(idx).toString());
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("copy")),
|
||||
tr("CopyToClipBoard"));
|
||||
}
|
||||
}));
|
||||
m_infotree->addAction(
|
||||
newAction(QStringLiteral("export"), tr("ExportResult"), [this]() {
|
||||
auto model = m_infotable->model();
|
||||
if (!model) {
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("NothingToSave"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto filename = WingFileDialog::getSaveFileName(
|
||||
this, tr("ChooseSaveFile"), m_lastusedpath,
|
||||
QStringLiteral("Json (*.json)"));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonArray rootArray;
|
||||
for (int row = 0; row < model->rowCount(); ++row) {
|
||||
QModelIndex index = model->index(row, 0);
|
||||
rootArray.append(extractModelData(model, index));
|
||||
}
|
||||
|
||||
QJsonDocument jsonDocument(rootArray);
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
WingMessageBox::critical(this, tr("Error"),
|
||||
tr("FilePermission"));
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(jsonDocument.toJson(QJsonDocument::Indented));
|
||||
file.close();
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("SaveSuccessfully"));
|
||||
}));
|
||||
m_infotree->addAction(
|
||||
newAction(QStringLiteral("del"), tr("ClearResult"), [this]() {
|
||||
auto model = m_infotree->model();
|
||||
model->removeRows(0, model->rowCount());
|
||||
m_infotree->setProperty("__TITLE__", {});
|
||||
}));
|
||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||
|
||||
m_infotable = new QTableView(this);
|
||||
m_infotable->setEditTriggers(QTableView::EditTrigger::NoEditTriggers);
|
||||
connect(m_infotable, &QTableView::clicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infotableclickfn) {
|
||||
m_infotableclickfn(index);
|
||||
}
|
||||
});
|
||||
connect(m_infotable, &QTableView::doubleClicked, this,
|
||||
[this](const QModelIndex &index) {
|
||||
if (m_infotabledblclickfn) {
|
||||
m_infotabledblclickfn(index);
|
||||
}
|
||||
});
|
||||
dw = buildDockWidget(dock, QStringLiteral("DVTable"), tr("DVTable"),
|
||||
m_infotable);
|
||||
m_infotable->setProperty(dpname, tr("DVTable"));
|
||||
m_infotable->setProperty(dockpname, quintptr(dw));
|
||||
m_infotable->installEventFilter(efilter);
|
||||
m_infotable->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
m_infotable->addAction(
|
||||
newAction(QStringLiteral("copy"), tr("Copy"), [this]() {
|
||||
auto idx = m_infotable->currentIndex();
|
||||
if (idx.isValid()) {
|
||||
qApp->clipboard()->setText(
|
||||
m_infotable->model()->data(idx).toString());
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("copy")),
|
||||
tr("CopyToClipBoard"));
|
||||
}
|
||||
}));
|
||||
m_infotable->addAction(
|
||||
newAction(QStringLiteral("export"), tr("ExportResult"), [this]() {
|
||||
auto model = m_infotable->model();
|
||||
saveTableContent(model);
|
||||
}));
|
||||
m_infotable->addAction(
|
||||
newAction(QStringLiteral("del"), tr("ClearResult"), [this]() {
|
||||
auto model = m_infotable->model();
|
||||
model->removeRows(0, model->rowCount());
|
||||
m_infotable->setProperty("__TITLE__", {});
|
||||
}));
|
||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||
|
||||
m_infotxt = new QTextBrowser(this);
|
||||
dw = buildDockWidget(dock, QStringLiteral("DVText"), tr("DVText"),
|
||||
m_infotxt);
|
||||
m_infotxt->setProperty(dpname, tr("DVText"));
|
||||
m_infotxt->setProperty(dockpname, quintptr(dw));
|
||||
m_infotxt->installEventFilter(efilter);
|
||||
m_infotxt->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
auto menu = m_infotxt->createStandardContextMenu();
|
||||
menu->addSeparator();
|
||||
menu->addAction(
|
||||
newAction(QStringLiteral("export"), tr("ExportResult"), [this]() {
|
||||
auto filename = WingFileDialog::getSaveFileName(
|
||||
this, tr("ChooseSaveFile"), m_lastusedpath,
|
||||
QStringLiteral("TXT (*.txt)"));
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
WingMessageBox::critical(this, tr("Error"),
|
||||
tr("FilePermission"));
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(m_infotxt->toPlainText().toUtf8());
|
||||
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("SaveSuccessfully"));
|
||||
}));
|
||||
menu->addAction(
|
||||
newAction(QStringLiteral("del"), tr("ClearResult"), [this]() {
|
||||
m_infotxt->clear();
|
||||
m_infotxt->setProperty("__TITLE__", {});
|
||||
}));
|
||||
connect(m_infotxt, &QTextBrowser::customContextMenuRequested, this,
|
||||
[=](const QPoint &pos) {
|
||||
menu->popup(m_infotxt->viewport()->mapToGlobal(pos));
|
||||
});
|
||||
|
||||
dock->addDockWidget(CenterDockWidgetArea, dw, ar);
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
RibbonTabContent *MainWindow::buildFilePage(RibbonTabContent *tab) {
|
||||
auto shortcuts = QKeySequences::instance();
|
||||
{
|
||||
|
@ -4035,32 +3775,6 @@ void MainWindow::onOutputBgScriptOutput(
|
|||
lastInfo.second = qMakePair(message.row, message.col);
|
||||
}
|
||||
|
||||
QJsonObject MainWindow::extractModelData(const QAbstractItemModel *model,
|
||||
const QModelIndex &parent) {
|
||||
QJsonObject jsonObject;
|
||||
|
||||
// Add data for the current row
|
||||
for (int col = 0; col < model->columnCount(parent); ++col) {
|
||||
QVariant data =
|
||||
model->data(model->index(parent.row(), col, parent.parent()));
|
||||
QString header = model->headerData(col, Qt::Horizontal).toString();
|
||||
jsonObject[header.isEmpty() ? tr("Column %1").arg(col) : header] =
|
||||
data.toString();
|
||||
}
|
||||
|
||||
// Recursively add child rows
|
||||
QJsonArray children;
|
||||
for (int row = 0; row < model->rowCount(parent); ++row) {
|
||||
QModelIndex childIndex = model->index(row, 0, parent);
|
||||
children.append(extractModelData(model, childIndex));
|
||||
}
|
||||
|
||||
if (!children.isEmpty())
|
||||
jsonObject["children"] = children;
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
|
||||
// plugin first checking
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "Qt-Advanced-Docking-System/src/DockManager.h"
|
||||
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
|
||||
#include "WingPlugin/iwingplugin.h"
|
||||
#include "class/clickcallback.h"
|
||||
#include "class/recentfilemanager.h"
|
||||
#include "class/scriptmanager.h"
|
||||
#include "control/editorview.h"
|
||||
|
@ -64,9 +63,6 @@ class MainWindow : public FramelessMainWindow {
|
|||
|
||||
friend class PluginSystem;
|
||||
|
||||
using ClickedCallBack = ClickCallBack;
|
||||
using DblClickedCallBack = ClickCallBack;
|
||||
|
||||
public:
|
||||
explicit MainWindow(SplashDialog *splash);
|
||||
virtual ~MainWindow() override;
|
||||
|
@ -125,9 +121,6 @@ private:
|
|||
ads::CDockAreaWidget *
|
||||
buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw = nullptr);
|
||||
ads::CDockAreaWidget *
|
||||
buildUpVisualDataDock(ads::CDockManager *dock, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw = nullptr);
|
||||
|
||||
RibbonTabContent *buildFilePage(RibbonTabContent *tab);
|
||||
RibbonTabContent *buildEditPage(RibbonTabContent *tab);
|
||||
|
@ -268,10 +261,6 @@ private:
|
|||
|
||||
void onOutputBgScriptOutput(const ScriptMachine::MessageInfo &message);
|
||||
|
||||
private:
|
||||
QJsonObject extractModelData(const QAbstractItemModel *model,
|
||||
const QModelIndex &parent = QModelIndex());
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
|
@ -507,20 +496,6 @@ private:
|
|||
QTableViewExt *m_metadatas = nullptr;
|
||||
MetaDataModel *_metadataEmpty = nullptr;
|
||||
|
||||
// data visualization widgets
|
||||
QListView *m_infolist = nullptr;
|
||||
ClickedCallBack m_infoclickfn;
|
||||
DblClickedCallBack m_infodblclickfn;
|
||||
|
||||
QTreeView *m_infotree = nullptr;
|
||||
ClickedCallBack m_infotreeclickfn;
|
||||
DblClickedCallBack m_infotreedblclickfn;
|
||||
|
||||
QTableView *m_infotable = nullptr;
|
||||
QTextBrowser *m_infotxt = nullptr;
|
||||
ClickedCallBack m_infotableclickfn;
|
||||
DblClickedCallBack m_infotabledblclickfn;
|
||||
|
||||
QMap<ToolButtonIndex, QToolButton *> m_toolBtneditors;
|
||||
|
||||
QAction *m_aDelBookMark = nullptr;
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "qjsontablemodel.h"
|
||||
#include <QJsonObject>
|
||||
|
||||
QJsonTableModel::QJsonTableModel(const QJsonTableModel::Header &header,
|
||||
QObject *parent)
|
||||
: QAbstractTableModel(parent), m_header(header) {}
|
||||
|
||||
bool QJsonTableModel::setJson(const QJsonDocument &json) {
|
||||
return setJson(json.array());
|
||||
}
|
||||
|
||||
bool QJsonTableModel::setJson(const QJsonArray &array) {
|
||||
beginResetModel();
|
||||
m_json = array;
|
||||
endResetModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant QJsonTableModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const {
|
||||
if (role != Qt::DisplayRole) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (orientation) {
|
||||
case Qt::Horizontal:
|
||||
return m_header[section]["title"];
|
||||
case Qt::Vertical:
|
||||
// return section + 1;
|
||||
return QVariant();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
int QJsonTableModel::rowCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return m_json.size();
|
||||
}
|
||||
|
||||
int QJsonTableModel::columnCount(const QModelIndex &parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return m_header.size();
|
||||
}
|
||||
|
||||
QJsonObject QJsonTableModel::getJsonObject(const QModelIndex &index) const {
|
||||
const QJsonValue &value = m_json[index.row()];
|
||||
return value.toObject();
|
||||
}
|
||||
|
||||
QVariant QJsonTableModel::data(const QModelIndex &index, int role) const {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole: {
|
||||
QJsonObject obj = getJsonObject(index);
|
||||
const QString &key = m_header[index.column()]["index"];
|
||||
if (obj.contains(key)) {
|
||||
QJsonValue v = obj[key];
|
||||
|
||||
if (v.isString()) {
|
||||
return v.toString();
|
||||
} else if (v.isDouble()) {
|
||||
return QString::number(v.toDouble());
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::ToolTipRole:
|
||||
return QVariant();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef QJSONTABLEMODEL_H
|
||||
#define QJSONTABLEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QHash>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
class QJsonTableModel : public QAbstractTableModel {
|
||||
public:
|
||||
typedef QHash<QString, QString> Heading;
|
||||
typedef QVector<Heading> Header;
|
||||
QJsonTableModel(const Header &header, QObject *parent = 0);
|
||||
|
||||
bool setJson(const QJsonDocument &json);
|
||||
bool setJson(const QJsonArray &array);
|
||||
|
||||
virtual QJsonObject getJsonObject(const QModelIndex &index) const;
|
||||
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
virtual QVariant data(const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const;
|
||||
|
||||
private:
|
||||
Header m_header;
|
||||
QJsonArray m_json;
|
||||
};
|
||||
|
||||
#endif // QJSONTABLEMODEL_H
|
Loading…
Reference in New Issue