1
0
mirror of https://github.com/jaredtao/TaoQuick.git synced 2025-01-17 20:12:54 +08:00

update format; update TaoCommon

This commit is contained in:
jared 2020-10-24 12:10:11 +08:00
parent 6e88f1d107
commit 2b0e06450a
28 changed files with 1161 additions and 1240 deletions

View File

@ -1,233 +0,0 @@
---
# 关闭格式化
DisableFormat: false
# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle: WebKit
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4
# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: AlwaysBreak
# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: false
# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: true
# 左对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right
# 水平对齐二元和三元表达式的操作数
AlignOperands: true
# 对齐连续的尾随的注释
AlignTrailingComments: true
# 允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: false
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: false
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: Empty
# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false
# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: false
# 总是在定义返回类型后换行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None
# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true
# false表示函数实参要么都在同一行要么都各自一行
BinPackArguments: false
# false表示所有形参要么都在同一行要么都各自一行
BinPackParameters: false
# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义与Attach类似),
# Mozilla(除枚举、函数、记录定义与Attach类似), Stroustrup(除函数定义、catch、else与Attach类似),
# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Custom
# 大括号换行只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
# class定义后面
AfterClass: true
# 控制语句后面
AfterControlStatement: false
# enum定义后面
AfterEnum: true
# 函数定义后面
AfterFunction: true
# 命名空间定义后面
AfterNamespace: true
# ObjC定义后面
AfterObjCDeclaration: false
# struct定义后面
AfterStruct: true
# union定义后面
AfterUnion: true
# extern 定义后面
AfterExternBlock: true
# catch之前
BeforeCatch: false
# else 之前
BeforeElse: false
# 缩进大括号
IndentBraces: false
#SplitEmptyFunction: true
#SplitEmptyRecord: true
#SplitEmptyNamespace: true
# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: All
# 继承列表的逗号前换行
BreakBeforeInheritanceComma: true
# 继承列表换行
BreakInheritanceList: BeforeColon
# 在三元运算符前换行
BreakBeforeTernaryOperators: true
# 在构造函数的初始化列表的逗号前换行
BreakConstructorInitializersBeforeComma: true
# 初始化列表前换行
BreakConstructorInitializers: BeforeComma
# Java注解后换行
BreakAfterJavaFieldAnnotations: true
BreakStringLiterals: true
# 每行字符的限制0表示没有限制
ColumnLimit: 160
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'
# 紧凑 命名空间
CompactNamespaces: false
# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false
# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: false
# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false
# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false
# 固定命名空间注释
FixNamespaceComments: true
# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
# 对#include进行排序匹配了某正则表达式的#include拥有对应的优先级匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前)
# 可以定义负数优先级从而保证某些#include永远在最前面
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: 'stdafx\.'
Priority: 1
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
# 缩进case标签
IndentCaseLabels: true
IndentPPDirectives: None
# 缩进宽度
IndentWidth: 4
# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: true
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
#KeepLineBreaksForNonEmptyLines: false
# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: true
# 开始一个块的宏的正则表达式
MacroBlockBegin: ''
# 结束一个块的宏的正则表达式
MacroBlockEnd: ''
# 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
# 使用ObjC块时缩进宽度
ObjCBlockIndentWidth: 4
# 在ObjC的@property后添加一个空格
ObjCSpaceAfterProperty: true
# 在ObjC的protocol列表前添加一个空格
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
# 在一个注释中引入换行的penalty
PenaltyBreakComment: 300
# 第一次在<<前换行的penalty
PenaltyBreakFirstLessLess: 120
# 在一个字符串字面量中引入换行的penalty
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
# 对于每个在行字符数限制之外的字符的penalty
PenaltyExcessCharacter: 1000000
# 将函数的返回类型放到它自己的行的penalty
PenaltyReturnTypeOnItsOwnLine: 60
# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right
#RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# 允许重新排版注释
ReflowComments: false
# 允许排序#include
SortIncludes: true
SortUsingDeclarations: true
# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# 模板关键字后面添加空格
SpaceAfterTemplateKeyword: true
# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false
# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1
# 在尖括号的<后和>前添加空格
SpacesInAngles: false
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# 在圆括号的(后和)前添加空格
SpacesInParentheses: false
# 在方括号的[后和]前添加空格lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# 标准: Cpp03, Cpp11, Auto
Standard: Cpp11
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
...

39
.commit-template Normal file
View File

@ -0,0 +1,39 @@
# ==[ Subject: One line only short meaningful description for logs ]===|
# ==[ Details: Describe what changed and explain why it changed ]======|
# Change log entry (see below for instructions).
#[ChangeLog][][]
# ==[ Footers: Uncomment and edit where applicable ]===================|
#
# One task per entry. Add a space after the colon.
# Use Fixes to automatically close an issue, and Task-number to
# reference it without further action.
# You do not need both for the same issue.
#Fixes:
#Task-number:
#Coverity-Id:
#
# Add a space-separated list of target branches that the change should
# be cherry-picked to automatically.
#Pick-to:
#
# ==[ Please wrap at 72 characters ]===================================|
#
# Remember to read http://wiki.qt.io/Commit_Policy
#
# Change log entry: If this commit adds a significant feature, fixes an
# issue or contains a behavior change that is relevant to others,
# add a change log entry. It can be multiple lines long and ends with an
# empty newline. Try to integrate it into the flow of the commit message
# to avoid redundancy.
# Use the module name to indicate the area of the change e.g. [QtCore].
# Optionally specify a class or subtopic [QtNetwork][QSslSocket].
# Other common tags are: [General], [Important Behavior Changes],
# [Platform Specific Changes][Windows][OS X][Linux/XCB].
#
# [ChangeLog][module][class/topic] description of the really important
# change that was just made on several lines.

68
.gitattributes vendored
View File

@ -1,62 +1,6 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
#*.png filter=lfs diff=lfs merge=lfs -text
#*.jpg filter=lfs diff=lfs merge=lfs -text
#*.gif filter=lfs diff=lfs merge=lfs -text
.tag export-subst
.gitignore export-ignore
.gitattributes export-ignore
.commit-template export-ignore eol=lf
init-repository export-ignore
README.git export-ignore

268
.gitignore vendored
View File

@ -1,264 +1,4 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
build/
run/
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
*.qmlc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
/.vscode/settings.json
Makefile
.qmake.cache
.qmake.super
*.pro.user*

1
.tag Normal file
View File

@ -0,0 +1 @@
$Format:%H$

View File

@ -6,102 +6,93 @@
#include <QJsonObject>
#include <QString>
#include "Logger/logger.h"
namespace TaoCommon
namespace TaoCommon {
static bool readFile(const QString &filePath, QByteArray &content)
{
static bool readFile(const QString &filePath, QByteArray &content)
{
QFile file(filePath);
if (!file.open(QFile::ReadOnly))
{
LOG_WARN << "open file " << filePath << "failed:" << file.errorString();
return false;
}
content = file.readAll();
file.close();
return true;
QFile file(filePath);
if (!file.open(QFile::ReadOnly)) {
LOG_WARN << "open file " << filePath << "failed:" << file.errorString();
return false;
}
static bool readJson(const QByteArray &data, QJsonDocument &doc)
{
QJsonParseError err;
doc = QJsonDocument::fromJson(data, &err);
if (doc.isNull())
{
LOG_WARN << "parse json failed:" << err.errorString();
return false;
}
return true;
content = file.readAll();
file.close();
return true;
}
static bool readJson(const QByteArray &data, QJsonDocument &doc)
{
QJsonParseError err;
doc = QJsonDocument::fromJson(data, &err);
if (doc.isNull()) {
LOG_WARN << "parse json failed:" << err.errorString();
return false;
}
static bool readJson(const QByteArray &data, QJsonArray &array)
{
QJsonDocument doc;
bool ok = readJson(data, doc);
if (ok)
{
array = doc.array();
}
return ok;
return true;
}
static bool readJson(const QByteArray &data, QJsonArray &array)
{
QJsonDocument doc;
bool ok = readJson(data, doc);
if (ok) {
array = doc.array();
}
static bool readJson(const QByteArray &data, QJsonObject &object)
{
QJsonDocument doc;
bool ok = readJson(data, doc);
if (ok)
{
object = doc.object();
}
return ok;
return ok;
}
static bool readJson(const QByteArray &data, QJsonObject &object)
{
QJsonDocument doc;
bool ok = readJson(data, doc);
if (ok) {
object = doc.object();
}
return ok;
}
static bool readJsonFile(const QString &filePath, QJsonDocument &jsonDoc)
{
QByteArray data;
if (!readFile(filePath, data))
{
return false;
}
return readJson(data, jsonDoc);
static bool readJsonFile(const QString &filePath, QJsonDocument &jsonDoc)
{
QByteArray data;
if (!readFile(filePath, data)) {
return false;
}
static bool readJsonFile(const QString &filePath, QJsonObject &jsonObj)
{
QByteArray data;
if (!readFile(filePath, data))
{
return false;
}
return readJson(data, jsonObj);
return readJson(data, jsonDoc);
}
static bool readJsonFile(const QString &filePath, QJsonObject &jsonObj)
{
QByteArray data;
if (!readFile(filePath, data)) {
return false;
}
static bool readJsonFile(const QString &filePath, QJsonArray &jsonArray)
{
QByteArray data;
if (!readFile(filePath, data))
{
return false;
}
return readJson(data, jsonArray);
return readJson(data, jsonObj);
}
static bool readJsonFile(const QString &filePath, QJsonArray &jsonArray)
{
QByteArray data;
if (!readFile(filePath, data)) {
return false;
}
static bool writeFile(const QString &filePath, const QByteArray &content)
{
QFile file(filePath);
if (!file.open(QFile::WriteOnly))
{
LOG_WARN << "open file " << filePath << "failed:" << file.errorString();
return false;
}
file.write(content);
file.close();
return true;
}
static bool writeJsonFile(const QString &filePath, const QJsonDocument &doc)
{
return writeFile(filePath, doc.toJson());
}
static bool writeJsonFile(const QString &filePath, const QJsonArray &jsonArray)
{
return writeJsonFile(filePath, QJsonDocument(jsonArray));
}
static bool writeJsonFile(const QString &filePath, const QJsonObject &jsonObj)
{
return writeJsonFile(filePath, QJsonDocument(jsonObj));
return readJson(data, jsonArray);
}
static bool writeFile(const QString &filePath, const QByteArray &content)
{
QFile file(filePath);
if (!file.open(QFile::WriteOnly)) {
LOG_WARN << "open file " << filePath << "failed:" << file.errorString();
return false;
}
file.write(content);
file.close();
return true;
}
static bool writeJsonFile(const QString &filePath, const QJsonDocument &doc)
{
return writeFile(filePath, doc.toJson());
}
static bool writeJsonFile(const QString &filePath, const QJsonArray &jsonArray)
{
return writeJsonFile(filePath, QJsonDocument(jsonArray));
}
static bool writeJsonFile(const QString &filePath, const QJsonObject &jsonObj)
{
return writeJsonFile(filePath, QJsonDocument(jsonObj));
}
} // namespace TaoCommon

View File

@ -9,22 +9,14 @@
namespace TaoCommon {
//对象存储器
template <typename Key, typename Value>
class ObjectMap {
template<typename Key, typename Value>
class ObjectMap
{
public:
virtual ~ObjectMap()
{
clear();
}
void addObj(const Key& key, const Value& obj)
{
m_objMap[key] = obj;
}
bool removeObj(const Key& key)
{
return (0 != m_objMap.erase(key));
}
Value getObj(const Key& key) const
virtual ~ObjectMap() { clear(); }
void addObj(const Key &key, const Value &obj) { m_objMap[key] = obj; }
bool removeObj(const Key &key) { return (0 != m_objMap.erase(key)); }
Value getObj(const Key &key) const
{
auto itor = m_objMap.find(key);
if (itor == m_objMap.end()) {
@ -34,79 +26,75 @@ public:
}
}
template<class CallbackType>
void forEach(const CallbackType& callback) const
void forEach(const CallbackType &callback) const
{
for (const auto& pair : m_objMap) {
for (const auto &pair : m_objMap) {
callback(pair.second.get());
}
}
void clear()
{
m_objMap.clear();
}
void clear() { m_objMap.clear(); }
protected:
std::unordered_map<Key, Value> m_objMap;
};
//智能对象存储器。自动生成key自动管理对象。
template <typename ObjectType>
class CObjectMap {
template<typename ObjectType>
class CObjectMap
{
public:
virtual ~CObjectMap()
virtual ~CObjectMap() { clear(); }
template<typename DeriveObjectType>
DeriveObjectType *getObject() const
{
clear();
}
template <typename DeriveObjectType>
DeriveObjectType* getObject() const
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
auto objPtr = m_objMap.getObj(std::type_index(typeid(std::shared_ptr<DeriveObjectType>)));
return std::static_pointer_cast<DeriveObjectType>(objPtr).get();
}
template <typename DeriveObjectType, typename... Args>
void createObject(Args&... args)
template<typename DeriveObjectType, typename... Args>
void createObject(Args &... args)
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
auto obj = std::make_shared<DeriveObjectType>(args...);
m_objMap.addObj(std::type_index(typeid(obj)), std::static_pointer_cast<ObjectType>(obj));
}
template <typename DeriveObjectType>
template<typename DeriveObjectType>
bool destroyObject()
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
return m_objMap.removeObj(std::type_index(typeid(std::shared_ptr<DeriveObjectType>)));
}
void forEach(const std::function<void(ObjectType*)>& callback) const
void forEach(const std::function<void(ObjectType *)> &callback) const
{
m_objMap.forEach(callback);
}
void clear()
{
m_objMap.clear();
}
void clear() { m_objMap.clear(); }
protected:
ObjectMap<std::type_index, std::shared_ptr<ObjectType>> m_objMap;
};
//优先级对象存储器。自动生成key自动管理对象。支持按优先级处理
template <typename ObjectType>
class CLevelObjectMap {
template<typename ObjectType>
class CLevelObjectMap
{
public:
virtual ~CLevelObjectMap()
virtual ~CLevelObjectMap() { clear(); }
template<typename DeriveObjectType>
DeriveObjectType *getObject() const
{
clear();
}
template <typename DeriveObjectType>
DeriveObjectType* getObject() const
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
auto index = std::type_index(typeid(std::shared_ptr<DeriveObjectType>));
for (const auto& mainPair : m_map) {
const std::unordered_map<std::type_index, std::shared_ptr<ObjectType>>& subMap = mainPair.second;
for (const auto &mainPair : m_map) {
const std::unordered_map<std::type_index, std::shared_ptr<ObjectType>> &subMap =
mainPair.second;
auto itor = subMap.find(index);
if (itor != subMap.end()) {
@ -115,22 +103,25 @@ public:
}
return nullptr;
}
template <typename DeriveObjectType, typename... Args>
void createObject(uint32_t level, Args&&... args)
template<typename DeriveObjectType, typename... Args>
void createObject(uint32_t level, Args &&... args)
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
auto obj = std::make_shared<DeriveObjectType>(args...);
m_map[level][std::type_index(typeid(obj))] = std::static_pointer_cast<ObjectType>(obj);
}
template <typename DeriveObjectType>
template<typename DeriveObjectType>
bool destroyObject()
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value, "DeriveObjectType must be derive from ObjectType");
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
auto index = std::type_index(typeid(std::shared_ptr<DeriveObjectType>));
for (auto& mainPair : m_map) {
std::unordered_map<std::type_index, std::shared_ptr<ObjectType>>& subMap = mainPair.second;
for (auto &mainPair : m_map) {
std::unordered_map<std::type_index, std::shared_ptr<ObjectType>> &subMap =
mainPair.second;
auto itor = subMap.find(index);
if (itor != subMap.end()) {
@ -140,19 +131,17 @@ public:
}
return false;
}
void forEach(const std::function<void(ObjectType*)>& callback) const
void forEach(const std::function<void(ObjectType *)> &callback) const
{
for (const auto& mainPair : m_map) {
const std::unordered_map<std::type_index, std::shared_ptr<ObjectType>>& subMap = mainPair.second;
for (const auto& subPair : subMap) {
for (const auto &mainPair : m_map) {
const std::unordered_map<std::type_index, std::shared_ptr<ObjectType>> &subMap =
mainPair.second;
for (const auto &subPair : subMap) {
callback(subPair.second.get());
}
}
}
void clear()
{
m_map.clear();
}
void clear() { m_map.clear(); }
private:
std::map<uint32_t, std::unordered_map<std::type_index, std::shared_ptr<ObjectType>>> m_map;

View File

@ -1,8 +1,8 @@
#pragma once
#pragma once
#include <QByteArray>
#include <QByteArrayList>
#include <QDataStream>
#include <QIODevice>
const int static headerLength = sizeof(quint32);
static QByteArray pack(const QByteArray &data)
@ -19,12 +19,10 @@ static QByteArrayList unpack(const QByteArray &data)
quint32 sum = data.size();
quint32 pos = 0;
quint32 packageLen = 0;
while (pos + headerLength < sum)
{
while (pos + headerLength < sum) {
packageLen = 0;
inStream >> packageLen;
if (packageLen <= 0 || packageLen + headerLength > sum - pos)
{
if (packageLen <= 0 || packageLen + headerLength > sum - pos) {
break;
}
QByteArray subPackage = data.mid(pos + headerLength, packageLen);

View File

@ -2,115 +2,97 @@
#include <algorithm>
#include <map>
#include <vector>
namespace TaoCommon
namespace TaoCommon {
//观察者模式Subject-Observer。
// Subject 事件或消息的主体。模板参数为观察者类型
template<typename ObserverType>
class Subject
{
//观察者模式Subject-Observer。
//Subject 事件或消息的主体。模板参数为观察者类型
template <typename ObserverType>
class Subject
public:
virtual ~Subject() { m_obsList.clear(); }
//订阅
void subscibe(ObserverType *obs)
{
public:
virtual ~Subject()
{
m_obsList.clear();
auto itor = std::find(m_obsList.begin(), m_obsList.end(), obs);
if (m_obsList.end() == itor) {
m_obsList.push_back(obs);
}
//订阅
void subscibe(ObserverType *obs)
{
auto itor = std::find(m_obsList.begin(), m_obsList.end(), obs);
if (m_obsList.end() == itor)
{
m_obsList.push_back(obs);
}
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
m_obsList.erase(std::remove(m_obsList.begin(), m_obsList.end(), obs));
}
//发布。这里的模板参数为函数类型。
template<typename FuncType>
void publish(FuncType func)
{
for (auto obs : m_obsList) {
//调用回调函数将obs作为第一个参数传递
func(obs);
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
m_obsList.erase(std::remove(m_obsList.begin(), m_obsList.end(), obs));
}
//发布。这里的模板参数为函数类型。
template <typename FuncType>
void publish(FuncType func)
{
for (auto obs : m_obsList)
{
//调用回调函数将obs作为第一个参数传递
}
//发布。支持过滤观察者。通常用在 观察者触发消息发布时,过滤观察者自己。
template<typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (auto obs : m_obsList) {
//调用回调函数将obs作为第一个参数传递
if (obs != exceptObs) {
func(obs);
}
}
//发布。支持过滤观察者。通常用在 观察者触发消息发布时,过滤观察者自己。
template <typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (auto obs : m_obsList)
{
//调用回调函数将obs作为第一个参数传递
if (obs != exceptObs)
{
func(obs);
}
}
}
}
private:
std::vector<ObserverType *> m_obsList;
};
private:
std::vector<ObserverType *> m_obsList;
};
//优先级观察者模式Subject-Observer。
template <typename ObserverType>
class LevelSubject
//优先级观察者模式Subject-Observer。
template<typename ObserverType>
class LevelSubject
{
public:
virtual ~LevelSubject() { m_obsMap.clear(); }
//订阅
void subscibe(ObserverType *obs, uint32_t level)
{
public:
virtual ~LevelSubject()
{
m_obsMap.clear();
auto &vec = m_obsMap[level];
auto itor = std::find(vec.begin(), vec.end(), obs);
if (vec.end() == itor) {
vec.push_back(obs);
}
//订阅
void subscibe(ObserverType *obs, uint32_t level)
{
auto &vec = m_obsMap[level];
auto itor = std::find(vec.begin(), vec.end(), obs);
if (vec.end() == itor)
{
vec.push_back(obs);
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
for (auto &obsPair : m_obsMap) {
obsPair.second.erase(std::remove(obsPair.second.begin(), obsPair.second.end(), obs));
}
}
//发布。这里的模板参数为函数类型。
template<typename FuncType>
void publish(FuncType func)
{
for (const auto &obsPair : m_obsMap) {
for (const auto &obs : obsPair.second) {
func(obs);
}
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
for (auto &obsPair : m_obsMap)
{
obsPair.second.erase(std::remove(obsPair.second.begin(), obsPair.second.end(), obs));
}
}
//发布。这里的模板参数为函数类型。
template <typename FuncType>
void publish(FuncType func)
{
for (const auto &obsPair : m_obsMap)
{
for (const auto &obs : obsPair.second)
{
}
template<typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (const auto &obsPair : m_obsMap) {
for (const auto &obs : obsPair.second) {
if (obs != exceptObs) {
func(obs);
}
}
}
template <typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (const auto &obsPair : m_obsMap)
{
for (const auto &obs : obsPair.second)
{
if (obs != exceptObs)
{
func(obs);
}
}
}
}
}
private:
std::map<uint32_t, std::vector<ObserverType *>> m_obsMap;
};
private:
std::map<uint32_t, std::vector<ObserverType *>> m_obsMap;
};
} // namespace TaoCommon

View File

@ -6,13 +6,14 @@
#include <QWindow>
#if WIN32
#include <WinUser.h>
#include <dwmapi.h>
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
#include <windows.h>
#include <windowsx.h>
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved external symbol __imp__DwmExtendFrameIntoClientArea
#pragma comment(lib, "user32.lib")
# include <WinUser.h>
# include <dwmapi.h>
# include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
# include <windows.h>
# include <windowsx.h>
# pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved
// external symbol __imp__DwmExtendFrameIntoClientArea
# pragma comment(lib, "user32.lib")
#endif
@ -20,13 +21,17 @@
static long hitTest(RECT winrect, long x, long y, int borderWidth)
{
// 鼠标区域位于窗体边框,进行缩放
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth)) {
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top)
&& (y < winrect.top + borderWidth)) {
return HTTOPLEFT;
} else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth) {
} else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top
&& y < winrect.top + borderWidth) {
return HTTOPRIGHT;
} else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth) {
} else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom
&& y >= winrect.bottom - borderWidth) {
return HTBOTTOMLEFT;
} else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth) {
} else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom
&& y >= winrect.bottom - borderWidth) {
return HTBOTTOMRIGHT;
} else if (x >= winrect.left && x < winrect.left + borderWidth) {
return HTLEFT;
@ -51,16 +56,13 @@ static bool isFullWin(QQuickView *win)
return win->windowState() == Qt::WindowFullScreen;
}
TaoFrameLessView::TaoFrameLessView(QWindow *parent)
: QQuickView(parent)
TaoFrameLessView::TaoFrameLessView(QWindow *parent) : QQuickView(parent)
{
setFlags(/*Qt::CustomizeWindowHint | */Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeViewToRootObject);
setColor(QColor(Qt::transparent));
setMinimumSize({1024, 720});
resize(1440, 960);
setFlags(/*Qt::CustomizeWindowHint | */ Qt::Window | Qt::FramelessWindowHint
| Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeRootObjectToView);
//WS_THICKFRAME 带回Areo效果
// WS_THICKFRAME 带回Areo效果
#if WIN32
DWORD style = ::GetWindowLong(HWND(winId()), GWL_STYLE);
style |= WS_THICKFRAME;
@ -68,7 +70,8 @@ TaoFrameLessView::TaoFrameLessView(QWindow *parent)
#endif
setIsMax(isMaxWin(this));
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) { setIsMax(state == Qt::WindowMaximized); });
connect(this, &QWindow::windowStateChanged, this,
[&](Qt::WindowState state) { setIsMax(state == Qt::WindowMaximized); });
}
TaoFrameLessView::~TaoFrameLessView() {}
@ -79,9 +82,9 @@ void TaoFrameLessView::setTitleItem(QQuickItem *item)
void TaoFrameLessView::moveToScreenCenter()
{
auto geo = screen()->availableGeometry();
int w = width();
int h = height();
auto pos = QPoint{ geo.x() + (geo.width() - w) / 2, geo.y() + (geo.height() - h) / 2 };
int w = width();
int h = height();
auto pos = QPoint { geo.x() + (geo.width() - w) / 2, geo.y() + (geo.height() - h) / 2 };
setPosition(pos.x(), pos.y());
update();
}
@ -97,11 +100,11 @@ void TaoFrameLessView::setIsMax(bool isMax)
#if WIN32
const long border_width = 6;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool TaoView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
# else
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
#endif
# endif
{
if (!result) {
return false;
@ -111,56 +114,56 @@ bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, l
return false;
}
switch (msg->message) {
case WM_NCCALCSIZE: {
const auto mode = static_cast<BOOL>(msg->wParam);
*result = mode ? WVR_REDRAW : 0;
case WM_NCCALCSIZE: {
const auto mode = static_cast<BOOL>(msg->wParam);
*result = mode ? WVR_REDRAW : 0;
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
//规避 拖动border进行resize时界面闪烁
if (!isMaxWin(this) && !isFullWin(this)) {
if (clientRect->top != 0)
{
clientRect->top -= 1;
}
} else {
if (clientRect->top != 0)
{
clientRect->top += 1;
}
const auto clientRect = mode
? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0])
: reinterpret_cast<LPRECT>(msg->lParam);
//规避 拖动border进行resize时界面闪烁
if (!isMaxWin(this) && !isFullWin(this)) {
if (clientRect->top != 0) {
clientRect->top -= 1;
}
} else {
if (clientRect->top != 0) {
clientRect->top += 1;
}
return true;
}
case WM_NCHITTEST: {
*result = 0;
return true;
}
case WM_NCHITTEST: {
*result = 0;
RECT winrect;
GetWindowRect(HWND(winId()), &winrect);
RECT winrect;
GetWindowRect(HWND(winId()), &winrect);
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
*result = 0;
if (!isMaxWin(this) && !isFullWin(this)) { //非最大化、非全屏时,进行命中测试,处理边框拖拽
*result = hitTest(winrect, x, y, border_width);
if (0 != *result) {
return true;
}
*result = 0;
if (!isMaxWin(this) && !isFullWin(this)) { //非最大化、非全屏时,进行命中测试,处理边框拖拽
*result = hitTest(winrect, x, y, border_width);
if (0 != *result) {
return true;
}
}
if (m_titleItem)
{
auto titlePos = m_titleItem->mapToGlobal(m_titleItem->position());
titlePos = mapFromGlobal(titlePos.toPoint());
auto titleRect = QRect(titlePos.x(), titlePos.y(), m_titleItem->width(), m_titleItem->height());
double dpr = qApp->devicePixelRatio();
QPoint pos = mapFromGlobal(QPoint(x / dpr, y / dpr));
if (titleRect.contains(pos)) {
*result = HTCAPTION;
return true;
}
if (m_titleItem) {
auto titlePos = m_titleItem->mapToGlobal(m_titleItem->position());
titlePos = mapFromGlobal(titlePos.toPoint());
auto titleRect =
QRect(titlePos.x(), titlePos.y(), m_titleItem->width(), m_titleItem->height());
double dpr = qApp->devicePixelRatio();
QPoint pos = mapFromGlobal(QPoint(x / dpr, y / dpr));
if (titleRect.contains(pos)) {
*result = HTCAPTION;
return true;
}
return false;
} //end case WM_NCHITTEST
}
return false;
} // end case WM_NCHITTEST
}
return QQuickView::nativeEvent(eventType, message, result);
}

View File

@ -11,14 +11,8 @@ public:
explicit TaoFrameLessView(QWindow *parent = nullptr);
~TaoFrameLessView();
void moveToScreenCenter();
bool isMax() const
{
return m_isMax;
}
QQuickItem *titleItem() const
{
return m_titleItem;
}
bool isMax() const { return m_isMax; }
QQuickItem *titleItem() const { return m_titleItem; }
public slots:
void setIsMax(bool isMax);
void setTitleItem(QQuickItem *item);
@ -26,16 +20,14 @@ signals:
void isMaxChanged(bool isMax);
protected:
#if WIN32
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
#else
# else
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
#endif
# endif
#endif
private:
bool m_isMax;
QQuickItem *m_titleItem = nullptr;
};

View File

@ -10,144 +10,135 @@
#include <string>
#ifdef Q_OS_WIN
#include <Windows.h>
# include <Windows.h>
#else
#include <cstdio>
# include <cstdio>
#endif
namespace Logger
namespace Logger {
static QString gLogDir;
static int gLogMaxCount;
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context,
const QString &msg);
void initLog(const QString &logPath, int logMaxCount, bool async)
{
static QString gLogDir;
static int gLogMaxCount;
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void outputMessageAsync(QtMsgType type, const QMessageLogContext& context, const QString& msg);
void initLog(const QString &logPath, int logMaxCount, bool async)
{
if (async)
{
qInstallMessageHandler(outputMessageAsync);
}
else
{
qInstallMessageHandler(outputMessage);
}
gLogDir = QCoreApplication::applicationDirPath() + QStringLiteral("/") + logPath;
gLogMaxCount = logMaxCount;
QDir dir(gLogDir);
if (!dir.exists())
{
dir.mkpath(dir.absolutePath());
}
QStringList infoList = dir.entryList(QDir::Files, QDir::Name);
while (infoList.size() > gLogMaxCount)
{
dir.remove(infoList.first());
infoList.removeFirst();
}
if (async) {
qInstallMessageHandler(outputMessageAsync);
} else {
qInstallMessageHandler(outputMessage);
}
static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
static const QString messageTemp = QStringLiteral("<div class=\"%1\">%2</div>\r\n");
static const char typeList[] = { 'd', 'w', 'c', 'f', 'i' };
static QMutex mutex;
static QFile file;
static QTextStream textStream;
static uint count = 0;
static const uint maxCount = 512;
Q_UNUSED(context)
QDateTime dt = QDateTime::currentDateTime();
//每小时一个文件
QString fileNameDt = dt.toString(QStringLiteral("yyyy-MM-dd_hh"));
gLogDir = QCoreApplication::applicationDirPath() + QStringLiteral("/") + logPath;
gLogMaxCount = logMaxCount;
QDir dir(gLogDir);
if (!dir.exists()) {
dir.mkpath(dir.absolutePath());
}
QStringList infoList = dir.entryList(QDir::Files, QDir::Name);
while (infoList.size() > gLogMaxCount) {
dir.remove(infoList.first());
infoList.removeFirst();
}
}
static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context,
const QString &msg)
{
static const QString messageTemp = QStringLiteral("<div class=\"%1\">%2</div>\r\n");
static const char typeList[] = { 'd', 'w', 'c', 'f', 'i' };
static QMutex mutex;
static QFile file;
static QTextStream textStream;
static uint count = 0;
static const uint maxCount = 512;
Q_UNUSED(context)
QDateTime dt = QDateTime::currentDateTime();
//每分钟一个文件
//QString fileNameDt = dt.toString("yyyy-MM-dd_hh_mm");
//每小时一个文件
QString fileNameDt = dt.toString(QStringLiteral("yyyy-MM-dd_hh"));
QString contentDt = dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"));
QString message = QStringLiteral("%1 %2").arg(contentDt).arg(msg);
QString htmlMessage = messageTemp.arg(typeList[static_cast<int>(type)]).arg(message);
QString newfileName = QStringLiteral("%1/%2_log.html").arg(gLogDir).arg(fileNameDt);
mutex.lock();
if (file.fileName() != newfileName)
{
if (file.isOpen())
{
file.close();
}
file.setFileName(newfileName);
bool exist = file.exists();
file.open(QIODevice::WriteOnly | QIODevice::Append);
textStream.setDevice(&file);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
textStream.setEncoding(QStringConverter::Utf8);
#else
textStream.setCodec("UTF-8");
#endif
if (!exist)
{
textStream << logTemplate << "\r\n";
}
}
textStream << htmlMessage;
textStream.flush();
count += htmlMessage.length();
if (count >= maxCount)
{
//每分钟一个文件
// QString fileNameDt = dt.toString("yyyy-MM-dd_hh_mm");
QString contentDt = dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"));
QString message = QStringLiteral("%1 %2").arg(contentDt).arg(msg);
QString htmlMessage = messageTemp.arg(typeList[static_cast<int>(type)]).arg(message);
QString newfileName = QStringLiteral("%1/%2_log.html").arg(gLogDir).arg(fileNameDt);
mutex.lock();
if (file.fileName() != newfileName) {
if (file.isOpen()) {
file.close();
file.open(QIODevice::WriteOnly | QIODevice::Append);
}
mutex.unlock();
#ifdef Q_OS_WIN
::OutputDebugString(message.toStdWString().data());
::OutputDebugString(L"\r\n");
#else
fprintf(stderr, message.toStdString().data());
#endif
}
static void outputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
static const QString messageTemp = QStringLiteral("<div class=\"%1\">%2</div>\r\n");
static const char typeList[] = { 'd', 'w', 'c', 'f', 'i' };
static QMutex mutex;
Q_UNUSED(context)
QDateTime dt = QDateTime::currentDateTime();
//每小时一个文件
QString fileNameDt = dt.toString(QStringLiteral("yyyy-MM-dd_hh"));
//每分钟一个文件
//QString fileNameDt = dt.toString("yyyy-MM-dd_hh_mm");
QString contentDt = dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"));
QString message = QStringLiteral("%1 %2").arg(contentDt).arg(msg);
QString htmlMessage = messageTemp.arg(typeList[static_cast<int>(type)]).arg(message);
QFile file(QStringLiteral("%1/%2_log.html").arg(gLogDir).arg(fileNameDt));
mutex.lock();
file.setFileName(newfileName);
bool exist = file.exists();
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream textStream(&file);
textStream.setDevice(&file);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
textStream.setEncoding(QStringConverter::Utf8);
#else
textStream.setCodec("UTF-8");
#endif
if (!exist)
{
if (!exist) {
textStream << logTemplate << "\r\n";
}
textStream << htmlMessage;
file.close();
mutex.unlock();
#ifdef Q_OS_WIN
::OutputDebugString(message.toStdWString().data());
::OutputDebugString(L"\r\n");
#else
fprintf(stderr, message.toStdString().data());
#endif
}
textStream << htmlMessage;
textStream.flush();
count += htmlMessage.length();
if (count >= maxCount) {
file.close();
file.open(QIODevice::WriteOnly | QIODevice::Append);
}
mutex.unlock();
#ifdef Q_OS_WIN
::OutputDebugString(message.toStdWString().data());
::OutputDebugString(L"\r\n");
#else
fprintf(stderr, message.toStdString().data());
#endif
}
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
static const QString messageTemp = QStringLiteral("<div class=\"%1\">%2</div>\r\n");
static const char typeList[] = { 'd', 'w', 'c', 'f', 'i' };
static QMutex mutex;
Q_UNUSED(context)
QDateTime dt = QDateTime::currentDateTime();
//每小时一个文件
QString fileNameDt = dt.toString(QStringLiteral("yyyy-MM-dd_hh"));
//每分钟一个文件
// QString fileNameDt = dt.toString("yyyy-MM-dd_hh_mm");
QString contentDt = dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"));
QString message = QStringLiteral("%1 %2").arg(contentDt).arg(msg);
QString htmlMessage = messageTemp.arg(typeList[static_cast<int>(type)]).arg(message);
QFile file(QStringLiteral("%1/%2_log.html").arg(gLogDir).arg(fileNameDt));
mutex.lock();
bool exist = file.exists();
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream textStream(&file);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
textStream.setEncoding(QStringConverter::Utf8);
#else
textStream.setCodec("UTF-8");
#endif
if (!exist) {
textStream << logTemplate << "\r\n";
}
textStream << htmlMessage;
file.close();
mutex.unlock();
#ifdef Q_OS_WIN
::OutputDebugString(message.toStdWString().data());
::OutputDebugString(L"\r\n");
#else
fprintf(stderr, message.toStdString().data());
#endif
}
} // namespace Logger

View File

@ -2,22 +2,22 @@
#include "taocommonglobal.h"
#include <QString>
#include <QDebug>
namespace Logger
{
namespace Logger {
#ifdef _DEBUG
#define LOG_DEBUG qDebug() << __FILE__ << __LINE__
#define LOG_INFO qInfo() << __FILE__ << __LINE__
#define LOG_WARN qWarning() << __FILE__ << __LINE__
#define LOG_CRIT qCritical() << __FILE__ << __LINE__
# define LOG_DEBUG qDebug() << __FILE__ << __LINE__
# define LOG_INFO qInfo() << __FILE__ << __LINE__
# define LOG_WARN qWarning() << __FILE__ << __LINE__
# define LOG_CRIT qCritical() << __FILE__ << __LINE__
#else
#define LOG_DEBUG qDebug()
#define LOG_INFO qInfo()
#define LOG_WARN qWarning()
#define LOG_CRIT qCritical()
# define LOG_DEBUG qDebug()
# define LOG_INFO qInfo()
# define LOG_WARN qWarning()
# define LOG_CRIT qCritical()
#endif
// 初始化Log存储。包括创建Log文件夹、删除超过最大数的log仅初始化时删除运行过程中不删除
// logPath 存储路径
// logMaxCount 最大数
// async 是否异步存储 默认异步存储。异步存储会缓存log达到一定数量、或者软件退出时才写入文件。
void TAO_API initLog(const QString &logPath = QStringLiteral("Log"), int logMaxCount = 1024, bool async = true);
// 初始化Log存储。包括创建Log文件夹、删除超过最大数的log仅初始化时删除运行过程中不删除
// logPath 存储路径
// logMaxCount 最大数
// async 是否异步存储 默认异步存储。异步存储会缓存log达到一定数量、或者软件退出时才写入文件。
void TAO_API initLog(const QString &logPath = QStringLiteral("Log"), int logMaxCount = 1024,
bool async = true);
} // namespace Logger

View File

@ -1,9 +1,8 @@
#pragma once
#pragma once
#include <QString>
#include <string>
namespace Logger
{
const static auto logTemplate = QString::fromUtf8(u8R"logTemplate(
namespace Logger {
const static auto logTemplate = QString::fromUtf8(u8R"logTemplate(
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>

View File

@ -1,10 +1,9 @@
#pragma once
#include <QMetaType>
#include <functional>
namespace TaoCommon
{
using WorkCallback = std::function<bool()>;
using WorkResultCallback = std::function<void(bool)>;
namespace TaoCommon {
using WorkCallback = std::function<bool()>;
using WorkResultCallback = std::function<void(bool)>;
}
Q_DECLARE_METATYPE(TaoCommon::WorkCallback);
Q_DECLARE_METATYPE(TaoCommon::WorkResultCallback);

View File

@ -1,22 +1,19 @@
#include "threadpool.h"
#include <QThreadPool>
namespace TaoCommon
namespace TaoCommon {
ThreadObject::ThreadObject(const WorkCallback &work) : m_workCall(work) {}
void ThreadObject::run()
{
ThreadObject::ThreadObject(const WorkCallback& work) : m_workCall(work) {}
void ThreadObject::run()
{
bool ok = m_workCall();
emit readyResult(ok);
}
//workCall in sub thread, resultCall in main thread
void ThreadPool::work(const WorkCallback& workCall, const WorkResultCallback& resultCall)
{
ThreadObject* obj = new ThreadObject(workCall);
obj->setAutoDelete(true);
connect(obj, &ThreadObject::readyResult, this, resultCall);
QThreadPool::globalInstance()->start(obj);
}
bool ok = m_workCall();
emit readyResult(ok);
}
// workCall in sub thread, resultCall in main thread
void ThreadPool::work(const WorkCallback &workCall, const WorkResultCallback &resultCall)
{
ThreadObject *obj = new ThreadObject(workCall);
obj->setAutoDelete(true);
connect(obj, &ThreadObject::readyResult, this, resultCall);
QThreadPool::globalInstance()->start(obj);
}
}

View File

@ -1,41 +1,39 @@
#pragma once
#pragma once
#include "taocommonglobal.h"
#include "threadcommon.h"
#include <QObject>
#include <QRunnable>
namespace TaoCommon
namespace TaoCommon {
// 对Qt线程池的简单封装适合一次性执行的任务。
// 用法: ThreadPool::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
// 不支持任务取消、暂停。
class ThreadObject : public QObject, public QRunnable
{
// 对Qt线程池的简单封装适合一次性执行的任务。
// 用法: ThreadPool::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
// 不支持任务取消、暂停。
Q_OBJECT
public:
explicit ThreadObject(const WorkCallback &work);
void run() override;
signals:
void readyResult(bool);
class ThreadObject
: public QObject
, public QRunnable
private:
WorkCallback m_workCall;
};
class TAO_API ThreadPool : public QObject
{
Q_OBJECT
public:
static ThreadPool *getInstance()
{
Q_OBJECT
public:
explicit ThreadObject(const WorkCallback& work);
void run() override;
signals:
void readyResult(bool);
static ThreadPool poll;
return &poll;
}
// workCall in sub thread, resultCall in main thread
void work(const WorkCallback &workCall, const WorkResultCallback &resultCall);
private:
WorkCallback m_workCall;
};
class TAO_API ThreadPool : public QObject
{
Q_OBJECT
public:
static ThreadPool* getInstance()
{
static ThreadPool poll;
return &poll;
}
//workCall in sub thread, resultCall in main thread
void work(const WorkCallback& workCall, const WorkResultCallback& resultCall);
private:
ThreadPool() {}
};
private:
ThreadPool() {}
};
} // namespace TaoCommon

View File

@ -1,129 +1,122 @@
#pragma once
#pragma once
#include "taocommonglobal.h"
#include "threadcommon.h"
#include <QMap>
#include <QThread>
namespace TaoCommon
namespace TaoCommon {
// 对Qt Worker-Controller 线程模型的简单封装,适合精确控制的任务。
// 用法: ThreadController::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
// work函数返回值为任务id。
// 取消任务用ThreadController::getInstance()->cancle(id)函数。
class ThreadWorker : public QObject
{
// 对Qt Worker-Controller 线程模型的简单封装,适合精确控制的任务。
// 用法: ThreadController::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
// work函数返回值为任务id。
// 取消任务用ThreadController::getInstance()->cancle(id)函数。
class ThreadWorker : public QObject
Q_OBJECT
public:
ThreadWorker(uint64_t id, const WorkCallback &workCall, QObject *parent = nullptr)
: QObject(parent), m_id(id), m_workCall(workCall)
{
Q_OBJECT
public:
ThreadWorker(uint64_t id, const WorkCallback &workCall, QObject *parent = nullptr) : QObject(parent), m_id(id), m_workCall(workCall) {}
}
signals:
void workFinished(bool, uint64_t);
public slots:
void doWork()
{
bool ret = m_workCall();
emit workFinished(ret, m_id);
}
private:
const uint64_t m_id;
WorkCallback m_workCall;
};
class TAO_API ThreadController : public QObject
signals:
void workFinished(bool, uint64_t);
public slots:
void doWork()
{
Q_OBJECT
public:
static ThreadController *getInstance()
{
static ThreadController controller;
return &controller;
}
bool ret = m_workCall();
emit workFinished(ret, m_id);
}
~ThreadController()
{
for (auto k : m_threadMap.uniqueKeys())
{
if (m_threadMap.value(k)->isRunning())
{
m_threadMap.value(k)->quit();
m_threadMap.value(k)->wait();
}
}
qDeleteAll(m_threadMap);
m_threadMap.clear();
m_resultCallback.clear();
}
uint64_t work(const WorkCallback &workCall, const WorkResultCallback &resultCall)
{
QThread *thread = new QThread;
m_rollId++;
ThreadWorker *obj = new ThreadWorker(m_rollId, workCall);
m_threadMap[m_rollId] = thread;
m_resultCallback[m_rollId] = resultCall;
obj->moveToThread(thread);
private:
const uint64_t m_id;
WorkCallback m_workCall;
};
class TAO_API ThreadController : public QObject
{
Q_OBJECT
public:
static ThreadController *getInstance()
{
static ThreadController controller;
return &controller;
}
connect(thread, &QThread::finished, obj, &QObject::deleteLater);
connect(thread, &QThread::started, obj, &ThreadWorker::doWork);
connect(obj, &ThreadWorker::workFinished, this, &ThreadController::onWorkFinished, Qt::QueuedConnection);
thread->start();
return m_rollId;
}
void cancle(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->terminate();
}
~ThreadController()
{
for (const auto &k : m_threadMap.keys()) {
if (m_threadMap.value(k)->isRunning()) {
m_threadMap.value(k)->quit();
m_threadMap.value(k)->wait();
}
}
qDeleteAll(m_threadMap);
m_threadMap.clear();
m_resultCallback.clear();
}
uint64_t work(const WorkCallback &workCall, const WorkResultCallback &resultCall)
{
QThread *thread = new QThread;
m_rollId++;
ThreadWorker *obj = new ThreadWorker(m_rollId, workCall);
m_threadMap[m_rollId] = thread;
m_resultCallback[m_rollId] = resultCall;
obj->moveToThread(thread);
connect(thread, &QThread::finished, obj, &QObject::deleteLater);
connect(thread, &QThread::started, obj, &ThreadWorker::doWork);
connect(obj, &ThreadWorker::workFinished, this, &ThreadController::onWorkFinished,
Qt::QueuedConnection);
thread->start();
return m_rollId;
}
void cancle(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end()) {
if ((*it)->isRunning()) {
(*it)->terminate();
}
}
m_resultCallback.remove(id);
}
void quit(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end()) {
if ((*it)->isRunning()) {
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
}
m_resultCallback.remove(id);
}
QList<uint64_t> getAllWorkId() const { return m_threadMap.keys(); }
protected slots:
void onWorkFinished(bool ok, uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end()) {
if ((*it)->isRunning()) {
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
m_threadMap.remove(id);
}
auto caller = m_resultCallback.find(id);
if (caller != m_resultCallback.end()) {
(*caller)(ok);
m_resultCallback.remove(id);
}
void quit(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
}
m_resultCallback.remove(id);
}
QList<uint64_t> getAllWorkId() const
{
return m_threadMap.uniqueKeys();
}
protected slots :
void onWorkFinished(bool ok, uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
m_threadMap.remove(id);
}
auto caller = m_resultCallback.find(id);
if (caller != m_resultCallback.end())
{
(*caller)(ok);
m_resultCallback.remove(id);
}
}
protected:
ThreadController(QObject *parent = nullptr) : QObject(parent) {}
}
private:
uint64_t m_rollId = 0;
QMap<uint64_t, QThread *> m_threadMap;
QMap<uint64_t, WorkResultCallback> m_resultCallback;
};
protected:
ThreadController(QObject *parent = nullptr) : QObject(parent) {}
private:
uint64_t m_rollId = 0;
QMap<uint64_t, QThread *> m_threadMap;
QMap<uint64_t, WorkResultCallback> m_resultCallback;
};
} // namespace LCIM

View File

@ -8,12 +8,9 @@
#include <QQmlEngine>
const static auto cEnglisthStr = QStringLiteral("English");
const static auto cChineseStr = QStringLiteral("简体中文");
Trans::Trans(QObject* parent)
: QTranslator(parent)
{
}
Trans::Trans(QObject *parent) : QTranslator(parent) {}
void Trans::beforeUiReady(QQmlContext* ctx)
void Trans::beforeUiReady(QQmlContext *ctx)
{
m_ctx = ctx;
ctx->setContextProperty("trans", this);
@ -21,12 +18,10 @@ void Trans::beforeUiReady(QQmlContext* ctx)
qApp->installTranslator(this);
}
void Trans::afterUiReady()
{
void Trans::afterUiReady() {}
}
QString Trans::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const
QString Trans::translate(const char *context, const char *sourceText, const char *disambiguation,
int n) const
{
Q_UNUSED(context)
Q_UNUSED(disambiguation)
@ -35,12 +30,12 @@ QString Trans::translate(const char *context, const char *sourceText, const char
return trans(sourceText);
}
void Trans::loadFolder(const QString& folder)
void Trans::loadFolder(const QString &folder)
{
QDir dir(folder);
auto infos = dir.entryInfoList({ "language_*.json" }, QDir::Files);
QString lang;
for (auto info : infos) {
for (const auto &info : infos) {
load(lang, info.absoluteFilePath());
}
@ -59,7 +54,7 @@ void Trans::loadFolder(const QString& folder)
emit folderLoaded(folder);
}
bool Trans::load(QString& lang, const QString& filePath)
bool Trans::load(QString &lang, const QString &filePath)
{
lang.clear();
QJsonObject rootObj;
@ -67,8 +62,8 @@ bool Trans::load(QString& lang, const QString& filePath)
return false;
}
lang = rootObj.value("lang").toString();
const auto& trans = rootObj.value("trans").toArray();
for (auto i : trans) {
const auto &trans = rootObj.value("trans").toArray();
for (const auto &i : trans) {
auto transObj = i.toObject();
QString key = transObj.value("key").toString();
QString value = transObj.value("value").toString();
@ -78,17 +73,17 @@ bool Trans::load(QString& lang, const QString& filePath)
return true;
}
const QString& Trans::currentLang() const
const QString &Trans::currentLang() const
{
return m_currentLang;
}
const QStringList& Trans::languages() const
const QStringList &Trans::languages() const
{
return m_languages;
}
const QString& Trans::transString() const
const QString &Trans::transString() const
{
return m_transString;
}
@ -102,18 +97,18 @@ void Trans::initEnglish()
} else {
map = m_map.value(m_map.keys().first());
}
for (auto key : map.keys()) {
for (const auto &key : map.keys()) {
m_map[cEnglisthStr][key] = key;
}
}
}
QString Trans::trans(const QString& source) const
QString Trans::trans(const QString &source) const
{
return m_map.value(m_currentLang).value(source, source);
}
void Trans::setCurrentLang(const QString& currentLang)
void Trans::setCurrentLang(const QString &currentLang)
{
if (m_currentLang == currentLang)
return;
@ -126,10 +121,9 @@ void Trans::setCurrentLang(const QString& currentLang)
#else
emit transStringChanged();
#endif
}
void Trans::setLanguages(const QStringList& languages)
void Trans::setLanguages(const QStringList &languages)
{
if (m_languages == languages)
return;

View File

@ -19,16 +19,18 @@ public:
Q_INVOKABLE void loadFolder(const QString &folder);
Q_INVOKABLE bool load(QString &lang, const QString &filePath);
public:
void beforeUiReady(QQmlContext* ctx);
void beforeUiReady(QQmlContext *ctx);
void afterUiReady();
QString translate(const char *context, const char *sourceText, const char *disambiguation = nullptr, int n = -1) const override;
QString translate(const char *context, const char *sourceText,
const char *disambiguation = nullptr, int n = -1) const override;
public:
const QString &currentLang() const;
const QStringList &languages() const;
const QString &transString() const;
@ -46,10 +48,12 @@ signals:
void folderLoaded(const QString &folder);
void transStringChanged();
protected:
void setLanguages(const QStringList &languages);
void initEnglish();
private:
QString m_currentLang;
// <"English", <"key", "value">>
@ -58,4 +62,3 @@ private:
QString m_transString;
QQmlContext *m_ctx;
};

View File

@ -2,11 +2,11 @@
#include <QtCore/QtGlobal>
#if !defined(BUILD_STATIC) && !defined(TaoCommon_NO_LIB)
#if defined(TaoCommon_Library)
#define TAO_API Q_DECL_EXPORT
# if defined(TaoCommon_Library)
# define TAO_API Q_DECL_EXPORT
# else
# define TAO_API Q_DECL_IMPORT
# endif
#else
#define TAO_API Q_DECL_IMPORT
#endif
#else
#define TAO_API
# define TAO_API
#endif

85
_clang-format Normal file
View File

@ -0,0 +1,85 @@
# Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
#
# You may use this file under the terms of the 3-clause BSD license.
# See the file LICENSE from this package for details.
# This is the clang-format configuration style to be used by Qt,
# based on the rules from https://wiki.qt.io/Qt_Coding_Style and
# https://wiki.qt.io/Coding_Conventions
---
# Webkit style was loosely based on the Qt style
BasedOnStyle: WebKit
Standard: Cpp11
# Column width is limited to 100 in accordance with Qt Coding Style.
# https://wiki.qt.io/Qt_Coding_Style
# Note that this may be changed at some point in the future.
ColumnLimit: 100
# How much weight do extra characters after the line length limit have.
# PenaltyExcessCharacter: 4
# Disable reflow of qdoc comments: indentation rules are different.
# Translation comments are also excluded.
CommentPragmas: "^!|^:"
# We want a space between the type and the star for pointer types.
PointerBindsToType: false
# We use template< without space.
SpaceAfterTemplateKeyword: false
# We want to break before the operators, but not before a '='.
BreakBeforeBinaryOperators: NonAssignment
# Braces are usually attached, but not after functions or class declarations.
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
# When constructor initializers do not fit on one line, put them each on a new line.
ConstructorInitializerAllOnOneLineOrOnePerLine: true
# Indent initializers by 4 spaces
ConstructorInitializerIndentWidth: 4
# Indent width for line continuations.
ContinuationIndentWidth: 8
# No indentation for namespaces.
NamespaceIndentation: None
# Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125
IndentPPDirectives: AfterHash
# Horizontally align arguments after an open bracket.
# The coding style does not specify the following, but this is what gives
# results closest to the existing code.
AlignAfterOpenBracket: true
AlwaysBreakTemplateDeclarations: true
# Ideally we should also allow less short function in a single line, but
# clang-format does not handle that.
AllowShortFunctionsOnASingleLine: Inline
# The coding style specifies some include order categories, but also tells to
# separate categories with an empty line. It does not specify the order within
# the categories. Since the SortInclude feature of clang-format does not
# re-order includes separated by empty lines, the feature is not used.
SortIncludes: false
# macros for which the opening brace stays attached.
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
# Break constructor initializers before the colon and after the commas.
BreakConstructorInitializers: BeforeColon

BIN
bin/debug/TaoQuickShow.exe Normal file

Binary file not shown.

BIN
bin/debug/TaoQuickShow.ilk Normal file

Binary file not shown.

BIN
bin/debug/TaoQuickShow.pdb Normal file

Binary file not shown.

View File

@ -0,0 +1,422 @@
{
"lang": "简体中文",
"trans":[
{
"key": "Chinese",
"value": "简体中文"
},
{
"key": "Quit",
"value": "退出"
},
{
"key": "minimal",
"value": "最小化"
},
{
"key": "maximize",
"value": "最大化"
},
{
"key": "normal",
"value": "窗口"
},
{
"key": "skin",
"value": "皮肤"
},
{
"key": "Language",
"value": "语言"
},
{
"key": "Settings",
"value": "设置"
},
{
"key": "About",
"value": "关于"
},
{
"key": "Badget",
"value": "徽章"
},
{
"key": "Barrage",
"value": "弹幕"
},
{
"key": "Label",
"value": "标签"
},
{
"key": "ProgressBar",
"value": "进度条"
},
{
"key": "Scrolling",
"value": "滚动列表"
},
{
"key": "Menu",
"value": "菜单"
},
{
"key": "TaoQuick",
"value": "TaoQuick"
},
{
"key": "Blue",
"value": "苍穹蓝"
},
{
"key": "Green",
"value": " 清爽绿"
},
{
"key": "Pink",
"value": "淑女粉"
},
{
"key": "Red",
"value": "一品红"
},
{
"key": "Gold",
"value": "富贵金"
},
{
"key": "Black",
"value": "高冷黑"
},
{
"key": "Search",
"value": "搜索"
},
{
"key": "TaoQuick provides a set of controls that can be used to build complete interfaces in Qt Quick.",
"value": "TaoQuick 提供一系列功能组件可用于Qt Quick 构建的应用中。"
},
{
"key": "Welcome",
"value": "欢迎"
},
{
"key": "Close",
"value": "关闭"
},
{
"key": "QRcode",
"value": "二维码"
},
{
"key": "IP address",
"value": "IP地址"
},
{
"key": "Home",
"value": "首页"
},
{
"key": "Button",
"value": "按钮"
},
{
"key": "Gradient",
"value": "渐变"
},
{
"key": "Background",
"value": "背景"
},
{
"key": "Dialog",
"value": "对话框"
},
{
"key": "ShaderEffect",
"value": "着色器特效"
},
{
"key": "Super Mario",
"value": "超级马里奥"
},
{
"key": "Effect",
"value": "特效"
},
{
"key": "Ring",
"value": "环"
},
{
"key": "Snail",
"value": "蜗牛"
},
{
"key": "CloudHole",
"value": "穿云洞"
},
{
"key": "Brilliant Starry Sky",
"value": "璀璨星空"
},
{
"key": "Keep up with the pace",
"value": "跟上节奏"
},
{
"key": "Undercurrent surge",
"value": "暗流涌动"
},
{
"key": "Magic Circle",
"value": "魔力圈圈"
},
{
"key": "Animation",
"value": "动画"
},
{
"key": "Enter",
"value": "飞入"
},
{
"key": "Grad",
"value": "梯度"
},
{
"key": "Cleavage",
"value": "劈裂"
},
{
"key": "Diagonal",
"value": "对角线"
},
{
"key": "Louver",
"value": "百叶窗"
},
{
"key": "Square",
"value": "方盒"
},
{
"key": "Circle",
"value": "圆盒"
},
{
"key": "Cross",
"value": "十字"
},
{
"key": "Rhombus",
"value": "菱形"
},
{
"key": "Wheel",
"value": "轮子"
},
{
"key": "Board",
"value": "棋盘"
},
{
"key": "Dissolve",
"value": "溶解"
},
{
"key": "PageSwitch",
"value": "页面切换"
},
{
"key": "FadeInOut",
"value": "淡入淡出"
},
{
"key": "Animation",
"value":"动画"
},
{
"key": "Effect",
"value":"效果"
},
{
"key": "PageSwitch",
"value":"页面切换"
},
{
"key": "ShaderEffect",
"value":"着色器特效"
},
{
"key": "Shape",
"value":"图元"
},
{
"key": "Text Button has no background and border",
"value": "文本按钮 没有背景和边框"
},
{
"key": "Material Button has a gradiant background when clicked",
"value":"Material 按钮 在点击时,展示一个渐变的背景"
},
{
"key": "General Button is consist of text, background and tooltip, it has normal, hover, pressed and disable states",
"value": "通用按钮 由文本、背景和悬浮框组成,状态包含常规、悬浮、按下和禁用"
},
{
"key": "Button can be design with different colors according to importance, example: blue for normal operation, red for delete operation and white for cancel operation",
"value": "按钮可以按照重要度设计为不同的颜色,例如: 常规操作用蓝色,删除操作用红色,取消操作用白色"
},
{
"key": "General Button can be custom style, such as round background, icon background, icon text ans so on",
"value": "通用按钮可以任意自定义风格, 诸如: 圆角背景、图标、带图标文字等等"
},
{
"key": "Image",
"value": "图片"
},
{
"key": "General Image",
"value": "通用图片"
},
{
"key": "Image with tip",
"value": "带悬浮的图片"
},
{
"key": "View Source Code",
"value": "查看源码"
},
{
"key": "Image Button",
"value": "图片按钮"
},
{
"key": "Image Text Button",
"value": "图文按钮"
},
{
"key": "Data Entry",
"value": "数据输入"
},
{
"key": "Hello, TaoQuick",
"value": "你好, TaoQuick"
},
{
"key": "Sunday",
"value": "星期天"
},
{
"key": "Monday",
"value": "星期一"
},
{
"key": "Tuesday",
"value": "星期二"
},
{
"key": "Wednesday",
"value": "星期三"
},
{
"key": "Thursday",
"value": "星期四"
},
{
"key": "Friday",
"value": "星期五"
},
{
"key": "Saturday",
"value": "星期六"
},
{
"key": "Others",
"value": "其它"
},
{
"key": "Sponsors",
"value": "赞助"
},
{
"key": "RectDraw, can draw rect by mouse press and move",
"value": "RectDraw 可以通过鼠标按下和移动来画框"
},
{
"key": "Drag Rect",
"value": "拖动框"
},
{
"key": "TemplateDragBorder can be use to resize, move or rotation Rectangle by draging corner or border handler",
"value": "TemplateDragBorder 可通过操作器改变尺寸、坐标或旋转"
},
{
"key": "General",
"value": "通用"
},
{
"key": "Animation",
"value": "动画"
},
{
"key": "Effect",
"value": "特效"
},
{
"key": "PageSwitch",
"value": "页面切换"
},
{
"key": "ShaderEffect",
"value": "着色器特效"
},
{
"key": "Auto Play",
"value": "自动播放"
},
{
"key": "Replay",
"value": "重新播放"
},
{
"key": "No Data",
"value": "无数据"
},
{
"key": "last %1 item",
"value": "前%1项"
},
{
"key": "last %1 items",
"value": "前%1项"
},
{
"key": "next %1 item",
"value": "后%1项"
},
{
"key": "next %1 items",
"value": "后%1项"
},
{
"key": "Total %1 item",
"value": "共计%1项"
},
{
"key": "Total %1 items",
"value": "共计%1项"
},
{
"key": "Go to",
"value": "转到"
}
]
}

View File

@ -1,6 +1,5 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
import TaoQuick 1.0
import "../Biz"
@ -116,13 +115,6 @@ Popup {
}
}
}
DropShadow {
source: back
anchors.fill: back
radius: 4
samples: 16
color: "#80000000"
}
}
function show() {

View File

@ -15,7 +15,7 @@ static void prepareApp()
QCoreApplication::setApplicationName("TaoQuickShow");
}
int main(int argc, char** argv)
int main(int argc, char **argv)
{
prepareApp();
QGuiApplication app(argc, argv);
@ -29,6 +29,8 @@ int main(int argc, char** argv)
qWarning() << "appPath" << appPath;
TaoFrameLessView view;
view.setMinimumSize({ 800, 600 });
view.resize(1440, 960);
Trans trans;
AppInfo appInfo;
trans.beforeUiReady(view.rootContext());