fix: 移除更新不兼容的脚本Json支持;Linux下文件权限优化;

This commit is contained in:
寂静的羽夏 2025-02-09 23:06:06 +08:00
parent cfb1759a39
commit 06f48375cf
20 changed files with 1566 additions and 1869 deletions

3
.gitmodules vendored
View File

@ -8,6 +8,3 @@
path = 3rdparty/AngelScript
url = git@github.com:Wing-summer/AngelScript.git
branch=stable
[submodule "3rdparty/json"]
path = 3rdparty/json
url = git@github.com:nlohmann/json.git

1
3rdparty/json vendored

@ -1 +0,0 @@
Subproject commit 606b6347edf0758c531abb6c36743e09a4c48a84

View File

@ -77,7 +77,6 @@ add_subdirectory(3rdparty/qcodeedit2)
add_subdirectory(3rdparty/Qt-Advanced-Docking-System)
add_subdirectory(3rdparty/AngelScript/sdk/angelscript/projects/cmake)
add_subdirectory(3rdparty/QJsonModel)
add_subdirectory(3rdparty/json)
set(ANGEL_SCRIPT_ADDON_ROOT
"${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/AngelScript/sdk/add_on")
@ -198,6 +197,7 @@ set(CONTROL_SRC
set(CLASS_SRC
src/class/logger.cpp
src/class/logger.h
src/class/scopeguard.h
src/class/skinmanager.cpp
src/class/skinmanager.h
src/class/workspacemanager.cpp
@ -334,8 +334,7 @@ set(SCRIPT_ADDON_SRC
src/scriptaddon/scriptregex.cpp
src/scriptaddon/scriptcolor.h
src/scriptaddon/scriptcolor.cpp
src/scriptaddon/scriptjson.cpp
src/scriptaddon/scriptjson.h)
src/scriptaddon/scriptjson.h src/scriptaddon/scriptjson.cpp)
set(CODEEDIT_WIDGET
src/qcodeeditwidget/qgotolinepanel.h
@ -507,7 +506,6 @@ target_link_libraries(
QCodeEditor2
QJsonModel
angelscript
nlohmann_json::nlohmann_json
qtadvanceddocking-qt${QT_VERSION_MAJOR})
if(WINGHEX_USE_FRAMELESS)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,20 +30,7 @@ QString AngelObjString::stringToString(void *obj, asDebugger *dbg) {
// We know the received object is a string
QString *val = reinterpret_cast<QString *>(obj);
constexpr auto limit = 100;
// Format the output string
if (val->length() < limit) {
return *val;
} else {
QString str;
QTextStream s(&str);
s << tr("(len=") << val->length() << QStringLiteral(") \"") << *val
<< QStringLiteral("...");
return str;
}
return *val;
}
QString AngelObjString::arrayToString(void *obj, asDebugger *dbg) {
@ -96,8 +83,6 @@ QString AngelObjString::dictionaryToString(void *obj, asDebugger *dbg) {
// active, the debugger will use the engine held inside it by
// default, but in an environment where there multiple engines this
// might not be the correct instance).
asIScriptContext *ctx = asGetActiveContext();
s << dbg->toString(const_cast<void *>(val), typeId, engine);
if (n < dic->GetSize() - 1)
@ -112,7 +97,7 @@ QString AngelObjString::colorToString(void *obj, asDebugger *dbg) {
auto color = reinterpret_cast<QColor *>(obj);
QString str;
QTextStream s(&str);
s << QStringLiteral("QColor(") << color->name() << QStringLiteral(")");
s << QStringLiteral("color(") << color->name() << QStringLiteral(")");
return str;
}

View File

@ -475,7 +475,8 @@ QString asDebugger::toString(void *value, asUINT typeId,
// this type
s << it.value()(value, this);
} else {
s << tr("NoPrintSupportFor:") << type->GetName();
// Unknown type: type + address
s << type->GetName() << '(' << value << ')';
}
}
} else

View File

@ -300,8 +300,7 @@ void QAsParser::addClassCompletion(asIScriptEngine *engine) {
auto b = obj->GetBehaviourByIndex(i, &bv);
switch (bv) {
case asBEHAVE_CONSTRUCT:
case asBEHAVE_DESTRUCT: {
case asBEHAVE_CONSTRUCT: {
// only these are supported
b->AddRef();
FnInfo fn;

19
src/class/scopeguard.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef SCOPEGUARD_H
#define SCOPEGUARD_H
#include <QtGlobal>
template <typename CtorFn, typename DctorFn>
class ScopeGuard {
const DctorFn &dctorfn;
Q_DISABLE_COPY_MOVE(ScopeGuard)
public:
ScopeGuard(CtorFn &&ctorfn, DctorFn &&dctorfn) : dctorfn(dctorfn) {
ctorfn();
}
~ScopeGuard() { dctorfn(); }
};
#endif // SCOPEGUARD_H

View File

@ -391,7 +391,7 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) {
_engine->GarbageCollect();
// Release all contexts that have been allocated
for (auto ctx : _ctxPool) {
for (auto &ctx : _ctxPool) {
ctx->Release();
}
@ -1611,7 +1611,7 @@ void ScriptMachine::registerEngineAddon(asIScriptEngine *engine) {
RegisterScriptGrid(engine);
RegisterScriptHandle(engine);
RegisterColor(engine);
RegisterScriptJson(engine);
RegisterQJson(engine);
registerExceptionRoutines(engine);
registerEngineAssert(engine);
}

View File

@ -21,8 +21,8 @@
#include "class/skinmanager.h"
#include "qeditor.h"
#include "settings/settings.h"
#include "utilities.h"
#include <QApplication>
#include <QFileInfo>
#include <QMetaEnum>
@ -108,6 +108,11 @@ void SettingManager::load() {
auto defaultFontSize = _defaultFont.pointSize();
Q_ASSERT(defaultFontSize > 0);
HANDLE_CONFIG;
if (!CONFIG.isWritable()) {
Logger::warning(tr("ConfigUnableSave"));
}
READ_CONFIG_INT(m_themeID, SKIN_THEME, 0);
m_themeID = qBound(0, m_themeID,
QMetaEnum::fromType<SkinManager::Theme>().keyCount());

View File

@ -21,6 +21,7 @@
#include "QHexView/document/buffer/qmemorybuffer.h"
#include "Qt-Advanced-Docking-System/src/DockWidgetTab.h"
#include "class/qkeysequences.h"
#include "class/settingmanager.h"
#include "class/workspacemanager.h"
#include "plugin/pluginsystem.h"
@ -31,6 +32,7 @@
#include <QVBoxLayout>
#ifdef Q_OS_LINUX
#include "class/scopeguard.h"
#include <unistd.h>
#endif
@ -400,7 +402,6 @@ ErrFile EditorView::openWorkSpace(const QString &filename) {
auto c = file.mid(extPrefix.length());
auto ci = c.indexOf('/');
auto ext = c.left(ci);
auto path = c.mid(ci + 1);
ret = openExtFile(ext, file);
} else {
// regard as regular files
@ -444,6 +445,33 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
#ifdef Q_OS_LINUX
bool needAdjustFile = !QFile::exists(fileName);
bool needAdjustWs = false;
ScopeGuard guard(
[] {},
[&] {
if (Utilities::isRoot()) {
// a trick off when root under linux OS
// When new file created, change file's permission to 666.
// Because you cannot open it when you use it in common user
// after saving under root user.
// It's a workaround and not eligent for permission system
if (needAdjustFile) {
if (Utilities::isFileOwnerRoot(fileName)) {
Utilities::fixUpFilePermissions(fileName);
}
}
if (needAdjustWs) {
if (Utilities::isFileOwnerRoot(workSpaceName)) {
Utilities::fixUpFilePermissions(workSpaceName);
}
}
}
});
#endif
if (isNewFile()) {
@ -518,30 +546,6 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
}
}
#ifdef Q_OS_LINUX
if (Utilities::isRoot()) {
// a trick off when root under linux OS
// When new file created, change file's permission to 666.
// Because you cannot open it when you use it in common user
// after saving under root user.
// It's a workaround and not eligent for permission system
if (needAdjustFile) {
if (Utilities::isFileOwnerRoot(fileName)) {
Utilities::fixUpFilePermissions(fileName);
}
}
if (needAdjustWs) {
if (Utilities::isFileOwnerRoot(workSpaceName)) {
Utilities::fixUpFilePermissions(workSpaceName);
}
}
}
#endif
return ErrFile::Success;
}

View File

@ -52,48 +52,32 @@ void ScriptingConsole::init() {
connect(_sp, &ScriptConsoleMachine::onOutput, this,
[=](ScriptConsoleMachine::MessageType type,
const ScriptConsoleMachine::MessageInfo &message) {
// If running ouput in the console,
// otherwise logging.
if (_sp->isRunning()) {
switch (type) {
case ScriptMachine::MessageType::Info:
stdOut(tr("[Info]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Warn:
stdWarn(tr("[Warn]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Error:
stdErr(tr("[Error]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Print:
switch (type) {
case ScriptMachine::MessageType::Info:
stdOut(tr("[Info]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Warn:
stdWarn(tr("[Warn]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Error:
stdErr(tr("[Error]") + message.message);
_s << Qt::flush;
newLine();
break;
case ScriptMachine::MessageType::Print:
// If running ouput in the console,
// otherwise logging.
if (_sp->isRunning()) {
stdOut(message.message);
break;
}
} else {
switch (type) {
case ScriptMachine::MessageType::Info:
Logger::logPrint(Logger::packInfoStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Warn:
Logger::logPrint(Logger::packWarnStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Error:
Logger::logPrint(Logger::packErrorStr(
packUpLoggingStr(message.message)));
break;
case ScriptMachine::MessageType::Print:
} else {
Logger::logPrint(Logger::packDebugStr(
packUpLoggingStr(message.message)));
break;
}
break;
}
});

View File

@ -32,6 +32,7 @@
#include "class/logger.h"
#include "class/qkeysequences.h"
#include "class/richtextitemdelegate.h"
#include "class/scopeguard.h"
#include "class/scriptconsolemachine.h"
#include "class/settingmanager.h"
#include "class/wingfiledialog.h"
@ -3622,14 +3623,10 @@ ErrFile MainWindow::saveEditor(EditorView *editor, const QString &filename,
}
auto isNewFile = editor->isNewFile();
if (isNewFile) {
if (isNewFile && filename.isEmpty()) {
return ErrFile::IsNewFile;
}
if (!writeSafeCheck(false, {})) {
return ErrFile::Permission;
}
auto oldName = editor->fileName();
auto newName = filename.isEmpty() ? oldName : filename;
@ -3877,20 +3874,6 @@ QHexView *MainWindow::currentHexView() {
return editor->hexEditor();
}
bool MainWindow::writeSafeCheck(bool isNewFile, const QString &savePath) {
if (Utilities::isRoot()) {
if (isNewFile || savePath.isEmpty()) {
return false;
}
QFileInfo finfo(savePath);
if (!finfo.exists()) {
return false;
}
}
return true;
}
void MainWindow::loadCacheIcon() {
_infoSaved = ICONRES(QStringLiteral("saved"));

View File

@ -258,8 +258,6 @@ private:
QHexView *currentHexView();
bool writeSafeCheck(bool isNewFile, const QString &savePath);
void loadCacheIcon();
QMessageBox::StandardButton saveRequest();
@ -275,19 +273,6 @@ protected:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
private:
template <typename CtorFn, typename DctorFn>
class ScopeGuard {
const DctorFn &dctorfn;
Q_DISABLE_COPY_MOVE(ScopeGuard)
public:
ScopeGuard(CtorFn &&ctorfn, DctorFn &&dctorfn) : dctorfn(dctorfn) {
ctorfn();
}
~ScopeGuard() { dctorfn(); }
};
template <typename Func>
inline QToolButton *
addPannelAction(RibbonButtonGroup *pannel, const QString &iconName,

View File

@ -1163,6 +1163,7 @@ void ScriptingDialog::on_newfile() {
// create an empty file
QFile f(filename);
f.open(QFile::WriteOnly | QFile::Text);
f.write("int main() {\n return 0;\n}\n");
f.close();
if (e) {
@ -1477,7 +1478,6 @@ void ScriptingDialog::closeEvent(QCloseEvent *event) {
auto &set = SettingManager::instance();
set.setRecentScriptFiles(m_recentmanager->saveRecent());
set.save(SettingManager::NONE);
FramelessMainWindow::closeEvent(event);
}

View File

@ -551,21 +551,10 @@ QString PluginSystem::getPluginID(IWingPluginBase *plg) const {
}
void PluginSystem::loadExtPlugin() {
#ifdef QT_DEBUG
QDir plugindir(QCoreApplication::applicationDirPath() + QDir::separator() +
QStringLiteral("plugin"));
#ifdef Q_OS_WIN
plugindir.setNameFilters({"*.dll", "*.wingplg"});
#else
plugindir.setNameFilters({"*.so", "*.wingplg"});
#endif
#else
QDir plugindir(QCoreApplication::applicationDirPath() + QDir::separator() +
QStringLiteral("plugin"));
plugindir.setNameFilters({"*.wingplg"});
#endif
Logger::newLine();
checkDirRootSafe(plugindir);
auto plgs = plugindir.entryInfoList();
@ -619,21 +608,10 @@ void PluginSystem::loadExtPlugin() {
}
void PluginSystem::loadDevicePlugin() {
#ifdef QT_DEBUG
QDir devdir(QCoreApplication::applicationDirPath() + QDir::separator() +
QStringLiteral("devdrv"));
#ifdef Q_OS_WIN
devdir.setNameFilters({"*.dll", "*.wingdrv"});
#else
devdir.setNameFilters({"*.so", "*.wingdrv"});
#endif
#else
QDir devdir(QCoreApplication::applicationDirPath() + QDir::separator() +
QStringLiteral("devdrv"));
devdir.setNameFilters({"*.wingdrv"});
#endif
Logger::newLine();
checkDirRootSafe(devdir);
auto plgs = devdir.entryInfoList();
@ -655,15 +633,17 @@ void PluginSystem::loadDevicePlugin() {
}
void PluginSystem::checkDirRootSafe(const QDir &dir) {
auto testFileName =
dir.absoluteFilePath(QUuid::createUuid().toString(QUuid::Id128));
if (!Utilities::isRoot()) {
auto testFileName =
dir.absoluteFilePath(QUuid::createUuid().toString(QUuid::Id128));
QFile f(testFileName);
if (f.open(QFile::WriteOnly)) {
f.close();
f.remove();
Logger::warning(QStringLiteral("<i><u>") % tr("UnsafePluginDir") %
QStringLiteral("</u></i>"));
QFile f(testFileName);
if (f.open(QFile::WriteOnly)) {
f.close();
f.remove();
Logger::warning(QStringLiteral("<i><u>") % tr("UnsafePluginDir") %
QStringLiteral("</u></i>"));
}
}
}
@ -3037,6 +3017,8 @@ void PluginSystem::loadAllPlugin() {
loadPlugin(cstructplg, meta, setd);
}
Logger::newLine();
bool ok;
auto disAll =

View File

@ -25,6 +25,7 @@ void RegisterColor(asIScriptEngine *engine) {
asOBJ_APP_CLASS_ALLINTS |
asGetTypeTraits<QColor>());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
// Register the constructors
r = engine->RegisterObjectBehaviour(
@ -33,6 +34,17 @@ void RegisterColor(asIScriptEngine *engine) {
void),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectBehaviour(
"color", asBEHAVE_CONSTRUCT, "void f(const string &in name)",
asFUNCTIONPR([](void *memory,
const QString &name) { new (memory) QColor(name); },
(void *, const QString &), void),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectBehaviour(
"color", asBEHAVE_CONSTRUCT, "void f(int r, int g, int b, int a = 255)",
asFUNCTIONPR([](void *memory, int r, int g, int b,
@ -40,6 +52,7 @@ void RegisterColor(asIScriptEngine *engine) {
(void *, int, int, int, int), void),
asCALL_CDECL_OBJFIRST);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
// Register the methods
r = engine->RegisterObjectMethod(
@ -47,43 +60,54 @@ void RegisterColor(asIScriptEngine *engine) {
asMETHODPR(QColor, setRgb, (int, int, int, int), void),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int red() const",
asMETHOD(QColor, red), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int green() const",
asMETHOD(QColor, green), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int blue() const",
asMETHOD(QColor, blue), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int alpha() const",
asMETHOD(QColor, alpha), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod(
"color", "void setHsv(int r, int g, int b, int a = 255)",
asMETHODPR(QColor, setHsv, (int, int, int, int), void),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int hsvHue() const",
asMETHOD(QColor, hsvHue), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int hsvSaturation() const",
asMETHOD(QColor, hsvSaturation),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
r = engine->RegisterObjectMethod("color", "int value() const",
asMETHOD(QColor, value), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
r = engine->RegisterObjectMethod("color", "string name()",
asMETHOD(QColor, name), asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
#else
r = engine->RegisterObjectMethod(
"color", "string name()", asMETHODPR(QColor, name, () const, QString),
asCALL_THISCALL);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +1,31 @@
//
// Script JSON.
//
#ifndef _ScriptJSON_h_
#define _ScriptJSON_h_
/*==============================================================================
** 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 SCRIPTJSON_H
#define SCRIPTJSON_H
#ifndef ANGELSCRIPT_H
// Avoid having to inform include path if header is already include before
#include <angelscript.h>
#include "AngelScript/sdk/angelscript/include/angelscript.h"
#endif
#include <string>
typedef std::string jsonKey_t;
#include "json/include/nlohmann/json.hpp"
using json = nlohmann::json;
BEGIN_AS_NAMESPACE
class CScriptArray;
enum CScriptJsonType {
OBJECT_VALUE,
ARRAY_VALUE,
BOOLEAN_VALUE,
STRING_VALUE,
NUMBER_VALUE,
REAL_VALUE,
NULL_VALUE
};
class CScriptJson {
public:
// Factory functions
static CScriptJson *Create(asIScriptEngine *engine);
static CScriptJson *Create(asIScriptEngine *engine, json js);
// Reference counting
void AddRef() const;
void Release() const;
// Reassign the json
CScriptJson &operator=(bool other);
CScriptJson &operator=(asINT64 other);
CScriptJson &operator=(double other);
CScriptJson &operator=(const std::string &other);
CScriptJson &operator=(const CScriptArray &other);
CScriptJson &operator=(const CScriptJson &other);
// Sets a key/value pair
void Set(const jsonKey_t &key, const bool &value);
void Set(const jsonKey_t &key, const asINT64 &value);
void Set(const jsonKey_t &key, const double &value);
void Set(const jsonKey_t &key, const std::string &value);
void Set(const jsonKey_t &key, const CScriptArray &value);
// Gets the stored value. Returns false if the value isn't compatible
bool Get(const jsonKey_t &key, bool &value) const;
bool Get(const jsonKey_t &key, asINT64 &value) const;
bool Get(const jsonKey_t &key, double &value) const;
bool Get(const jsonKey_t &key, std::string &value) const;
bool Get(const jsonKey_t &key, CScriptArray &value) const;
bool GetBool();
std::string GetString();
int GetNumber();
double GetReal();
CScriptArray *GetArray();
// Index accessors. If the json is not const it inserts the value if it
// doesn't already exist If the json is const then a script exception is set
// if it doesn't exist and a null pointer is returned
CScriptJson *operator[](const jsonKey_t &key);
const CScriptJson *operator[](const jsonKey_t &key) const;
// Returns true if the key is set
bool Exists(const jsonKey_t &key) const;
// Returns true if there are no key/value pairs in the json
bool IsEmpty() const;
// Returns the number of key/value pairs in the json
asUINT GetSize() const;
// Deletes all keys
void Clear();
// Get Value type
CScriptJsonType Type();
int GetRefCount();
json *js_info = NULL;
private:
// Since the dictionary uses the asAllocMem and asFreeMem functions to
// allocate memory the constructors are made protected so that the
// application cannot allocate it manually in a different way
CScriptJson(asIScriptEngine *engine);
// We don't want anyone to call the destructor directly, it should be called
// through the Release method
~CScriptJson();
// Our properties
asIScriptEngine *engine;
mutable int refCount;
};
// This function will determine the configuration of the engine
// and use one of the two functions below to register the dictionary object
void RegisterScriptJson(asIScriptEngine *engine);
void RegisterQJson(asIScriptEngine *engine);
END_AS_NAMESPACE
#endif
#endif // SCRIPTJSON_H