Compare commits

..

2 Commits

Author SHA1 Message Date
朱子楚\zhuzi
8d1ee6fc36 update clang-format 2024-06-28 17:09:23 +08:00
朱子楚\zhuzi
1dc726a61a update 2024-06-28 16:48:44 +08:00
54 changed files with 815 additions and 661 deletions

130
.clang-format Normal file
View File

@ -0,0 +1,130 @@
# References:
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# https://code.qt.io/cgit/qt/qt5.git/tree/_clang-format
BasedOnStyle: LLVM
Standard: c++17
# 指针和引用的对齐方式。
# 可能的值有:
# PAS_Left (在配置中: Left) 指针左对齐。
# PAS_Right (在配置中: Right) 指针右对齐。
# PAS_Middle (在配置中: Middle) 指针中间对齐。
PointerAlignment: Right
# public/protected/private 等访问修饰符偏移量
AccessModifierOffset: -4
# 缩进长度
IndentWidth: 4
# 连续空行的最大数
MaxEmptyLinesToKeep: 999
# 在OC中的@property后面添加一个空格。例如使用“@property (readonly)”而不是“@property(readonly)”
ObjCSpaceAfterProperty: true
# OC块中所拍的字符数
ObjCBlockIndentWidth: 4
# 取决于值, 语句“int f() { return 0; }”可以被放到一个单行。
# 可能的值有:
# SFS_None (在配置中: None) 从不合并方法或函数到单独的一行。
# SFS_Empty (在配置中: Empty) 仅合并空的函数。
# SFS_Inline (在配置中: Inline) 仅合并类中定义的方法或函数. 意味着 “empty”.
# SFS_All (在配置中: All) 合并所有的方法适应单行.
AllowShortFunctionsOnASingleLine: None
# 如果为真true, 语句“if (a) return;” 能被放到单行。
AllowShortIfStatementsOnASingleLine: false
# 如果为真true, 对齐注释。
AlignTrailingComments: true
# 如果为真,对齐连续的宏定义
AlignConsecutiveMacros: true
# 如果为真true,将会在“[”之后和“]”之前插入空格。
SpacesInSquareBrackets: false
# 如果为真true, 将会在“(”之后和“)”之前插入空格。
SpacesInParentheses : false
# 如果为真true, 校准连续的声明。
# 这将会校准连续多行的声明的名字。这将会导致像下面这样的格式:
# int aaaa = 12;
# float b = 23;
# std::string ccc = 23;
AlignConsecutiveDeclarations: false
# 如果为真true连续调整多行
# 这将会调整连续行中的分配操作符。这将会导致像下面这样的格式:
# int aaaa = 12;
# int b = 23;
# int ccc = 23;
AlignConsecutiveAssignments: false
# 如果为假false移除分配操作符=)前空格。
SpaceBeforeAssignmentOperators: true
# 如果为真true, 将会在字面量容器中插入空格(例如 OC和Javascript的数组和字典字面量)。
SpacesInContainerLiterals: false
# 缩进case标签
IndentCaseLabels: true
# 如果表达式中包含函数调用,并且函数调用因为表达式太长被放到了下一行,是否缩进
IndentWrappedFunctionNames: true
# 如果为真true, 保持块的起始空行。
# true: false:
# if (foo) { vs. if (foo) {
# bar();
# bar(); }
# }
KeepEmptyLinesAtTheStartOfBlocks: true
# 允许所有参数都被放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 使用C风格强制类型转换后是否在中间添加一个空格
SpaceAfterCStyleCast: true
# 在模板定义后换行
AlwaysBreakTemplateDeclarations: Yes
# Tab长度
TabWidth: 4
# 是否使用Tab
UseTab: Never
# 在括号后对齐参数
# someLongFunction(argument1,
# argument2);
AlignAfterOpenBracket: Align
# 名字空间内部缩进
NamespaceIndentation: All
# 一行最长列数
ColumnLimit: 100
# 按层次缩进宏定义
IndentPPDirectives: AfterHash
# 预处理语句缩进为 2
PPIndentWidth: 2
# 数组元素对齐
AlignArrayOfStructures: Left
# 不对头文件排序
SortIncludes: Never
FixNamespaceComments: false
StatementMacros: ['__qas_attr__', '__qas_exclude__', '__qas_include__']
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]

View File

@ -4,11 +4,11 @@
#include <QGuiApplication> #include <QGuiApplication>
#include "Version.h" #include "Version.h"
AppInfo::AppInfo(QObject *parent) AppInfo::AppInfo(QObject *parent) : QObject{parent} {
: QObject{parent} {
version(APPLICATION_VERSION); version(APPLICATION_VERSION);
} }
[[maybe_unused]] void AppInfo::testCrash() { [[maybe_unused]] void AppInfo::testCrash() {
auto *crash = reinterpret_cast<volatile int *>(0); auto *crash = reinterpret_cast<volatile int *>(0);
*crash = 0; *crash = 0;

View File

@ -6,13 +6,12 @@
#include "singleton.h" #include "singleton.h"
class AppInfo : public QObject { class AppInfo : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString, version) Q_PROPERTY_AUTO(QString, version)
private: private:
explicit AppInfo(QObject *parent = nullptr); explicit AppInfo(QObject *parent = nullptr);
public: public:
SINGLETON(AppInfo) SINGLETON(AppInfo)
Q_INVOKABLE [[maybe_unused]] void testCrash();
[[maybe_unused]] Q_INVOKABLE void testCrash();
}; };

View File

@ -11,21 +11,28 @@
#pragma comment(lib, "Dbghelp.lib") #pragma comment(lib, "Dbghelp.lib")
static void static void miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam) { CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
typedef HRESULT (WINAPI *MiniDumpWriteDumpPtr)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam) {
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); typedef HRESULT(WINAPI * MiniDumpWriteDumpPtr)(
HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
HMODULE module = LoadLibraryW(L"Dbghelp.dll"); HMODULE module = LoadLibraryW(L"Dbghelp.dll");
if (module) { if (module) {
MiniDumpWriteDumpPtr mini_dump_write_dump; MiniDumpWriteDumpPtr mini_dump_write_dump;
mini_dump_write_dump = reinterpret_cast<MiniDumpWriteDumpPtr>(GetProcAddress(module, "MiniDumpWriteDump")); mini_dump_write_dump =
reinterpret_cast<MiniDumpWriteDumpPtr>(GetProcAddress(module, "MiniDumpWriteDump"));
if (mini_dump_write_dump) { if (mini_dump_write_dump) {
mini_dump_write_dump(hProcess, ProcessId, hFile, static_cast<MINIDUMP_TYPE>(80), ExceptionParam, nullptr, CallbackParam); mini_dump_write_dump(hProcess, ProcessId, hFile, static_cast<MINIDUMP_TYPE>(80),
ExceptionParam, nullptr, CallbackParam);
} }
} }
} }
BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PMINIDUMP_CALLBACK_OUTPUT output) { BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input,
PMINIDUMP_CALLBACK_OUTPUT output) {
if (input == nullptr || output == nullptr) if (input == nullptr || output == nullptr)
return FALSE; return FALSE;
@ -42,8 +49,7 @@ BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PM
output->ModuleWriteFlags &= ~ModuleWriteModule; output->ModuleWriteFlags &= ~ModuleWriteModule;
} }
ret = TRUE; ret = TRUE;
} } break;
break;
default: default:
break; break;
} }
@ -51,7 +57,9 @@ BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PM
} }
void WriteDump(EXCEPTION_POINTERS *exp, const std::wstring &path) { void WriteDump(EXCEPTION_POINTERS *exp, const std::wstring &path) {
HANDLE h = ::CreateFileW(path.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); HANDLE h = ::CreateFileW(path.c_str(), GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, nullptr);
MINIDUMP_EXCEPTION_INFORMATION info; MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = ::GetCurrentThreadId(); info.ThreadId = ::GetCurrentThreadId();
info.ExceptionPointers = exp; info.ExceptionPointers = exp;
@ -64,8 +72,10 @@ void WriteDump(EXCEPTION_POINTERS *exp, const std::wstring &path) {
} }
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *exp) { LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *exp) {
const QString dumpFileName = QString("%1_%2.dmp").arg("crash", QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")); const QString dumpFileName =
const QString dumpDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/dmp"; QString("%1_%2.dmp").arg("crash", QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"));
const QString dumpDirPath =
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/dmp";
const QDir dumpDir(dumpDirPath); const QDir dumpDir(dumpDirPath);
if (!dumpDir.exists()) { if (!dumpDir.exists()) {
dumpDir.mkpath(dumpDirPath); dumpDir.mkpath(dumpDirPath);

View File

@ -15,9 +15,7 @@ CircularReveal::CircularReveal(QQuickItem *parent) : QQuickPaintedItem(parent) {
setVisible(false); setVisible(false);
Q_EMIT animationFinished(); Q_EMIT animationFinished();
}); });
connect(this, &CircularReveal::radiusChanged, this, [=]() { connect(this, &CircularReveal::radiusChanged, this, [=]() { update(); });
update();
});
} }
void CircularReveal::paint(QPainter *painter) { void CircularReveal::paint(QPainter *painter) {
@ -36,7 +34,8 @@ void CircularReveal::paint(QPainter *painter) {
_anim->setEndValue(radius); _anim->setEndValue(radius);
_center = center; _center = center;
_grabResult = _target->grabToImage(QSize(w, h)); _grabResult = _target->grabToImage(QSize(w, h));
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult); connect(_grabResult.data(), &QQuickItemGrabResult::ready, this,
&CircularReveal::handleGrabResult);
} }
void CircularReveal::handleGrabResult() { void CircularReveal::handleGrabResult() {

View File

@ -7,20 +7,15 @@
#include "src/stdafx.h" #include "src/stdafx.h"
class CircularReveal : public QQuickPaintedItem { class CircularReveal : public QQuickPaintedItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO_P(QQuickItem*, target) Q_PROPERTY_AUTO_P(QQuickItem *, target)
Q_PROPERTY_AUTO(int, radius) Q_PROPERTY_AUTO(int, radius)
public: public:
explicit CircularReveal(QQuickItem *parent = nullptr); explicit CircularReveal(QQuickItem *parent = nullptr);
void paint(QPainter *painter) override; void paint(QPainter *painter) override;
Q_INVOKABLE [[maybe_unused]] void start(int w, int h, const QPoint &center, int radius);
[[maybe_unused]] Q_INVOKABLE void start(int w, int h, const QPoint &center, int radius);
Q_SIGNAL void imageChanged(); Q_SIGNAL void imageChanged();
Q_SIGNAL void animationFinished(); Q_SIGNAL void animationFinished();
Q_SLOT void handleGrabResult(); Q_SLOT void handleGrabResult();
private: private:

View File

@ -6,11 +6,10 @@
#include "src/stdafx.h" #include "src/stdafx.h"
class FileWatcher : public QObject { class FileWatcher : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString, path); Q_PROPERTY_AUTO(QString, path)
public: public:
explicit FileWatcher(QObject *parent = nullptr); explicit FileWatcher(QObject *parent = nullptr);
Q_SIGNAL void fileChanged(); Q_SIGNAL void fileChanged();
private: private:

View File

@ -12,7 +12,9 @@ FpsItem::FpsItem() {
}); });
connect(this, &QQuickItem::windowChanged, this, [this] { connect(this, &QQuickItem::windowChanged, this, [this] {
if (window()) { if (window()) {
connect(window(), &QQuickWindow::afterRendering, this, [this] { _frameCount++; }, Qt::DirectConnection); connect(
window(), &QQuickWindow::afterRendering, this, [this] { _frameCount++; },
Qt::DirectConnection);
} }
}); });
timer->start(1000); timer->start(1000);

View File

@ -4,12 +4,11 @@
#include "src/stdafx.h" #include "src/stdafx.h"
class FpsItem : public QQuickItem { class FpsItem : public QQuickItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int, fps) Q_PROPERTY_AUTO(int, fps)
public: public:
FpsItem(); FpsItem();
private: private:
int _frameCount = 0; int _frameCount = 0;
}; };

View File

@ -7,11 +7,8 @@
class FBORenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions { class FBORenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
public: public:
explicit FBORenderer(const OpenGLItem *item); explicit FBORenderer(const OpenGLItem *item);
void render() override; void render() override;
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override; QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
QOpenGLShaderProgram program; QOpenGLShaderProgram program;
const OpenGLItem *item = nullptr; const OpenGLItem *item = nullptr;
}; };
@ -19,22 +16,22 @@ public:
FBORenderer::FBORenderer(const OpenGLItem *item) { FBORenderer::FBORenderer(const OpenGLItem *item) {
this->item = item; this->item = item;
initializeOpenGLFunctions(); initializeOpenGLFunctions();
program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, "attribute highp vec4 vertices;"
"attribute highp vec4 vertices;" "varying highp vec2 coords;"
"varying highp vec2 coords;" "void main() {"
"void main() {" " gl_Position = vertices;"
" gl_Position = vertices;" " coords = vertices.xy;"
" coords = vertices.xy;" "}");
"}"); program.addCacheableShaderFromSourceCode(
program.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, QOpenGLShader::Fragment,
"uniform lowp float t;" "uniform lowp float t;"
"varying highp vec2 coords;" "varying highp vec2 coords;"
"void main() {" "void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));" " lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);" " i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;" " i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);" " gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}"); "}");
program.bindAttributeLocation("vertices", 0); program.bindAttributeLocation("vertices", 0);
program.link(); program.link();
@ -54,16 +51,11 @@ void FBORenderer::render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program.bind(); program.bind();
program.enableAttributeArray(0); program.enableAttributeArray(0);
float values[] = { float values[] = {-1, -1, 1, -1, -1, 1, 1, 1};
-1, -1,
1, -1,
-1, 1,
1, 1
};
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
program.setAttributeArray(0, GL_FLOAT, values, 2); program.setAttributeArray(0, GL_FLOAT, values, 2);
program.setUniformValue("t", (float) item->t()); program.setUniformValue("t", (float) item->t());
glViewport(0, 0, qRound(item->width()*pixelRatio), qRound(item->height()*pixelRatio)); glViewport(0, 0, qRound(item->width() * pixelRatio), qRound(item->height() * pixelRatio));
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendFunc(GL_SRC_ALPHA, GL_ONE);

View File

@ -7,21 +7,17 @@
class FBORenderer; class FBORenderer;
class OpenGLItem : public QQuickFramebufferObject, protected QOpenGLFunctions { class OpenGLItem : public QQuickFramebufferObject, protected QOpenGLFunctions {
Q_OBJECT Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged) Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
public: public:
explicit OpenGLItem(QQuickItem *parent = nullptr); explicit OpenGLItem(QQuickItem *parent = nullptr);
[[nodiscard]] QQuickFramebufferObject::Renderer *createRenderer() const override; [[nodiscard]] QQuickFramebufferObject::Renderer *createRenderer() const override;
void timerEvent(QTimerEvent *) override; void timerEvent(QTimerEvent *) override;
[[nodiscard]] qreal t() const {
[[nodiscard]] qreal t() const { return m_t; } return m_t;
}
void setT(qreal t); void setT(qreal t);
signals: signals:
void tChanged(); void tChanged();
private: private:

View File

@ -4,11 +4,11 @@
#include <QGuiApplication> #include <QGuiApplication>
[[maybe_unused]] InitializrHelper::InitializrHelper(QObject *parent) : QObject(parent) { [[maybe_unused]] InitializrHelper::InitializrHelper(QObject *parent) : QObject(parent) {
} }
InitializrHelper::~InitializrHelper() = default; InitializrHelper::~InitializrHelper() = default;
bool InitializrHelper::copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists) { bool InitializrHelper::copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists) {
const QDir &_formDir = fromDir; const QDir &_formDir = fromDir;
QDir _toDir = toDir; QDir _toDir = toDir;
@ -17,25 +17,25 @@ bool InitializrHelper::copyDir(const QDir &fromDir, const QDir &toDir, bool cove
return false; return false;
} }
QFileInfoList fileInfoList = _formDir.entryInfoList(); QFileInfoList fileInfoList = _formDir.entryInfoList();
foreach(QFileInfo fileInfo, fileInfoList) { foreach (QFileInfo fileInfo, fileInfoList) {
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
continue; continue;
if (fileInfo.isDir()) { if (fileInfo.isDir()) {
if (!copyDir(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()), true)) if (!copyDir(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()), true))
return false; return false;
} else { } else {
if (coverIfFileExists && _toDir.exists(fileInfo.fileName())) { if (coverIfFileExists && _toDir.exists(fileInfo.fileName())) {
_toDir.remove(fileInfo.fileName()); _toDir.remove(fileInfo.fileName());
} }
if (!QFile::copy(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()))) { if (!QFile::copy(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()))) {
return false; return false;
}
} }
} }
}
return true; return true;
} }
template<typename...Args> template <typename... Args>
void InitializrHelper::templateToFile(const QString &source, const QString &dest, Args &&...args) { void InitializrHelper::templateToFile(const QString &source, const QString &dest, Args &&...args) {
QFile file(source); QFile file(source);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -61,7 +61,8 @@ void InitializrHelper::templateToFile(const QString &source, const QString &dest
void InitializrHelper::copyFile(const QString &source, const QString &dest) { void InitializrHelper::copyFile(const QString &source, const QString &dest) {
QFile::copy(source, dest); QFile::copy(source, dest);
QFile::setPermissions(dest, QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther); QFile::setPermissions(dest, QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup |
QFile::WriteOther);
} }
[[maybe_unused]] void InitializrHelper::generate(const QString &name, const QString &path) { [[maybe_unused]] void InitializrHelper::generate(const QString &name, const QString &path) {
@ -87,15 +88,21 @@ void InitializrHelper::copyFile(const QString &source, const QString &dest) {
projectDir.mkpath(projectPath); projectDir.mkpath(projectPath);
QDir fluentDir(projectDir.filePath("FluentUI")); QDir fluentDir(projectDir.filePath("FluentUI"));
copyDir(QDir(QGuiApplication::applicationDirPath() + "/source"), fluentDir); copyDir(QDir(QGuiApplication::applicationDirPath() + "/source"), fluentDir);
templateToFile(":/example/res/template/CMakeLists.txt.in", projectDir.filePath("CMakeLists.txt"), name); templateToFile(":/example/res/template/CMakeLists.txt.in",
templateToFile(":/example/res/template/src/CMakeLists.txt.in", projectDir.filePath("src/CMakeLists.txt"), name); projectDir.filePath("CMakeLists.txt"), name);
templateToFile(":/example/res/template/src/main.cpp.in", projectDir.filePath("src/main.cpp"), name); templateToFile(":/example/res/template/src/CMakeLists.txt.in",
templateToFile(":/example/res/template/src/main.qml.in", projectDir.filePath("src/main.qml"), name); projectDir.filePath("src/CMakeLists.txt"), name);
templateToFile(":/example/res/template/src/en_US.ts.in", projectDir.filePath("src/" + name + "_en_US.ts"), name); templateToFile(":/example/res/template/src/main.cpp.in", projectDir.filePath("src/main.cpp"),
templateToFile(":/example/res/template/src/zh_CN.ts.in", projectDir.filePath("src/" + name + "_zh_CN.ts"), name); name);
templateToFile(":/example/res/template/src/main.qml.in", projectDir.filePath("src/main.qml"),
name);
templateToFile(":/example/res/template/src/en_US.ts.in",
projectDir.filePath("src/" + name + "_en_US.ts"), name);
templateToFile(":/example/res/template/src/zh_CN.ts.in",
projectDir.filePath("src/" + name + "_zh_CN.ts"), name);
copyFile(":/example/res/template/src/App.qml.in", projectDir.filePath("src/App.qml")); copyFile(":/example/res/template/src/App.qml.in", projectDir.filePath("src/App.qml"));
copyFile(":/example/res/template/src/qml.qrc.in", projectDir.filePath("src/qml.qrc")); copyFile(":/example/res/template/src/qml.qrc.in", projectDir.filePath("src/qml.qrc"));
copyFile(":/example/res/template/src/logo.ico.in", projectDir.filePath("src/logo.ico")); copyFile(":/example/res/template/src/logo.ico.in", projectDir.filePath("src/logo.ico"));
copyFile(":/example/res/template/src/README.md.in", projectDir.filePath("src/README.md")); copyFile(":/example/res/template/src/README.md.in", projectDir.filePath("src/README.md"));
return this->success(projectPath+"/CMakeLists.txt"); return this->success(projectPath + "/CMakeLists.txt");
} }

View File

@ -6,25 +6,18 @@
#include "src/singleton.h" #include "src/singleton.h"
class InitializrHelper : public QObject { class InitializrHelper : public QObject {
Q_OBJECT Q_OBJECT
private: private:
[[maybe_unused]] explicit InitializrHelper(QObject *parent = nullptr); [[maybe_unused]] explicit InitializrHelper(QObject *parent = nullptr);
bool copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists = true); bool copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists = true);
static void copyFile(const QString &source, const QString &dest); static void copyFile(const QString &source, const QString &dest);
template <typename... Args>
template<typename...Args>
void templateToFile(const QString &source, const QString &dest, Args &&...args); void templateToFile(const QString &source, const QString &dest, Args &&...args);
public: public:
SINGLETON(InitializrHelper) SINGLETON(InitializrHelper)
~InitializrHelper() override; ~InitializrHelper() override;
Q_INVOKABLE [[maybe_unused]] void generate(const QString &name, const QString &path);
[[maybe_unused]] Q_INVOKABLE void generate(const QString &name, const QString &path);
Q_SIGNAL void error(const QString &message); Q_SIGNAL void error(const QString &message);
Q_SIGNAL void success(const QString &path); Q_SIGNAL void success(const QString &path);
}; };

View File

@ -13,11 +13,9 @@
#include "Version.h" #include "Version.h"
#ifdef WIN32 #ifdef WIN32
# include <process.h>
#include <process.h>
#else #else
#include <unistd.h> # include <unistd.h>
#endif #endif
#ifndef QT_ENDL #ifndef QT_ENDL
@ -38,19 +36,20 @@ static std::unique_ptr<QTextStream> g_logStream = nullptr;
static int g_logLevel = 4; static int g_logLevel = 4;
std::map<QtMsgType, int> logLevelMap = { std::map<QtMsgType, int> logLevelMap = {
{QtFatalMsg, 0}, {QtFatalMsg, 0},
{QtCriticalMsg, 1}, {QtCriticalMsg, 1},
{QtWarningMsg, 2}, {QtWarningMsg, 2},
{QtInfoMsg, 3}, {QtInfoMsg, 3},
{QtDebugMsg, 4} {QtDebugMsg, 4}
}; };
QString Log::prettyProductInfoWrapper() { QString Log::prettyProductInfoWrapper() {
auto productName = QSysInfo::prettyProductName(); auto productName = QSysInfo::prettyProductName();
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
#if defined(Q_OS_MACOS) # if defined(Q_OS_MACOS)
auto macosVersionFile = QString::fromUtf8("/System/Library/CoreServices/.SystemVersionPlatform.plist"); auto macosVersionFile =
auto fi = QFileInfo (macosVersionFile); QString::fromUtf8("/System/Library/CoreServices/.SystemVersionPlatform.plist");
auto fi = QFileInfo(macosVersionFile);
if (fi.exists() && fi.isReadable()) { if (fi.exists() && fi.isReadable()) {
auto plistFile = QFile(macosVersionFile); auto plistFile = QFile(macosVersionFile);
plistFile.open(QIODevice::ReadOnly); plistFile.open(QIODevice::ReadOnly);
@ -69,10 +68,12 @@ QString Log::prettyProductInfoWrapper() {
} }
} }
} }
#endif # endif
#endif #endif
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings regKey{QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"), QSettings::NativeFormat}; QSettings regKey{
QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"),
QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) { if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt(); auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
if (buildNumber > 0) { if (buildNumber > 0) {
@ -91,7 +92,8 @@ QString Log::prettyProductInfoWrapper() {
return productName; return productName;
} }
static inline void messageHandler(const QtMsgType type, const QMessageLogContext &context, const QString &message) { static inline void messageHandler(const QtMsgType type, const QMessageLogContext &context,
const QString &message) {
if (message == "Could not get the INetworkConnection instance for the adapter GUID.") { if (message == "Could not get the INetworkConnection instance for the adapter GUID.") {
return; return;
} }
@ -132,14 +134,15 @@ static inline void messageHandler(const QtMsgType type, const QMessageLogContext
sprintf(fn, "%s", ptrTmp + 1); sprintf(fn, "%s", ptrTmp + 1);
strFileTmp = fn; strFileTmp = fn;
} }
fileAndLineLogStr = QString::fromStdString("[%1:%2]").arg(QString::fromStdString(strFileTmp), QString::number(context.line)); fileAndLineLogStr = QString::fromStdString("[%1:%2]").arg(
QString::fromStdString(strFileTmp), QString::number(context.line));
} }
const QString finalMessage = QString::fromStdString("%1[%2]%3[%4]:%5").arg( const QString finalMessage =
QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz"), QString::fromStdString("%1[%2]%3[%4]:%5")
levelName, .arg(QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz"), levelName,
fileAndLineLogStr, fileAndLineLogStr,
QString::number(reinterpret_cast<quintptr>(QThread::currentThreadId())), QString::number(reinterpret_cast<quintptr>(QThread::currentThreadId())),
message); message);
if ((type == QtInfoMsg) || (type == QtDebugMsg)) { if ((type == QtInfoMsg) || (type == QtDebugMsg)) {
std::cout << qPrintable(finalMessage) << std::endl; std::cout << qPrintable(finalMessage) << std::endl;
} else { } else {
@ -151,7 +154,8 @@ static inline void messageHandler(const QtMsgType type, const QMessageLogContext
if (!g_logFile) { if (!g_logFile) {
g_logFile = std::make_unique<QFile>(g_file_path); g_logFile = std::make_unique<QFile>(g_file_path);
if (!g_logFile->open(QFile::WriteOnly | QFile::Text | QFile::Append)) { if (!g_logFile->open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
std::cerr << "Can't open file to write: " << qPrintable(g_logFile->errorString()) << std::endl; std::cerr << "Can't open file to write: " << qPrintable(g_logFile->errorString())
<< std::endl;
g_logFile.reset(); g_logFile.reset();
g_logError = true; g_logError = true;
return; return;
@ -179,8 +183,10 @@ void Log::setup(char *argv[], const QString &app, int level) {
QString applicationPath = QString::fromStdString(argv[0]); QString applicationPath = QString::fromStdString(argv[0]);
once = true; once = true;
g_app = app; g_app = app;
const QString logFileName = QString("%1_%2.log").arg(g_app, QDateTime::currentDateTime().toString("yyyyMMdd")); const QString logFileName =
const QString logDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/log"; QString("%1_%2.log").arg(g_app, QDateTime::currentDateTime().toString("yyyyMMdd"));
const QString logDirPath =
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/log";
const QDir logDir(logDirPath); const QDir logDir(logDirPath);
if (!logDir.exists()) { if (!logDir.exists()) {
logDir.mkpath(logDirPath); logDir.mkpath(logDirPath);
@ -195,7 +201,7 @@ void Log::setup(char *argv[], const QString &app, int level) {
#ifdef WIN32 #ifdef WIN32
qInfo() << "[ProcessId]" << QString::number(_getpid()); qInfo() << "[ProcessId]" << QString::number(_getpid());
#else #else
qInfo()<<"[ProcessId]"<<QString::number(getpid()); qInfo() << "[ProcessId]" << QString::number(getpid());
#endif #endif
qInfo() << "[GitHashCode]" << COMMIT_HASH; qInfo() << "[GitHashCode]" << COMMIT_HASH;
qInfo() << "[DeviceInfo]"; qInfo() << "[DeviceInfo]";

View File

@ -4,6 +4,5 @@
namespace Log { namespace Log {
QString prettyProductInfoWrapper(); QString prettyProductInfoWrapper();
void setup(char *argv[], const QString &app, int level = 4); void setup(char *argv[], const QString &app, int level = 4);
} }

View File

@ -19,9 +19,7 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <utility> #include <utility>
NetworkCallable::NetworkCallable(QObject *parent) : QObject{parent} { NetworkCallable::NetworkCallable(QObject *parent) : QObject{parent} {
} }
QString NetworkParams::method2String() const { QString NetworkParams::method2String() const {
@ -64,12 +62,11 @@ bool NetworkParams::getOpenLog() const {
return Network::getInstance()->openLog(); return Network::getInstance()->openLog();
} }
FluDownloadParam::FluDownloadParam(QObject *parent) FluDownloadParam::FluDownloadParam(QObject *parent) : QObject{parent} {
: QObject{parent} {
} }
FluDownloadParam::FluDownloadParam(QString destPath, bool append, QObject *parent) FluDownloadParam::FluDownloadParam(QString destPath, bool append, QObject *parent)
: QObject{parent} { : QObject{parent} {
this->_destPath = std::move(destPath); this->_destPath = std::move(destPath);
this->_append = append; this->_append = append;
} }
@ -80,7 +77,7 @@ NetworkParams::NetworkParams(QObject *parent) : QObject{parent} {
} }
NetworkParams::NetworkParams(QString url, Type type, Method method, QObject *parent) NetworkParams::NetworkParams(QString url, Type type, Method method, QObject *parent)
: QObject{parent} { : QObject{parent} {
this->_method = method; this->_method = method;
this->_url = std::move(url); this->_url = std::move(url);
this->_type = type; this->_type = type;
@ -178,12 +175,14 @@ void Network::handle(NetworkParams *params, NetworkCallable *c) {
callable->start(); callable->start();
} }
QString cacheKey = params->buildCacheKey(); QString cacheKey = params->buildCacheKey();
if (params->_cacheMode == NetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)) { if (params->_cacheMode == NetworkType::CacheMode::FirstCacheThenRequest &&
cacheExists(cacheKey)) {
if (!callable.isNull()) { if (!callable.isNull()) {
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
} }
} }
if (params->_cacheMode == NetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)) { if (params->_cacheMode == NetworkType::CacheMode::IfNoneCacheRequest &&
cacheExists(cacheKey)) {
if (!callable.isNull()) { if (!callable.isNull()) {
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
callable->finish(); callable->finish();
@ -194,7 +193,8 @@ void Network::handle(NetworkParams *params, NetworkCallable *c) {
QNetworkAccessManager manager; QNetworkAccessManager manager;
manager.setTransferTimeout(params->getTimeout()); manager.setTransferTimeout(params->getTimeout());
QEventLoop loop; QEventLoop loop;
connect(&manager, &QNetworkAccessManager::finished, &manager, [&loop](QNetworkReply *reply) { loop.quit(); }); connect(&manager, &QNetworkAccessManager::finished, &manager,
[&loop](QNetworkReply *reply) { loop.quit(); });
for (int i = 0; i <= params->getRetry() - 1; ++i) { for (int i = 0; i <= params->getRetry() - 1; ++i) {
QUrl url(params->_url); QUrl url(params->_url);
addQueryParam(&url, params->_queryMap); addQueryParam(&url, params->_queryMap);
@ -216,9 +216,11 @@ void Network::handle(NetworkParams *params, NetworkCallable *c) {
QMetaObject::Connection conn_destroyed = {}; QMetaObject::Connection conn_destroyed = {};
QMetaObject::Connection conn_quit = {}; QMetaObject::Connection conn_quit = {};
if (params->_target) { if (params->_target) {
conn_destroyed = connect(params->_target, &QObject::destroyed, &manager, abortCallable); conn_destroyed =
connect(params->_target, &QObject::destroyed, &manager, abortCallable);
} }
conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, abortCallable); conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit,
&manager, abortCallable);
loop.exec(); loop.exec();
if (conn_destroyed) { if (conn_destroyed) {
disconnect(conn_destroyed); disconnect(conn_destroyed);
@ -247,7 +249,8 @@ void Network::handle(NetworkParams *params, NetworkCallable *c) {
} else { } else {
if (i == params->getRetry() - 1) { if (i == params->getRetry() - 1) {
if (!callable.isNull()) { if (!callable.isNull()) {
if (params->_cacheMode == NetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)) { if (params->_cacheMode == NetworkType::CacheMode::RequestFailedReadCache &&
cacheExists(cacheKey)) {
if (!callable.isNull()) { if (!callable.isNull()) {
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
} }
@ -332,35 +335,41 @@ void Network::handleDownload(NetworkParams *params, NetworkCallable *c) {
reply->abort(); reply->abort();
} }
}; };
connect(&manager, &QNetworkAccessManager::finished, &manager, [&loop](QNetworkReply *reply) { loop.quit(); }); connect(&manager, &QNetworkAccessManager::finished, &manager,
connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, [&loop, reply]() { reply->abort(), loop.quit(); }); [&loop](QNetworkReply *reply) { loop.quit(); });
connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager,
[&loop, reply]() { reply->abort(), loop.quit(); });
QMetaObject::Connection conn_destroyed = {}; QMetaObject::Connection conn_destroyed = {};
QMetaObject::Connection conn_quit = {}; QMetaObject::Connection conn_quit = {};
if (params->_target) { if (params->_target) {
conn_destroyed = connect(params->_target, &QObject::destroyed, &manager, abortCallable); conn_destroyed = connect(params->_target, &QObject::destroyed, &manager, abortCallable);
} }
conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, abortCallable); conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager,
connect(reply, &QNetworkReply::readyRead, reply, [reply, seek, destFile, cacheFile, callable] { abortCallable);
if (!reply || !destFile || reply->error() != QNetworkReply::NoError) { connect(reply, &QNetworkReply::readyRead, reply,
return; [reply, seek, destFile, cacheFile, callable] {
} if (!reply || !destFile || reply->error() != QNetworkReply::NoError) {
QMap<QString, QVariant> downInfo; return;
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong() + seek; }
downInfo.insert("contentLength", contentLength); QMap<QString, QVariant> downInfo;
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString(); qint64 contentLength =
downInfo.insert("eTag", eTag); reply->header(QNetworkRequest::ContentLengthHeader).toLongLong() + seek;
destFile->write(reply->readAll()); downInfo.insert("contentLength", contentLength);
destFile->flush(); QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
downInfo.insert("fileSize", destFile->size()); downInfo.insert("eTag", eTag);
if (cacheFile->isOpen()) { destFile->write(reply->readAll());
cacheFile->resize(0); destFile->flush();
cacheFile->write(QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64()); downInfo.insert("fileSize", destFile->size());
cacheFile->flush(); if (cacheFile->isOpen()) {
} cacheFile->resize(0);
if (!callable.isNull()) { cacheFile->write(
callable->downloadProgress(destFile->size(), contentLength); QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64());
} cacheFile->flush();
}); }
if (!callable.isNull()) {
callable->downloadProgress(destFile->size(), contentLength);
}
});
loop.exec(); loop.exec();
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpStatus == 200) { if (httpStatus == 200) {
@ -430,7 +439,9 @@ QString Network::map2String(const QMap<QString, QVariant> &map) {
return parameters.join(" "); return parameters.join(" ");
} }
void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest request, NetworkParams *params, QNetworkReply *&reply, bool isFirst, const QPointer<NetworkCallable> &callable) { void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest request,
NetworkParams *params, QNetworkReply *&reply, bool isFirst,
const QPointer<NetworkCallable> &callable) {
QByteArray verb = params->method2String().toUtf8(); QByteArray verb = params->method2String().toUtf8();
switch (params->_type) { switch (params->_type) {
case NetworkParams::TYPE_FORM: { case NetworkParams::TYPE_FORM: {
@ -438,13 +449,14 @@ void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest reques
if (isFormData) { if (isFormData) {
auto *multiPart = new QHttpMultiPart(); auto *multiPart = new QHttpMultiPart();
multiPart->setContentType(QHttpMultiPart::FormDataType); multiPart->setContentType(QHttpMultiPart::FormDataType);
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto &each : params->_paramMap.toStdMap()) {
QHttpPart part; QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(each.first)); part.setHeader(QNetworkRequest::ContentDispositionHeader,
QString("form-data; name=\"%1\"").arg(each.first));
part.setBody(each.second.toByteArray()); part.setBody(each.second.toByteArray());
multiPart->append(part); multiPart->append(part);
} }
for (const auto &each: params->_fileMap.toStdMap()) { for (const auto &each : params->_fileMap.toStdMap()) {
QString filePath = each.second.toString(); QString filePath = each.second.toString();
QString name = each.first; QString name = each.first;
auto *file = new QFile(filePath); auto *file = new QFile(filePath);
@ -452,21 +464,25 @@ void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest reques
file->open(QIODevice::ReadOnly); file->open(QIODevice::ReadOnly);
file->setParent(multiPart); file->setParent(multiPart);
QHttpPart part; QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString(R"(form-data; name="%1"; filename="%2")").arg(name, fileName)); part.setHeader(
QNetworkRequest::ContentDispositionHeader,
QString(R"(form-data; name="%1"; filename="%2")").arg(name, fileName));
part.setBodyDevice(file); part.setBodyDevice(file);
multiPart->append(part); multiPart->append(part);
} }
reply = manager->sendCustomRequest(request, verb, multiPart); reply = manager->sendCustomRequest(request, verb, multiPart);
multiPart->setParent(reply); multiPart->setParent(reply);
connect(reply, &QNetworkReply::uploadProgress, reply, [callable](qint64 bytesSent, qint64 bytesTotal) { connect(reply, &QNetworkReply::uploadProgress, reply,
if (!callable.isNull() && bytesSent != 0 && bytesTotal != 0) { [callable](qint64 bytesSent, qint64 bytesTotal) {
Q_EMIT callable->uploadProgress(bytesSent, bytesTotal); if (!callable.isNull() && bytesSent != 0 && bytesTotal != 0) {
} Q_EMIT callable->uploadProgress(bytesSent, bytesTotal);
}); }
});
} else { } else {
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded")); request.setHeader(QNetworkRequest::ContentTypeHeader,
QString("application/x-www-form-urlencoded"));
QString value; QString value;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto &each : params->_paramMap.toStdMap()) {
value += QString("%1=%2").arg(each.first, each.second.toString()); value += QString("%1=%2").arg(each.first, each.second.toString());
value += "&"; value += "&";
} }
@ -479,9 +495,10 @@ void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest reques
break; break;
} }
case NetworkParams::TYPE_JSON: { case NetworkParams::TYPE_JSON: {
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader,
QString("application/json;charset=utf-8"));
QJsonObject json; QJsonObject json;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto &each : params->_paramMap.toStdMap()) {
json.insert(each.first, each.second.toJsonValue()); json.insert(each.first, each.second.toJsonValue());
} }
QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact); QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact);
@ -489,9 +506,10 @@ void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest reques
break; break;
} }
case NetworkParams::TYPE_JSONARRAY: { case NetworkParams::TYPE_JSONARRAY: {
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader,
QString("application/json;charset=utf-8"));
QJsonArray jsonArray; QJsonArray jsonArray;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto &each : params->_paramMap.toStdMap()) {
QJsonObject json; QJsonObject json;
json.insert(each.first, each.second.toJsonValue()); json.insert(each.first, each.second.toJsonValue());
jsonArray.append(json); jsonArray.append(json);
@ -501,7 +519,8 @@ void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest reques
break; break;
} }
case NetworkParams::TYPE_BODY: { case NetworkParams::TYPE_BODY: {
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader,
QString("text/plain;charset=utf-8"));
QByteArray data = params->_body.toUtf8(); QByteArray data = params->_body.toUtf8();
reply = manager->sendCustomRequest(request, verb, data); reply = manager->sendCustomRequest(request, verb, data);
break; break;
@ -519,15 +538,20 @@ void Network::printRequestStartLog(const QNetworkRequest &request, NetworkParams
if (!params->getOpenLog()) { if (!params->getOpenLog()) {
return; return;
} }
qDebug() << "<------" << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString()) << "Request Start ------>"; qDebug() << "<------"
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String())) << qUtf8Printable(params->_url); << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())
<< "Request Start ------>";
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))
<< qUtf8Printable(params->_url);
auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString(); auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString();
if (!contentType.isEmpty()) { if (!contentType.isEmpty()) {
qDebug() << qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg("Content-Type", contentType)); qDebug() << qUtf8Printable(
QString::fromStdString("<Header> %1=%2").arg("Content-Type", contentType));
} }
QList<QByteArray> headers = request.rawHeaderList(); QList<QByteArray> headers = request.rawHeaderList();
for (const QByteArray &header: headers) { for (const QByteArray &header : headers) {
qDebug() << qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg(header, request.rawHeader(header))); qDebug() << qUtf8Printable(
QString::fromStdString("<Header> %1=%2").arg(header, request.rawHeader(header)));
} }
if (!params->_queryMap.isEmpty()) { if (!params->_queryMap.isEmpty()) {
qDebug() << "<Query>" << qUtf8Printable(map2String(params->_queryMap)); qDebug() << "<Query>" << qUtf8Printable(map2String(params->_queryMap));
@ -543,12 +567,16 @@ void Network::printRequestStartLog(const QNetworkRequest &request, NetworkParams
} }
} }
void Network::printRequestEndLog(const QNetworkRequest &request, NetworkParams *params, QNetworkReply *&reply, const QString &response) { void Network::printRequestEndLog(const QNetworkRequest &request, NetworkParams *params,
QNetworkReply *&reply, const QString &response) {
if (!params->getOpenLog()) { if (!params->getOpenLog()) {
return; return;
} }
qDebug() << "<------" << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString()) << "Request End ------>"; qDebug() << "<------"
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String())) << qUtf8Printable(params->_url); << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())
<< "Request End ------>";
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))
<< qUtf8Printable(params->_url);
qDebug() << "<Result>" << qUtf8Printable(response); qDebug() << "<Result>" << qUtf8Printable(response);
} }
@ -562,7 +590,10 @@ void Network::saveResponse(const QString &key, const QString &response) {
} }
void Network::addHeaders(QNetworkRequest *request, const QMap<QString, QVariant> &headers) { void Network::addHeaders(QNetworkRequest *request, const QMap<QString, QVariant> &headers) {
request->setHeader(QNetworkRequest::UserAgentHeader, QString::fromStdString("Mozilla/5.0 %1/%2").arg(QGuiApplication::applicationName(), QGuiApplication::applicationVersion())); request->setHeader(
QNetworkRequest::UserAgentHeader,
QString::fromStdString("Mozilla/5.0 %1/%2")
.arg(QGuiApplication::applicationName(), QGuiApplication::applicationVersion()));
QMapIterator<QString, QVariant> iter(headers); QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext()) { while (iter.hasNext()) {
iter.next(); iter.next();
@ -584,7 +615,9 @@ Network::Network(QObject *parent) : QObject{parent} {
_timeout = 5000; _timeout = 5000;
_retry = 3; _retry = 3;
_openLog = false; _openLog = false;
_cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"); _cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
.append(QDir::separator())
.append("network");
} }
NetworkParams *Network::get(const QString &url) { NetworkParams *Network::get(const QString &url) {
@ -656,7 +689,8 @@ NetworkParams *Network::patchJsonArray(const QString &url) {
} }
NetworkParams *Network::deleteJsonArray(const QString &url) { NetworkParams *Network::deleteJsonArray(const QString &url) {
return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_DELETE, this); return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_DELETE,
this);
} }
void Network::setInterceptor(QJSValue interceptor) { void Network::setInterceptor(QJSValue interceptor) {

View File

@ -28,7 +28,7 @@ namespace NetworkType {
* @brief The NetworkCallable class * @brief The NetworkCallable class
*/ */
class NetworkCallable : public QObject { class NetworkCallable : public QObject {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(NetworkCallable) QML_NAMED_ELEMENT(NetworkCallable)
public: public:
explicit NetworkCallable(QObject *parent = nullptr); explicit NetworkCallable(QObject *parent = nullptr);
@ -52,7 +52,7 @@ public:
* @brief The FluDownloadParam class * @brief The FluDownloadParam class
*/ */
class FluDownloadParam : public QObject { class FluDownloadParam : public QObject {
Q_OBJECT Q_OBJECT
public: public:
explicit FluDownloadParam(QObject *parent = nullptr); explicit FluDownloadParam(QObject *parent = nullptr);
@ -67,24 +67,11 @@ public:
* @brief The NetworkParams class * @brief The NetworkParams class
*/ */
class NetworkParams : public QObject { class NetworkParams : public QObject {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(NetworkParams) QML_NAMED_ELEMENT(NetworkParams)
public: public:
enum Method { enum Method { METHOD_GET, METHOD_HEAD, METHOD_POST, METHOD_PUT, METHOD_PATCH, METHOD_DELETE };
METHOD_GET, enum Type { TYPE_NONE, TYPE_FORM, TYPE_JSON, TYPE_JSONARRAY, TYPE_BODY };
METHOD_HEAD,
METHOD_POST,
METHOD_PUT,
METHOD_PATCH,
METHOD_DELETE
};
enum Type {
TYPE_NONE,
TYPE_FORM,
TYPE_JSON,
TYPE_JSONARRAY,
TYPE_BODY
};
explicit NetworkParams(QObject *parent = nullptr); explicit NetworkParams(QObject *parent = nullptr);
@ -145,11 +132,11 @@ public:
* @brief The Network class * @brief The Network class
*/ */
class Network : public QObject { class Network : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int, timeout) Q_PROPERTY_AUTO(int, timeout)
Q_PROPERTY_AUTO(int, retry) Q_PROPERTY_AUTO(int, retry)
Q_PROPERTY_AUTO(QString, cacheDir) Q_PROPERTY_AUTO(QString, cacheDir)
Q_PROPERTY_AUTO(bool, openLog) Q_PROPERTY_AUTO(bool, openLog)
QML_NAMED_ELEMENT(Network) QML_NAMED_ELEMENT(Network)
QML_SINGLETON QML_SINGLETON
@ -157,9 +144,11 @@ private:
explicit Network(QObject *parent = nullptr); explicit Network(QObject *parent = nullptr);
public: public:
SINGLETON(Network) SINGLETON(Network)
static Network *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) { return getInstance(); } static Network *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
return getInstance();
}
Q_INVOKABLE NetworkParams *get(const QString &url); Q_INVOKABLE NetworkParams *get(const QString &url);
@ -204,7 +193,9 @@ SINGLETON(Network)
void handleDownload(NetworkParams *params, NetworkCallable *result); void handleDownload(NetworkParams *params, NetworkCallable *result);
private: private:
static void sendRequest(QNetworkAccessManager *manager, QNetworkRequest request, NetworkParams *params, QNetworkReply *&reply, bool isFirst, const QPointer<NetworkCallable> &callable); static void sendRequest(QNetworkAccessManager *manager, QNetworkRequest request,
NetworkParams *params, QNetworkReply *&reply, bool isFirst,
const QPointer<NetworkCallable> &callable);
static void addQueryParam(QUrl *url, const QMap<QString, QVariant> &params); static void addQueryParam(QUrl *url, const QMap<QString, QVariant> &params);
@ -222,7 +213,8 @@ private:
static void printRequestStartLog(const QNetworkRequest &request, NetworkParams *params); static void printRequestStartLog(const QNetworkRequest &request, NetworkParams *params);
static void printRequestEndLog(const QNetworkRequest &request, NetworkParams *params, QNetworkReply *&reply, const QString &response); static void printRequestEndLog(const QNetworkRequest &request, NetworkParams *params,
QNetworkReply *&reply, const QString &response);
static QString map2String(const QMap<QString, QVariant> &map); static QString map2String(const QMap<QString, QVariant> &map);

View File

@ -4,7 +4,6 @@
#include <QStandardPaths> #include <QStandardPaths>
SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent) { SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent) {
} }
SettingsHelper::~SettingsHelper() = default; SettingsHelper::~SettingsHelper() = default;
@ -13,6 +12,7 @@ void SettingsHelper::save(const QString &key, QVariant val) {
m_settings->setValue(key, val); m_settings->setValue(key, val);
} }
QVariant SettingsHelper::get(const QString &key, QVariant def) { QVariant SettingsHelper::get(const QString &key, QVariant def) {
QVariant data = m_settings->value(key); QVariant data = m_settings->value(key);
if (!data.isNull() && data.isValid()) { if (!data.isNull() && data.isValid()) {
@ -25,6 +25,7 @@ void SettingsHelper::init(char *argv[]) {
QString applicationPath = QString::fromStdString(argv[0]); QString applicationPath = QString::fromStdString(argv[0]);
const QFileInfo fileInfo(applicationPath); const QFileInfo fileInfo(applicationPath);
const QString iniFileName = fileInfo.completeBaseName() + ".ini"; const QString iniFileName = fileInfo.completeBaseName() + ".ini";
const QString iniFilePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + iniFileName; const QString iniFilePath =
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + iniFileName;
m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat)); m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat));
} }

View File

@ -10,32 +10,35 @@
#include "src/singleton.h" #include "src/singleton.h"
class SettingsHelper : public QObject { class SettingsHelper : public QObject {
Q_OBJECT Q_OBJECT
private: private:
explicit SettingsHelper(QObject *parent = nullptr); explicit SettingsHelper(QObject *parent = nullptr);
public: public:
SINGLETON(SettingsHelper) SINGLETON(SettingsHelper)
~SettingsHelper() override; ~SettingsHelper() override;
void init(char *argv[]); void init(char *argv[]);
Q_INVOKABLE void saveDarkMode(int darkModel) {
Q_INVOKABLE void saveDarkMode(int darkModel) { save("darkMode", darkModel); } save("darkMode", darkModel);
}
Q_INVOKABLE int getDarkMode() { return get("darkMode", QVariant(0)).toInt(); } Q_INVOKABLE int getDarkMode() {
return get("darkMode", QVariant(0)).toInt();
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar) { save("useSystemAppBar", useSystemAppBar); } }
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar) {
Q_INVOKABLE bool getUseSystemAppBar() { return get("useSystemAppBar", QVariant(false)).toBool(); } save("useSystemAppBar", useSystemAppBar);
}
Q_INVOKABLE void saveLanguage(const QString &language) { save("language", language); } Q_INVOKABLE bool getUseSystemAppBar() {
return get("useSystemAppBar", QVariant(false)).toBool();
Q_INVOKABLE QString getLanguage() { return get("language", QVariant("en_US")).toString(); } }
Q_INVOKABLE void saveLanguage(const QString &language) {
save("language", language);
}
Q_INVOKABLE QString getLanguage() {
return get("language", QVariant("en_US")).toString();
}
private: private:
void save(const QString &key, QVariant val); void save(const QString &key, QVariant val);
QVariant get(const QString &key, QVariant def = {}); QVariant get(const QString &key, QVariant def = {});
private: private:

View File

@ -18,7 +18,8 @@ void TranslateHelper::init(QQmlEngine *engine) {
_translator = new QTranslator(this); _translator = new QTranslator(this);
QGuiApplication::installTranslator(_translator); QGuiApplication::installTranslator(_translator);
QString translatorPath = QGuiApplication::applicationDirPath() + "/i18n"; QString translatorPath = QGuiApplication::applicationDirPath() + "/i18n";
if (_translator->load(QString::fromStdString("%1/example_%2.qm").arg(translatorPath, _current))) { if (_translator->load(
QString::fromStdString("%1/example_%2.qm").arg(translatorPath, _current))) {
_engine->retranslate(); _engine->retranslate();
} }
} }

View File

@ -7,17 +7,15 @@
#include "src/stdafx.h" #include "src/stdafx.h"
class TranslateHelper : public QObject { class TranslateHelper : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString, current) Q_PROPERTY_AUTO(QString, current)
Q_PROPERTY_READONLY_AUTO(QStringList, languages) Q_PROPERTY_READONLY_AUTO(QStringList, languages)
private: private:
[[maybe_unused]] explicit TranslateHelper(QObject *parent = nullptr); [[maybe_unused]] explicit TranslateHelper(QObject *parent = nullptr);
public: public:
SINGLETON(TranslateHelper) SINGLETON(TranslateHelper)
~TranslateHelper() override; ~TranslateHelper() override;
void init(QQmlEngine *engine); void init(QQmlEngine *engine);
private: private:

View File

@ -20,36 +20,36 @@
#include "src/helper/TranslateHelper.h" #include "src/helper/TranslateHelper.h"
#include "src/helper/Network.h" #include "src/helper/Network.h"
#ifdef FLUENTUI_BUILD_STATIC_LIB #ifdef FLUENTUI_BUILD_STATIC_LIB
#if (QT_VERSION > QT_VERSION_CHECK(6, 2, 0)) # if (QT_VERSION > QT_VERSION_CHECK(6, 2, 0))
Q_IMPORT_QML_PLUGIN(FluentUIPlugin) Q_IMPORT_QML_PLUGIN(FluentUIPlugin)
#endif # endif
#include <FluentUI.h> # include <FluentUI.h>
#endif #endif
#ifdef WIN32 #ifdef WIN32
#include "app_dmp.h" # include "app_dmp.h"
#endif #endif
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{
const char *uri = "example"; const char *uri = "example";
int major = 1; int major = 1;
int minor = 0; int minor = 0;
#ifdef WIN32 #ifdef WIN32
::SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); ::SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
qputenv("QT_QPA_PLATFORM","windows:darkmode=2"); qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
#endif #endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
qputenv("QT_QUICK_CONTROLS_STYLE","Basic"); qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
#else #else
qputenv("QT_QUICK_CONTROLS_STYLE","Default"); qputenv("QT_QUICK_CONTROLS_STYLE", "Default");
#endif #endif
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
//fix bug UOSv20 does not print logs // fix bug UOSv20 does not print logs
qputenv("QT_LOGGING_RULES",""); qputenv("QT_LOGGING_RULES", "");
//fix bug UOSv20 v-sync does not work // fix bug UOSv20 v-sync does not work
qputenv("QSG_RENDER_LOOP","basic"); qputenv("QSG_RENDER_LOOP", "basic");
#endif #endif
QApplication::setOrganizationName("ZhuZiChu"); QApplication::setOrganizationName("ZhuZiChu");
QApplication::setOrganizationDomain("https://zhuzichu520.github.io"); QApplication::setOrganizationDomain("https://zhuzichu520.github.io");
@ -58,43 +58,47 @@ int main(int argc, char *argv[])
QApplication::setApplicationVersion(APPLICATION_VERSION); QApplication::setApplicationVersion(APPLICATION_VERSION);
QApplication::setQuitOnLastWindowClosed(false); QApplication::setQuitOnLastWindowClosed(false);
SettingsHelper::getInstance()->init(argv); SettingsHelper::getInstance()->init(argv);
Log::setup(argv,uri); Log::setup(argv, uri);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
#endif #endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication::setHighDpiScaleFactorRoundingPolicy(
#endif Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
# endif
#endif #endif
QApplication app(argc, argv); QApplication app(argc, argv);
//@uri example //@uri example
qmlRegisterType<CircularReveal>(uri, major, minor, "CircularReveal"); qmlRegisterType<CircularReveal>(uri, major, minor, "CircularReveal");
qmlRegisterType<FileWatcher>(uri, major, minor, "FileWatcher"); qmlRegisterType<FileWatcher>(uri, major, minor, "FileWatcher");
qmlRegisterType<FpsItem>(uri, major, minor, "FpsItem"); qmlRegisterType<FpsItem>(uri, major, minor, "FpsItem");
qmlRegisterType<NetworkCallable>(uri,major,minor,"NetworkCallable"); qmlRegisterType<NetworkCallable>(uri, major, minor, "NetworkCallable");
qmlRegisterType<NetworkParams>(uri,major,minor,"NetworkParams"); qmlRegisterType<NetworkParams>(uri, major, minor, "NetworkParams");
qmlRegisterType<OpenGLItem>(uri,major,minor,"OpenGLItem"); qmlRegisterType<OpenGLItem>(uri, major, minor, "OpenGLItem");
qmlRegisterUncreatableMetaObject(NetworkType::staticMetaObject, uri, major, minor, "NetworkType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(NetworkType::staticMetaObject, uri, major, minor,
"NetworkType", "Access to enums & flags only");
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
TranslateHelper::getInstance()->init(&engine); TranslateHelper::getInstance()->init(&engine);
engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance()); engine.rootContext()->setContextProperty("AppInfo", AppInfo::getInstance());
engine.rootContext()->setContextProperty("SettingsHelper",SettingsHelper::getInstance()); engine.rootContext()->setContextProperty("SettingsHelper", SettingsHelper::getInstance());
engine.rootContext()->setContextProperty("InitializrHelper",InitializrHelper::getInstance()); engine.rootContext()->setContextProperty("InitializrHelper", InitializrHelper::getInstance());
engine.rootContext()->setContextProperty("TranslateHelper",TranslateHelper::getInstance()); engine.rootContext()->setContextProperty("TranslateHelper", TranslateHelper::getInstance());
engine.rootContext()->setContextProperty("Network",Network::getInstance()); engine.rootContext()->setContextProperty("Network", Network::getInstance());
#ifdef FLUENTUI_BUILD_STATIC_LIB #ifdef FLUENTUI_BUILD_STATIC_LIB
FluentUI::getInstance()->registerTypes(&engine); FluentUI::getInstance()->registerTypes(&engine);
#endif #endif
const QUrl url(QStringLiteral("qrc:/example/qml/App.qml")); const QUrl url(QStringLiteral("qrc:/example/qml/App.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, QObject::connect(
&app, [url](QObject *obj, const QUrl &objUrl) { &engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl) if (!obj && url == objUrl)
QCoreApplication::exit(-1); QCoreApplication::exit(-1);
}, Qt::QueuedConnection); },
Qt::QueuedConnection);
engine.load(url); engine.load(url);
const int exec = QApplication::exec(); const int exec = QApplication::exec();
if (exec == 931) { if (exec == 931) {

View File

@ -3,22 +3,23 @@
/** /**
* @brief The Singleton class * @brief The Singleton class
*/ */
template<typename T> template <typename T>
class Singleton { class Singleton {
public: public:
static T *getInstance(); static T *getInstance();
}; };
template<typename T> template <typename T>
T *Singleton<T>::getInstance() { T *Singleton<T>::getInstance() {
static T *instance = new T(); static T *instance = new T();
return instance; return instance;
} }
#define SINGLETON(Class) \ #define SINGLETON(Class) \
private: \ private: \
friend class Singleton<Class>; \ friend class Singleton<Class>; \
public: \ \
static Class* getInstance() { \ public: \
return Singleton<Class>::getInstance(); \ static Class *getInstance() { \
} return Singleton<Class>::getInstance(); \
}

View File

@ -1,50 +1,47 @@
#pragma once #pragma once
#define Q_PROPERTY_AUTO_P(TYPE, M) \ #define Q_PROPERTY_AUTO_P(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(TYPE in_##M) \ void M(TYPE in_##M) { \
{ \ _##M = in_##M; \
_##M = in_##M; \ Q_EMIT M##Changed(); \
Q_EMIT M##Changed(); \ } \
} \ TYPE M() { \
TYPE M() \ return _##M; \
{ \ } \
return _##M; \ \
} \ private: \
private: \
TYPE _##M; TYPE _##M;
#define Q_PROPERTY_AUTO(TYPE, M) \ #define Q_PROPERTY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \ void M(const TYPE &in_##M) { \
{ \ _##M = in_##M; \
_##M = in_##M; \ Q_EMIT M##Changed(); \
Q_EMIT M##Changed(); \ } \
} \ TYPE M() { \
TYPE M() \ return _##M; \
{ \ } \
return _##M; \ \
} \ private: \
private: \
TYPE _##M; TYPE _##M;
#define Q_PROPERTY_READONLY_AUTO(TYPE, M) \ #define Q_PROPERTY_READONLY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \ Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \ void M(const TYPE &in_##M) { \
{ \ _##M = in_##M; \
_##M = in_##M; \ Q_EMIT M##Changed(); \
Q_EMIT M##Changed(); \ } \
} \ TYPE M() { \
TYPE M() \ return _##M; \
{ \ } \
return _##M; \ \
} \ private: \
private: \
TYPE _##M; TYPE _##M;

View File

@ -59,11 +59,7 @@ namespace FluPageType {
namespace FluWindowType { namespace FluWindowType {
Q_NAMESPACE Q_NAMESPACE
enum LaunchMode { enum LaunchMode { Standard = 0x0000, SingleTask = 0x0001, SingleInstance = 0x0002 };
Standard = 0x0000,
SingleTask = 0x0001,
SingleInstance = 0x0002
};
Q_ENUM_NS(LaunchMode) Q_ENUM_NS(LaunchMode)
@ -72,11 +68,7 @@ namespace FluWindowType {
namespace FluTreeViewType { namespace FluTreeViewType {
Q_NAMESPACE Q_NAMESPACE
enum SelectionMode { enum SelectionMode { None = 0x0000, Single = 0x0001, Multiple = 0x0002 };
None = 0x0000,
Single = 0x0001,
Multiple = 0x0002
};
Q_ENUM_NS(SelectionMode) Q_ENUM_NS(SelectionMode)
@ -85,12 +77,7 @@ namespace FluTreeViewType {
namespace FluStatusLayoutType { namespace FluStatusLayoutType {
Q_NAMESPACE Q_NAMESPACE
enum StatusMode { enum StatusMode { Loading = 0x0000, Empty = 0x0001, Error = 0x0002, Success = 0x0004 };
Loading = 0x0000,
Empty = 0x0001,
Error = 0x0002,
Success = 0x0004
};
Q_ENUM_NS(StatusMode) Q_ENUM_NS(StatusMode)
@ -99,11 +86,7 @@ namespace FluStatusLayoutType {
namespace FluContentDialogType { namespace FluContentDialogType {
Q_NAMESPACE Q_NAMESPACE
enum ButtonFlag { enum ButtonFlag { NeutralButton = 0x0001, NegativeButton = 0x0002, PositiveButton = 0x0004 };
NeutralButton = 0x0001,
NegativeButton = 0x0002,
PositiveButton = 0x0004
};
Q_ENUM_NS(ButtonFlag) Q_ENUM_NS(ButtonFlag)
@ -112,10 +95,7 @@ namespace FluContentDialogType {
namespace FluTimePickerType { namespace FluTimePickerType {
Q_NAMESPACE Q_NAMESPACE
enum HourFormat { enum HourFormat { H = 0x0000, HH = 0x0001 };
H = 0x0000,
HH = 0x0001
};
Q_ENUM_NS(HourFormat) Q_ENUM_NS(HourFormat)
@ -124,11 +104,7 @@ namespace FluTimePickerType {
namespace FluCalendarViewType { namespace FluCalendarViewType {
Q_NAMESPACE Q_NAMESPACE
enum DisplayMode { enum DisplayMode { Month = 0x0000, Year = 0x0001, Decade = 0x0002 };
Month = 0x0000,
Year = 0x0001,
Decade = 0x0002
};
Q_ENUM_NS(DisplayMode) Q_ENUM_NS(DisplayMode)
@ -137,19 +113,11 @@ namespace FluCalendarViewType {
namespace FluTabViewType { namespace FluTabViewType {
Q_NAMESPACE Q_NAMESPACE
enum TabWidthBehavior { enum TabWidthBehavior { Equal = 0x0000, SizeToContent = 0x0001, Compact = 0x0002 };
Equal = 0x0000,
SizeToContent = 0x0001,
Compact = 0x0002
};
Q_ENUM_NS(TabWidthBehavior) Q_ENUM_NS(TabWidthBehavior)
enum CloseButtonVisibility { enum CloseButtonVisibility { Never = 0x0000, Always = 0x0001, OnHover = 0x0002 };
Never = 0x0000,
Always = 0x0001,
OnHover = 0x0002
};
Q_ENUM_NS(CloseButtonVisibility) Q_ENUM_NS(CloseButtonVisibility)
@ -158,19 +126,11 @@ namespace FluTabViewType {
namespace FluNavigationViewType { namespace FluNavigationViewType {
Q_NAMESPACE Q_NAMESPACE
enum DisplayMode { enum DisplayMode { Open = 0x0000, Compact = 0x0001, Minimal = 0x0002, Auto = 0x0004 };
Open = 0x0000,
Compact = 0x0001,
Minimal = 0x0002,
Auto = 0x0004
};
Q_ENUM_NS(DisplayMode) Q_ENUM_NS(DisplayMode)
enum PageMode { enum PageMode { Stack = 0x0000, NoStack = 0x0001 };
Stack = 0x0000,
NoStack = 0x0001
};
Q_ENUM_NS(PageMode) Q_ENUM_NS(PageMode)

View File

@ -9,15 +9,15 @@
* @brief The FluAccentColor class * @brief The FluAccentColor class
*/ */
class FluAccentColor : public QObject { class FluAccentColor : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QColor, darkest) Q_PROPERTY_AUTO(QColor, darkest)
Q_PROPERTY_AUTO(QColor, darker) Q_PROPERTY_AUTO(QColor, darker)
Q_PROPERTY_AUTO(QColor, dark) Q_PROPERTY_AUTO(QColor, dark)
Q_PROPERTY_AUTO(QColor, normal) Q_PROPERTY_AUTO(QColor, normal)
Q_PROPERTY_AUTO(QColor, light) Q_PROPERTY_AUTO(QColor, light)
Q_PROPERTY_AUTO(QColor, lighter) Q_PROPERTY_AUTO(QColor, lighter)
Q_PROPERTY_AUTO(QColor, lightest) Q_PROPERTY_AUTO(QColor, lightest)
QML_NAMED_ELEMENT(FluAccentColor) QML_NAMED_ELEMENT(FluAccentColor)
public: public:
explicit FluAccentColor(QObject *parent = nullptr); explicit FluAccentColor(QObject *parent = nullptr);

View File

@ -23,7 +23,7 @@ void FluApp::init(QObject *launcher, QLocale locale) {
_translator = new QTranslator(this); _translator = new QTranslator(this);
QGuiApplication::installTranslator(_translator); QGuiApplication::installTranslator(_translator);
const QStringList uiLanguages = _locale.uiLanguages(); const QStringList uiLanguages = _locale.uiLanguages();
for (const QString &name: uiLanguages) { for (const QString &name : uiLanguages) {
const QString baseName = "fluentui_" + QLocale(name).name(); const QString baseName = "fluentui_" + QLocale(name).name();
if (_translator->load(":/qt/qml/FluentUI/i18n/" + baseName)) { if (_translator->load(":/qt/qml/FluentUI/i18n/" + baseName)) {
_engine->retranslate(); _engine->retranslate();
@ -34,7 +34,8 @@ void FluApp::init(QObject *launcher, QLocale locale) {
[[maybe_unused]] QJsonArray FluApp::iconData(const QString &keyword) { [[maybe_unused]] QJsonArray FluApp::iconData(const QString &keyword) {
QJsonArray arr; QJsonArray arr;
QMetaEnum enumType = FluentIcons::staticMetaObject.enumerator(FluentIcons::staticMetaObject.indexOfEnumerator("Type")); QMetaEnum enumType = FluentIcons::staticMetaObject.enumerator(
FluentIcons::staticMetaObject.indexOfEnumerator("Type"));
for (int i = 0; i <= enumType.keyCount() - 1; ++i) { for (int i = 0; i <= enumType.keyCount() - 1; ++i) {
QString name = enumType.key(i); QString name = enumType.key(i);
int icon = enumType.value(i); int icon = enumType.value(i);

View File

@ -16,12 +16,11 @@
* @brief The FluApp class * @brief The FluApp class
*/ */
class FluApp : public QObject { class FluApp : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(bool, useSystemAppBar)
Q_PROPERTY_AUTO(bool, useSystemAppBar) Q_PROPERTY_AUTO(QString, windowIcon)
Q_PROPERTY_AUTO(QString, windowIcon) Q_PROPERTY_AUTO(QLocale, locale)
Q_PROPERTY_AUTO(QLocale, locale) Q_PROPERTY_AUTO_P(QObject *, launcher)
Q_PROPERTY_AUTO_P(QObject*,launcher)
QML_NAMED_ELEMENT(FluApp) QML_NAMED_ELEMENT(FluApp)
QML_SINGLETON QML_SINGLETON
@ -31,9 +30,11 @@ private:
~FluApp() override; ~FluApp() override;
public: public:
SINGLETON(FluApp) SINGLETON(FluApp)
static FluApp *create(QQmlEngine *, QJSEngine *) { return getInstance(); } static FluApp *create(QQmlEngine *, QJSEngine *) {
return getInstance();
}
Q_INVOKABLE void init(QObject *launcher, QLocale locale = QLocale::system()); Q_INVOKABLE void init(QObject *launcher, QLocale locale = QLocale::system());

View File

@ -40,7 +40,8 @@ void FluCaptcha::paint(QPainter *painter) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
pen = QPen(QColor(generaNumber(255), generaNumber(255), generaNumber(255))); pen = QPen(QColor(generaNumber(255), generaNumber(255), generaNumber(255)));
painter->setPen(pen); painter->setPen(pen);
painter->drawText(15 + 35 * i, 10 + generaNumber(15), 30, 40, Qt::AlignCenter, QString(_code[i])); painter->drawText(15 + 35 * i, 10 + generaNumber(15), 30, 40, Qt::AlignCenter,
QString(_code[i]));
} }
painter->restore(); painter->restore();
} }

View File

@ -9,10 +9,10 @@
* @brief The FluCaptcha class * @brief The FluCaptcha class
*/ */
class FluCaptcha : public QQuickPaintedItem { class FluCaptcha : public QQuickPaintedItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QFont, font); Q_PROPERTY_AUTO(QFont, font)
Q_PROPERTY_AUTO(bool, ignoreCase); Q_PROPERTY_AUTO(bool, ignoreCase)
QML_NAMED_ELEMENT(FluCaptcha) QML_NAMED_ELEMENT(FluCaptcha)
public: public:

View File

@ -11,41 +11,41 @@
* @brief The FluColors class * @brief The FluColors class
*/ */
class FluColors : public QObject { class FluColors : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QColor, Transparent); Q_PROPERTY_AUTO(QColor, Transparent)
Q_PROPERTY_AUTO(QColor, Black); Q_PROPERTY_AUTO(QColor, Black)
Q_PROPERTY_AUTO(QColor, White); Q_PROPERTY_AUTO(QColor, White)
Q_PROPERTY_AUTO(QColor, Grey10); Q_PROPERTY_AUTO(QColor, Grey10)
Q_PROPERTY_AUTO(QColor, Grey20); Q_PROPERTY_AUTO(QColor, Grey20)
Q_PROPERTY_AUTO(QColor, Grey30); Q_PROPERTY_AUTO(QColor, Grey30)
Q_PROPERTY_AUTO(QColor, Grey40); Q_PROPERTY_AUTO(QColor, Grey40)
Q_PROPERTY_AUTO(QColor, Grey50); Q_PROPERTY_AUTO(QColor, Grey50)
Q_PROPERTY_AUTO(QColor, Grey60); Q_PROPERTY_AUTO(QColor, Grey60)
Q_PROPERTY_AUTO(QColor, Grey70); Q_PROPERTY_AUTO(QColor, Grey70)
Q_PROPERTY_AUTO(QColor, Grey80); Q_PROPERTY_AUTO(QColor, Grey80)
Q_PROPERTY_AUTO(QColor, Grey90); Q_PROPERTY_AUTO(QColor, Grey90)
Q_PROPERTY_AUTO(QColor, Grey100); Q_PROPERTY_AUTO(QColor, Grey100)
Q_PROPERTY_AUTO(QColor, Grey110); Q_PROPERTY_AUTO(QColor, Grey110)
Q_PROPERTY_AUTO(QColor, Grey120); Q_PROPERTY_AUTO(QColor, Grey120)
Q_PROPERTY_AUTO(QColor, Grey130); Q_PROPERTY_AUTO(QColor, Grey130)
Q_PROPERTY_AUTO(QColor, Grey140); Q_PROPERTY_AUTO(QColor, Grey140)
Q_PROPERTY_AUTO(QColor, Grey150); Q_PROPERTY_AUTO(QColor, Grey150)
Q_PROPERTY_AUTO(QColor, Grey160); Q_PROPERTY_AUTO(QColor, Grey160)
Q_PROPERTY_AUTO(QColor, Grey170); Q_PROPERTY_AUTO(QColor, Grey170)
Q_PROPERTY_AUTO(QColor, Grey180); Q_PROPERTY_AUTO(QColor, Grey180)
Q_PROPERTY_AUTO(QColor, Grey190); Q_PROPERTY_AUTO(QColor, Grey190)
Q_PROPERTY_AUTO(QColor, Grey200); Q_PROPERTY_AUTO(QColor, Grey200)
Q_PROPERTY_AUTO(QColor, Grey210); Q_PROPERTY_AUTO(QColor, Grey210)
Q_PROPERTY_AUTO(QColor, Grey220); Q_PROPERTY_AUTO(QColor, Grey220)
Q_PROPERTY_AUTO_P(FluAccentColor*, Yellow); Q_PROPERTY_AUTO_P(FluAccentColor *, Yellow)
Q_PROPERTY_AUTO_P(FluAccentColor*, Orange); Q_PROPERTY_AUTO_P(FluAccentColor *, Orange)
Q_PROPERTY_AUTO_P(FluAccentColor*, Red); Q_PROPERTY_AUTO_P(FluAccentColor *, Red)
Q_PROPERTY_AUTO_P(FluAccentColor*, Magenta); Q_PROPERTY_AUTO_P(FluAccentColor *, Magenta)
Q_PROPERTY_AUTO_P(FluAccentColor*, Purple); Q_PROPERTY_AUTO_P(FluAccentColor *, Purple)
Q_PROPERTY_AUTO_P(FluAccentColor*, Blue); Q_PROPERTY_AUTO_P(FluAccentColor *, Blue)
Q_PROPERTY_AUTO_P(FluAccentColor*, Teal); Q_PROPERTY_AUTO_P(FluAccentColor *, Teal)
Q_PROPERTY_AUTO_P(FluAccentColor*, Green); Q_PROPERTY_AUTO_P(FluAccentColor *, Green)
QML_NAMED_ELEMENT(FluColors) QML_NAMED_ELEMENT(FluColors)
QML_SINGLETON QML_SINGLETON
@ -53,9 +53,11 @@ private:
explicit FluColors(QObject *parent = nullptr); explicit FluColors(QObject *parent = nullptr);
public: public:
SINGLETON(FluColors) SINGLETON(FluColors)
[[maybe_unused]] Q_INVOKABLE FluAccentColor *createAccentColor(const QColor &primaryColor); [[maybe_unused]] Q_INVOKABLE FluAccentColor *createAccentColor(const QColor &primaryColor);
static FluColors *create(QQmlEngine *, QJSEngine *) { return getInstance(); } static FluColors *create(QQmlEngine *, QJSEngine *) {
return getInstance();
}
}; };

View File

@ -14,16 +14,15 @@ using QT_NATIVE_EVENT_RESULT_TYPE = long;
using QT_ENTER_EVENT_TYPE = QEvent; using QT_ENTER_EVENT_TYPE = QEvent;
#endif #endif
class FluFrameless : public QQuickItem, QAbstractNativeEventFilter { class FluFrameless : public QQuickItem, QAbstractNativeEventFilter {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO_P(QQuickItem*, appbar) Q_PROPERTY_AUTO_P(QQuickItem *, appbar)
Q_PROPERTY_AUTO_P(QQuickItem*, maximizeButton) Q_PROPERTY_AUTO_P(QQuickItem *, maximizeButton)
Q_PROPERTY_AUTO_P(QQuickItem*, minimizedButton) Q_PROPERTY_AUTO_P(QQuickItem *, minimizedButton)
Q_PROPERTY_AUTO_P(QQuickItem*, closeButton) Q_PROPERTY_AUTO_P(QQuickItem *, closeButton)
Q_PROPERTY_AUTO(bool, topmost) Q_PROPERTY_AUTO(bool, topmost)
Q_PROPERTY_AUTO(bool, disabled) Q_PROPERTY_AUTO(bool, disabled)
Q_PROPERTY_AUTO(bool, fixSize) Q_PROPERTY_AUTO(bool, fixSize)
QML_NAMED_ELEMENT(FluFrameless) QML_NAMED_ELEMENT(FluFrameless)
public: public:
explicit FluFrameless(QQuickItem *parent = nullptr); explicit FluFrameless(QQuickItem *parent = nullptr);
@ -32,7 +31,8 @@ public:
void componentComplete() override; void componentComplete() override;
[[maybe_unused]] bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override; [[maybe_unused]] bool nativeEventFilter(const QByteArray &eventType, void *message,
QT_NATIVE_EVENT_RESULT_TYPE *result) override;
[[maybe_unused]] Q_INVOKABLE void showFullScreen(); [[maybe_unused]] Q_INVOKABLE void showFullScreen();

View File

@ -1,31 +1,26 @@
#include "FluHotkey.h" #include "FluHotkey.h"
#include "QGuiApplication" #include "QGuiApplication"
FluHotkey::FluHotkey(QObject *parent)
: QObject{parent} FluHotkey::FluHotkey(QObject *parent) : QObject{parent} {
{
_sequence = ""; _sequence = "";
_isRegistered = false; _isRegistered = false;
connect(this,&FluHotkey::sequenceChanged,this,[=]{ connect(this, &FluHotkey::sequenceChanged, this, [=] {
if(_hotkey){ if (_hotkey) {
delete _hotkey; delete _hotkey;
_hotkey = nullptr; _hotkey = nullptr;
} }
_hotkey = new QHotkey(QKeySequence(_sequence), true, qApp); _hotkey = new QHotkey(QKeySequence(_sequence), true, qApp);
this->isRegistered(_hotkey->isRegistered()); this->isRegistered(_hotkey->isRegistered());
QObject::connect(_hotkey, &QHotkey::activated, qApp, [=](){ QObject::connect(_hotkey, &QHotkey::activated, qApp, [=]() { Q_EMIT this->activated(); });
Q_EMIT this->activated(); QObject::connect(_hotkey, &QHotkey::registeredChanged, qApp,
}); [=]() { this->isRegistered(_hotkey->isRegistered()); });
QObject::connect(_hotkey, &QHotkey::registeredChanged, qApp, [=](){
this->isRegistered(_hotkey->isRegistered());
});
}); });
} }
FluHotkey::~FluHotkey(){ FluHotkey::~FluHotkey() {
if(_hotkey){ if (_hotkey) {
delete _hotkey; delete _hotkey;
_hotkey = nullptr; _hotkey = nullptr;
} }

View File

@ -6,19 +6,20 @@
#include "qhotkey/qhotkey.h" #include "qhotkey/qhotkey.h"
#include "stdafx.h" #include "stdafx.h"
class FluHotkey : public QObject class FluHotkey : public QObject {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,sequence) Q_PROPERTY_AUTO(QString, sequence)
Q_PROPERTY_AUTO(QString,name) Q_PROPERTY_AUTO(QString, name)
Q_PROPERTY_READONLY_AUTO(bool,isRegistered) Q_PROPERTY_READONLY_AUTO(bool, isRegistered)
QML_NAMED_ELEMENT(FluHotkey) QML_NAMED_ELEMENT(FluHotkey)
public: public:
explicit FluHotkey(QObject *parent = nullptr); explicit FluHotkey(QObject *parent = nullptr);
~FluHotkey(); ~FluHotkey();
Q_SIGNAL void activated(); Q_SIGNAL void activated();
private: private:
QHotkey* _hotkey = nullptr; QHotkey *_hotkey = nullptr;
}; };
#endif // FLUHOTKEY_H #endif // FLUHOTKEY_H

View File

@ -9,12 +9,12 @@
* @brief The FluQrCodeItem class * @brief The FluQrCodeItem class
*/ */
class FluQrCodeItem : public QQuickPaintedItem { class FluQrCodeItem : public QQuickPaintedItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString, text) Q_PROPERTY_AUTO(QString, text)
Q_PROPERTY_AUTO(QColor, color) Q_PROPERTY_AUTO(QColor, color)
Q_PROPERTY_AUTO(QColor, bgColor) Q_PROPERTY_AUTO(QColor, bgColor)
Q_PROPERTY_AUTO(int, size); Q_PROPERTY_AUTO(int, size)
QML_NAMED_ELEMENT(FluQrCodeItem) QML_NAMED_ELEMENT(FluQrCodeItem)
public: public:
explicit FluQrCodeItem(QQuickItem *parent = nullptr); explicit FluQrCodeItem(QQuickItem *parent = nullptr);

View File

@ -8,6 +8,7 @@ FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) {
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); }); connect(this, &FluRectangle::radiusChanged, this, [=] { update(); });
} }
void FluRectangle::paint(QPainter *painter) { void FluRectangle::paint(QPainter *painter) {
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing);
@ -15,13 +16,19 @@ void FluRectangle::paint(QPainter *painter) {
QRectF rect = boundingRect(); QRectF rect = boundingRect();
path.moveTo(rect.bottomRight() - QPointF(0, _radius[2])); path.moveTo(rect.bottomRight() - QPointF(0, _radius[2]));
path.lineTo(rect.topRight() + QPointF(0, _radius[1])); path.lineTo(rect.topRight() + QPointF(0, _radius[1]));
path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(_radius[1] * 2, 0)), QSize(_radius[1] * 2, _radius[1] * 2)), 0, 90); path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(_radius[1] * 2, 0)),
QSize(_radius[1] * 2, _radius[1] * 2)),
0, 90);
path.lineTo(rect.topLeft() + QPointF(_radius[0], 0)); path.lineTo(rect.topLeft() + QPointF(_radius[0], 0));
path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(_radius[0] * 2, _radius[0] * 2)), 90, 90); path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(_radius[0] * 2, _radius[0] * 2)), 90, 90);
path.lineTo(rect.bottomLeft() - QPointF(0, _radius[3])); path.lineTo(rect.bottomLeft() - QPointF(0, _radius[3]));
path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)), QSize(_radius[3] * 2, _radius[3] * 2)), 180, 90); path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)),
QSize(_radius[3] * 2, _radius[3] * 2)),
180, 90);
path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0)); path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0));
path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)), QSize(_radius[2] * 2, _radius[2] * 2)), 270, 90); path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)),
QSize(_radius[2] * 2, _radius[2] * 2)),
270, 90);
painter->fillPath(path, _color); painter->fillPath(path, _color);
painter->restore(); painter->restore();
} }

View File

@ -9,9 +9,9 @@
* @brief The FluRectangle class * @brief The FluRectangle class
*/ */
class FluRectangle : public QQuickPaintedItem { class FluRectangle : public QQuickPaintedItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QColor, color) Q_PROPERTY_AUTO(QColor, color)
Q_PROPERTY_AUTO(QList<int>, radius) Q_PROPERTY_AUTO(QList<int>, radius)
QML_NAMED_ELEMENT(FluRectangle) QML_NAMED_ELEMENT(FluRectangle)
public: public:
explicit FluRectangle(QQuickItem *parent = nullptr); explicit FluRectangle(QQuickItem *parent = nullptr);

View File

@ -1,13 +1,13 @@
#include "FluTableModel.h" #include "FluTableModel.h"
FluTableModel::FluTableModel(QObject *parent) : QAbstractTableModel{parent} { FluTableModel::FluTableModel(QObject *parent) : QAbstractTableModel{parent} {
} }
int FluTableModel::rowCount(const QModelIndex &parent) const { int FluTableModel::rowCount(const QModelIndex &parent) const {
return _rows.count(); return _rows.count();
} }
int FluTableModel::columnCount(const QModelIndex &parent) const { int FluTableModel::columnCount(const QModelIndex &parent) const {
return this->_columnSource.size(); return this->_columnSource.size();
} }
@ -26,8 +26,8 @@ QVariant FluTableModel::data(const QModelIndex &index, int role) const {
QHash<int, QByteArray> FluTableModel::roleNames() const { QHash<int, QByteArray> FluTableModel::roleNames() const {
return { return {
{FluTableModel::RowModel, "rowModel"}, {FluTableModel::RowModel, "rowModel" },
{FluTableModel::ColumnModel, "columnModel"} {FluTableModel::ColumnModel, "columnModel"}
}; };
} }

View File

@ -7,16 +7,14 @@
#include "stdafx.h" #include "stdafx.h"
class FluTableModel : public QAbstractTableModel { class FluTableModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource) Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource)
Q_PROPERTY_AUTO(QList<QVariantMap>, rows) Q_PROPERTY_AUTO(QList<QVariantMap>, rows)
Q_PROPERTY(int rowCount READ rowCount CONSTANT) Q_PROPERTY(int rowCount READ rowCount CONSTANT)
QML_NAMED_ELEMENT(FluTableModel) QML_NAMED_ELEMENT(FluTableModel)
public: public:
enum TableModelRoles { enum TableModelRoles { RowModel = 0x0101, ColumnModel = 0x0102 };
RowModel = 0x0101,
ColumnModel = 0x0102
};
explicit FluTableModel(QObject *parent = nullptr); explicit FluTableModel(QObject *parent = nullptr);
@ -24,7 +22,8 @@ public:
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override; [[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant data(const QModelIndex &index,
int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
@ -39,7 +38,6 @@ public:
Q_INVOKABLE void removeRow(int rowIndex, int rows = 1); Q_INVOKABLE void removeRow(int rowIndex, int rows = 1);
Q_INVOKABLE void appendRow(QVariant row); Q_INVOKABLE void appendRow(QVariant row);
}; };

View File

@ -2,13 +2,14 @@
#include <QJSValueList> #include <QJSValueList>
FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent) : QSortFilterProxyModel{parent} { FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent)
connect(this, &FluTableSortProxyModel::modelChanged, this, [=] { : QSortFilterProxyModel{parent} {
setSourceModel(this->model().value<QAbstractTableModel *>()); connect(this, &FluTableSortProxyModel::modelChanged, this,
}); [=] { setSourceModel(this->model().value<QAbstractTableModel *>()); });
} }
bool FluTableSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { bool FluTableSortProxyModel::filterAcceptsRow(int source_row,
const QModelIndex &source_parent) const {
QJSValue filter = _filter; QJSValue filter = _filter;
if (filter.isUndefined()) { if (filter.isUndefined()) {
return true; return true;
@ -18,11 +19,13 @@ bool FluTableSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex
return filter.call(data).toBool(); return filter.call(data).toBool();
} }
bool FluTableSortProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const { bool FluTableSortProxyModel::filterAcceptsColumn(int source_column,
const QModelIndex &source_parent) const {
return true; return true;
} }
bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left,
const QModelIndex &source_right) const {
QJSValue comparator = _comparator; QJSValue comparator = _comparator;
if (comparator.isUndefined()) { if (comparator.isUndefined()) {
return true; return true;
@ -58,18 +61,25 @@ bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left, const QMod
[[maybe_unused]] QVariant FluTableSortProxyModel::getRow(int rowIndex) { [[maybe_unused]] QVariant FluTableSortProxyModel::getRow(int rowIndex) {
QVariant result; QVariant result;
QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "getRow", Q_RETURN_ARG(QVariant, result), Q_ARG(int, mapToSource(index(rowIndex, 0)).row())); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "getRow",
Q_RETURN_ARG(QVariant, result),
Q_ARG(int, mapToSource(index(rowIndex, 0)).row()));
return result; return result;
} }
[[maybe_unused]] void FluTableSortProxyModel::setRow(int rowIndex, const QVariant &val) { [[maybe_unused]] void FluTableSortProxyModel::setRow(int rowIndex, const QVariant &val) {
QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "setRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val)); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "setRow",
Q_ARG(int, mapToSource(index(rowIndex, 0)).row()),
Q_ARG(QVariant, val));
} }
[[maybe_unused]] void FluTableSortProxyModel::insertRow(int rowIndex, const QVariant &val) { [[maybe_unused]] void FluTableSortProxyModel::insertRow(int rowIndex, const QVariant &val) {
QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "insertRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val)); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "insertRow",
Q_ARG(int, mapToSource(index(rowIndex, 0)).row()),
Q_ARG(QVariant, val));
} }
[[maybe_unused]] void FluTableSortProxyModel::removeRow(int rowIndex, int rows) { [[maybe_unused]] void FluTableSortProxyModel::removeRow(int rowIndex, int rows) {
QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "removeRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows)); QMetaObject::invokeMethod(_model.value<QAbstractTableModel *>(), "removeRow",
Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows));
} }

View File

@ -7,8 +7,8 @@
#include "stdafx.h" #include "stdafx.h"
class FluTableSortProxyModel : public QSortFilterProxyModel { class FluTableSortProxyModel : public QSortFilterProxyModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO_P(QVariant, model) Q_PROPERTY_AUTO_P(QVariant, model)
QML_NAMED_ELEMENT(FluTableSortProxyModel) QML_NAMED_ELEMENT(FluTableSortProxyModel)
public: public:
explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr); explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr);

View File

@ -10,16 +10,17 @@
* @brief The FluTextStyle class * @brief The FluTextStyle class
*/ */
class FluTextStyle : public QObject { class FluTextStyle : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Q_PROPERTY_AUTO(QString, family) Q_PROPERTY_AUTO(QString, family)
Q_PROPERTY_AUTO(QFont, Caption); Q_PROPERTY_AUTO(QFont, Caption)
Q_PROPERTY_AUTO(QFont, Body); Q_PROPERTY_AUTO(QFont, Body)
Q_PROPERTY_AUTO(QFont, BodyStrong); Q_PROPERTY_AUTO(QFont, BodyStrong)
Q_PROPERTY_AUTO(QFont, Subtitle); Q_PROPERTY_AUTO(QFont, Subtitle)
Q_PROPERTY_AUTO(QFont, Title); Q_PROPERTY_AUTO(QFont, Title)
Q_PROPERTY_AUTO(QFont, TitleLarge); Q_PROPERTY_AUTO(QFont, TitleLarge)
Q_PROPERTY_AUTO(QFont, Display); Q_PROPERTY_AUTO(QFont, Display)
QML_NAMED_ELEMENT(FluTextStyle) QML_NAMED_ELEMENT(FluTextStyle)
QML_SINGLETON QML_SINGLETON
@ -27,7 +28,9 @@ private:
explicit FluTextStyle(QObject *parent = nullptr); explicit FluTextStyle(QObject *parent = nullptr);
public: public:
SINGLETON(FluTextStyle) SINGLETON(FluTextStyle)
static FluTextStyle *create(QQmlEngine *, QJSEngine *) { return getInstance(); } static FluTextStyle *create(QQmlEngine *, QJSEngine *) {
return getInstance();
}
}; };

View File

@ -24,15 +24,13 @@ FluTheme::FluTheme(QObject *parent) : QObject{parent} {
_blurBehindWindowEnabled = false; _blurBehindWindowEnabled = false;
QGuiApplication::instance()->installEventFilter(this); QGuiApplication::instance()->installEventFilter(this);
refreshColors(); refreshColors();
connect(this, &FluTheme::darkModeChanged, this, [=] { connect(this, &FluTheme::darkModeChanged, this, [=] { Q_EMIT darkChanged(); });
Q_EMIT darkChanged();
});
connect(this, &FluTheme::darkChanged, this, [=] { refreshColors(); }); connect(this, &FluTheme::darkChanged, this, [=] { refreshColors(); });
connect(this, &FluTheme::accentColorChanged, this, [=] { refreshColors(); }); connect(this, &FluTheme::accentColorChanged, this, [=] { refreshColors(); });
connect(&_watcher, &QFileSystemWatcher::fileChanged, this, [=](const QString &path) { connect(&_watcher, &QFileSystemWatcher::fileChanged, this,
Q_EMIT desktopImagePathChanged(); [=](const QString &path) { Q_EMIT desktopImagePathChanged(); });
}); connect(this, &FluTheme::blurBehindWindowEnabledChanged, this,
connect(this, &FluTheme::blurBehindWindowEnabledChanged, this, [=] { checkUpdateDesktopImage(); }); [=] { checkUpdateDesktopImage(); });
startTimer(1000); startTimer(1000);
} }
@ -47,11 +45,16 @@ void FluTheme::refreshColors() {
fontSecondaryColor(isDark ? QColor(222, 222, 222, 255) : QColor(102, 102, 102, 255)); fontSecondaryColor(isDark ? QColor(222, 222, 222, 255) : QColor(102, 102, 102, 255));
fontTertiaryColor(isDark ? QColor(200, 200, 200, 255) : QColor(153, 153, 153, 255)); fontTertiaryColor(isDark ? QColor(200, 200, 200, 255) : QColor(153, 153, 153, 255));
itemNormalColor(isDark ? QColor(255, 255, 255, 0) : QColor(0, 0, 0, 0)); itemNormalColor(isDark ? QColor(255, 255, 255, 0) : QColor(0, 0, 0, 0));
frameColor(isDark ? QColor(56, 56, 56, qRound(255 * 0.8)) : QColor(243, 243, 243, qRound(255 * 0.8))); frameColor(isDark ? QColor(56, 56, 56, qRound(255 * 0.8))
frameActiveColor(isDark ? QColor(48, 48, 48, qRound(255 * 0.8)) : QColor(255, 255, 255, qRound(255 * 0.8))); : QColor(243, 243, 243, qRound(255 * 0.8)));
itemHoverColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.06)) : QColor(0, 0, 0, qRound(255 * 0.03))); frameActiveColor(isDark ? QColor(48, 48, 48, qRound(255 * 0.8))
itemPressColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.09)) : QColor(0, 0, 0, qRound(255 * 0.06))); : QColor(255, 255, 255, qRound(255 * 0.8)));
itemCheckColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.12)) : QColor(0, 0, 0, qRound(255 * 0.09))); itemHoverColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.06))
: QColor(0, 0, 0, qRound(255 * 0.03)));
itemPressColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.09))
: QColor(0, 0, 0, qRound(255 * 0.06)));
itemCheckColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.12))
: QColor(0, 0, 0, qRound(255 * 0.09)));
} }
bool FluTheme::eventFilter(QObject *, QEvent *event) { bool FluTheme::eventFilter(QObject *, QEvent *event) {

View File

@ -16,28 +16,28 @@
* @brief The FluTheme class * @brief The FluTheme class
*/ */
class FluTheme : public QObject { class FluTheme : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged) Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
Q_PROPERTY_AUTO_P(FluAccentColor*, accentColor); Q_PROPERTY_AUTO_P(FluAccentColor *, accentColor)
Q_PROPERTY_AUTO(QColor, primaryColor); Q_PROPERTY_AUTO(QColor, primaryColor)
Q_PROPERTY_AUTO(QColor, backgroundColor); Q_PROPERTY_AUTO(QColor, backgroundColor)
Q_PROPERTY_AUTO(QColor, dividerColor); Q_PROPERTY_AUTO(QColor, dividerColor)
Q_PROPERTY_AUTO(QColor, windowBackgroundColor); Q_PROPERTY_AUTO(QColor, windowBackgroundColor)
Q_PROPERTY_AUTO(QColor, windowActiveBackgroundColor); Q_PROPERTY_AUTO(QColor, windowActiveBackgroundColor)
Q_PROPERTY_AUTO(QColor, fontPrimaryColor); Q_PROPERTY_AUTO(QColor, fontPrimaryColor)
Q_PROPERTY_AUTO(QColor, fontSecondaryColor); Q_PROPERTY_AUTO(QColor, fontSecondaryColor)
Q_PROPERTY_AUTO(QColor, fontTertiaryColor); Q_PROPERTY_AUTO(QColor, fontTertiaryColor)
Q_PROPERTY_AUTO(QColor, itemNormalColor); Q_PROPERTY_AUTO(QColor, itemNormalColor)
Q_PROPERTY_AUTO(QColor, frameColor); Q_PROPERTY_AUTO(QColor, frameColor)
Q_PROPERTY_AUTO(QColor, frameActiveColor); Q_PROPERTY_AUTO(QColor, frameActiveColor)
Q_PROPERTY_AUTO(QColor, itemHoverColor); Q_PROPERTY_AUTO(QColor, itemHoverColor)
Q_PROPERTY_AUTO(QColor, itemPressColor); Q_PROPERTY_AUTO(QColor, itemPressColor)
Q_PROPERTY_AUTO(QColor, itemCheckColor); Q_PROPERTY_AUTO(QColor, itemCheckColor)
Q_PROPERTY_AUTO(QString, desktopImagePath); Q_PROPERTY_AUTO(QString, desktopImagePath)
Q_PROPERTY_AUTO(int, darkMode); Q_PROPERTY_AUTO(int, darkMode)
Q_PROPERTY_AUTO(bool, nativeText); Q_PROPERTY_AUTO(bool, nativeText)
Q_PROPERTY_AUTO(bool, animationEnabled); Q_PROPERTY_AUTO(bool, animationEnabled)
Q_PROPERTY_AUTO(bool, blurBehindWindowEnabled); Q_PROPERTY_AUTO(bool, blurBehindWindowEnabled)
QML_NAMED_ELEMENT(FluTheme) QML_NAMED_ELEMENT(FluTheme)
QML_SINGLETON QML_SINGLETON
@ -49,17 +49,18 @@ private:
void refreshColors(); void refreshColors();
protected: protected:
void timerEvent(QTimerEvent *event) override; void timerEvent(QTimerEvent *event) override;
void checkUpdateDesktopImage(); void checkUpdateDesktopImage();
public: public:
SINGLETON(FluTheme) SINGLETON(FluTheme)
Q_SIGNAL void darkChanged(); Q_SIGNAL void darkChanged();
static FluTheme *create(QQmlEngine *, QJSEngine *) { return getInstance(); } static FluTheme *create(QQmlEngine *, QJSEngine *) {
return getInstance();
}
bool dark() const; bool dark() const;

View File

@ -17,15 +17,14 @@
#include <QSettings> #include <QSettings>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment (lib, "user32.lib") # pragma comment(lib, "user32.lib")
#include <windows.h> # include <windows.h>
#include <windowsx.h> # include <windowsx.h>
#endif #endif
FluTools::FluTools(QObject *parent) : QObject{parent} { FluTools::FluTools(QObject *parent) : QObject{parent} {
} }
void FluTools::clipText(const QString &text) { void FluTools::clipText(const QString &text) {
@ -164,11 +163,12 @@ void FluTools::showFileInFolder(const QString &path) {
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
QFileInfo fileInfo(path); QFileInfo fileInfo(path);
auto process = "xdg-open"; auto process = "xdg-open";
auto arguments = { fileInfo.absoluteDir().absolutePath() }; auto arguments = {fileInfo.absoluteDir().absolutePath()};
QProcess::startDetached(process, arguments); QProcess::startDetached(process, arguments);
#endif #endif
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
QProcess::execute("/usr/bin/osascript", {"-e", "tell application \"Finder\" to reveal POSIX file \"" + path + "\""}); QProcess::execute("/usr/bin/osascript",
{"-e", "tell application \"Finder\" to reveal POSIX file \"" + path + "\""});
QProcess::execute("/usr/bin/osascript", {"-e", "tell application \"Finder\" to activate"}); QProcess::execute("/usr/bin/osascript", {"-e", "tell application \"Finder\" to activate"});
#endif #endif
} }
@ -206,7 +206,9 @@ int FluTools::cursorScreenIndex() {
int FluTools::windowBuildNumber() { int FluTools::windowBuildNumber() {
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings regKey{QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"), QSettings::NativeFormat}; QSettings regKey{
QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"),
QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) { if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt(); auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
return buildNumber; return buildNumber;
@ -289,7 +291,7 @@ QString FluTools::getWallpaperFilePath() {
process.start("osascript", args); process.start("osascript", args);
process.waitForFinished(); process.waitForFinished();
QByteArray result = process.readAllStandardOutput().trimmed(); QByteArray result = process.readAllStandardOutput().trimmed();
if(result.isEmpty()){ if (result.isEmpty()) {
return "/System/Library/CoreServices/DefaultDesktop.heic"; return "/System/Library/CoreServices/DefaultDesktop.heic";
} }
return result; return result;
@ -313,5 +315,7 @@ QColor FluTools::imageMainColor(const QImage &image, double bright) {
} }
} }
} }
return QColor(int(bright * r / t) > 255 ? 255 : int(bright * r / t), int(bright * g / t) > 255 ? 255 : int(bright * g / t), int(bright * b / t) > 255 ? 255 : int(bright * b / t)); return QColor(int(bright * r / t) > 255 ? 255 : int(bright * r / t),
int(bright * g / t) > 255 ? 255 : int(bright * g / t),
int(bright * b / t) > 255 ? 255 : int(bright * b / t));
} }

View File

@ -11,7 +11,7 @@
* @brief The FluTools class * @brief The FluTools class
*/ */
class FluTools : public QObject { class FluTools : public QObject {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(FluTools) QML_NAMED_ELEMENT(FluTools)
QML_SINGLETON QML_SINGLETON
@ -19,9 +19,11 @@ private:
explicit FluTools(QObject *parent = nullptr); explicit FluTools(QObject *parent = nullptr);
public: public:
SINGLETON(FluTools) SINGLETON(FluTools)
static FluTools *create(QQmlEngine *, QJSEngine *) { return getInstance(); } static FluTools *create(QQmlEngine *, QJSEngine *) {
return getInstance();
}
Q_INVOKABLE int qtMajor(); Q_INVOKABLE int qtMajor();

View File

@ -31,8 +31,8 @@ QVariant FluTreeModel::data(const QModelIndex &index, int role) const {
QHash<int, QByteArray> FluTreeModel::roleNames() const { QHash<int, QByteArray> FluTreeModel::roleNames() const {
return { return {
{TreeModelRoles::RowModel, "rowModel"}, {TreeModelRoles::RowModel, "rowModel" },
{TreeModelRoles::ColumnModel, "columnModel"} {TreeModelRoles::ColumnModel, "columnModel"}
}; };
} }
@ -90,9 +90,9 @@ void FluTreeModel::checkRow(int row, bool checked) {
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) { if (!children.isEmpty()) {
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
} else { } else {
@ -102,7 +102,6 @@ void FluTreeModel::checkRow(int row, bool checked) {
itemData->_checked = checked; itemData->_checked = checked;
} }
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0)); Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0));
} }
void FluTreeModel::setDataSource(QList<QMap<QString, QVariant>> data) { void FluTreeModel::setDataSource(QList<QMap<QString, QVariant>> data) {
@ -184,9 +183,9 @@ void FluTreeModel::expand(int row) {
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) { if (!children.isEmpty()) {
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
insertRows(row + 1, insertData); insertRows(row + 1, insertData);
@ -223,9 +222,9 @@ void FluTreeModel::allExpand() {
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) { if (!children.isEmpty()) {
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
_rows = data; _rows = data;
@ -245,9 +244,9 @@ void FluTreeModel::allCollapse() {
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) { if (!children.isEmpty()) {
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
_rows = _root->_children; _rows = _root->_children;
@ -256,10 +255,10 @@ void FluTreeModel::allCollapse() {
QVariant FluTreeModel::selectionModel() { QVariant FluTreeModel::selectionModel() {
QList<FluTreeNode *> data; QList<FluTreeNode *> data;
foreach (auto item, _dataSource) { foreach (auto item, _dataSource) {
if (item->checked()) { if (item->checked()) {
data.append(item); data.append(item);
}
} }
}
return QVariant::fromValue(data); return QVariant::fromValue(data);
} }

View File

@ -7,11 +7,12 @@
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include "stdafx.h" #include "stdafx.h"
/** /**
* @brief The FluTreeNode class * @brief The FluTreeNode class
*/ */
class FluTreeNode : public QObject { class FluTreeNode : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QVariantMap data READ data CONSTANT) Q_PROPERTY(QVariantMap data READ data CONSTANT)
Q_PROPERTY(int depth READ depth CONSTANT) Q_PROPERTY(int depth READ depth CONSTANT)
Q_PROPERTY(bool isExpanded READ isExpanded CONSTANT) Q_PROPERTY(bool isExpanded READ isExpanded CONSTANT)
@ -19,13 +20,21 @@ Q_OBJECT
public: public:
explicit FluTreeNode(QObject *parent = nullptr); explicit FluTreeNode(QObject *parent = nullptr);
[[nodiscard]] Q_INVOKABLE int depth() const { return _depth; }; [[nodiscard]] Q_INVOKABLE int depth() const {
return _depth;
};
[[nodiscard]] Q_INVOKABLE bool isExpanded() const { return _isExpanded; }; [[nodiscard]] Q_INVOKABLE bool isExpanded() const {
return _isExpanded;
};
[[nodiscard]] Q_INVOKABLE QVariantMap data() const { return _data; }; [[nodiscard]] Q_INVOKABLE QVariantMap data() const {
return _data;
};
[[nodiscard]] Q_INVOKABLE bool hasChildren() const { return !_children.isEmpty(); }; [[nodiscard]] Q_INVOKABLE bool hasChildren() const {
return !_children.isEmpty();
};
Q_INVOKABLE bool hasNextNodeByIndex(int index) { Q_INVOKABLE bool hasNextNodeByIndex(int index) {
FluTreeNode *p = this; FluTreeNode *p = this;
@ -87,15 +96,12 @@ public:
}; };
class FluTreeModel : public QAbstractTableModel { class FluTreeModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int, dataSourceSize) Q_PROPERTY_AUTO(int, dataSourceSize)
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource) Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource)
QML_NAMED_ELEMENT(FluTreeModel) QML_NAMED_ELEMENT(FluTreeModel)
public: public:
enum TreeModelRoles { enum TreeModelRoles { RowModel = 0x0101, ColumnModel = 0x0102 };
RowModel = 0x0101,
ColumnModel = 0x0102
};
explicit FluTreeModel(QObject *parent = nullptr); explicit FluTreeModel(QObject *parent = nullptr);
@ -103,7 +109,8 @@ public:
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override; [[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; [[nodiscard]] QVariant data(const QModelIndex &index,
int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;

View File

@ -17,6 +17,7 @@ FluWatermark::FluWatermark(QQuickItem *parent) : QQuickPaintedItem(parent) {
connect(this, &FluWatermark::textSizeChanged, this, [=] { update(); }); connect(this, &FluWatermark::textSizeChanged, this, [=] { update(); });
} }
void FluWatermark::paint(QPainter *painter) { void FluWatermark::paint(QPainter *painter) {
QFont font; QFont font;
font.setFamily(FluTextStyle::getInstance()->family()); font.setFamily(FluTextStyle::getInstance()->family());
@ -37,7 +38,8 @@ void FluWatermark::paint(QPainter *painter) {
painter->save(); painter->save();
painter->translate(centerX, centerY); painter->translate(centerX, centerY);
painter->rotate(_rotate); painter->rotate(_rotate);
painter->drawText(QRectF(-fontWidth / 2.0, -fontHeight / 2.0, fontWidth, fontHeight), _text); painter->drawText(QRectF(-fontWidth / 2.0, -fontHeight / 2.0, fontWidth, fontHeight),
_text);
painter->restore(); painter->restore();
} }
} }

View File

@ -8,10 +8,10 @@
* @brief The FluentUI class * @brief The FluentUI class
*/ */
class FluentUI : public QObject { class FluentUI : public QObject {
Q_OBJECT Q_OBJECT
public: public:
SINGLETON(FluentUI) SINGLETON(FluentUI)
Q_DECL_EXPORT void registerTypes(QQmlEngine *engine); Q_DECL_EXPORT void registerTypes(QQmlEngine *engine);

View File

@ -6,7 +6,7 @@
* @brief The FluentUIPlugin class * @brief The FluentUIPlugin class
*/ */
class FluentUIPlugin : public QQmlExtensionPlugin { class FluentUIPlugin : public QQmlExtensionPlugin {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public: public:

View File

@ -132,7 +132,7 @@ quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok)
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface<QNativeInterface::QX11Application>(); const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
Display *display = x11Interface->display(); Display *display = x11Interface ? x11Interface->display() : nullptr;
#else #else
const bool x11Interface = QX11Info::isPlatformX11(); const bool x11Interface = QX11Info::isPlatformX11();
Display *display = QX11Info::display(); Display *display = QX11Info::display();

View File

@ -1,24 +1,26 @@
#pragma once #pragma once
/** /**
* @brief The Singleton class * @brief The Singleton class
*/ */
template<typename T> template <typename T>
class Singleton { class Singleton {
public: public:
static T *getInstance(); static T *getInstance();
}; };
template<typename T> template <typename T>
T *Singleton<T>::getInstance() { T *Singleton<T>::getInstance() {
static T *instance = new T(); static T *instance = new T();
return instance; return instance;
} }
#define SINGLETON(Class) \ #define SINGLETON(Class) \
private: \ private: \
friend class Singleton<Class>; \ friend class Singleton<Class>; \
public: \ \
static Class* getInstance() { \ public: \
return Singleton<Class>::getInstance(); \ static Class *getInstance() { \
} return Singleton<Class>::getInstance(); \
}

View File

@ -1,50 +1,48 @@
#pragma once #pragma once
#define Q_PROPERTY_AUTO_P(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \ #define Q_PROPERTY_AUTO_P(TYPE, M) \
public: \ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
Q_SIGNAL void M##Changed(); \ public: \
void M(TYPE in_##M) \ Q_SIGNAL void M##Changed(); \
{ \ void M(TYPE in_##M) { \
_##M = in_##M; \ _##M = in_##M; \
Q_EMIT M##Changed(); \ Q_EMIT M##Changed(); \
} \ } \
TYPE M() \ TYPE M() { \
{ \ return _##M; \
return _##M; \ } \
} \ \
private: \ private: \
TYPE _##M; TYPE _##M;
#define Q_PROPERTY_AUTO(TYPE, M) \ #define Q_PROPERTY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \ void M(const TYPE &in_##M) { \
{ \ _##M = in_##M; \
_##M = in_##M; \ Q_EMIT M##Changed(); \
Q_EMIT M##Changed(); \ } \
} \ TYPE M() { \
TYPE M() \ return _##M; \
{ \ } \
return _##M; \ \
} \ private: \
private: \
TYPE _##M; TYPE _##M;
#define Q_PROPERTY_READONLY_AUTO(TYPE, M) \ #define Q_PROPERTY_READONLY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \ Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \ void M(const TYPE &in_##M) { \
{ \ _##M = in_##M; \
_##M = in_##M; \ Q_EMIT M##Changed(); \
Q_EMIT M##Changed(); \ } \
} \ TYPE M() { \
TYPE M() \ return _##M; \
{ \ } \
return _##M; \ \
} \ private: \
private: \
TYPE _##M; TYPE _##M;