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

foramt all

This commit is contained in:
jared 2023-04-25 09:59:36 +08:00
parent 021f3385e1
commit 70e4213128
42 changed files with 1091 additions and 960 deletions

View File

@ -17,23 +17,31 @@ ColumnLimit: 160
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
UseTab: Always
# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: AlwaysBreak
#对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right
# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: true
# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: true
# 左对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right
# 对齐连续的宏定义
AlignConsecutiveMacros: true
# 对齐尾注释
AlignTrailingComments: true
# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义与Attach类似),
# Mozilla(除枚举、函数、记录定义与Attach类似), Stroustrup(除函数定义、catch、else与Attach类似),
# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Custom
BreakBeforeBraces: Allman
# 大括号换行只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
# class定义后面
@ -61,7 +69,10 @@ BraceWrapping:
# 缩进大括号
IndentBraces: false
# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: None
# 继承列表的逗号前换行
BreakBeforeInheritanceComma: true
@ -77,12 +88,6 @@ BreakConstructorInitializers: BeforeComma
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true
# false表示函数实参要么都在同一行要么都各自一行
BinPackArguments: false
# false表示所有形参要么都在同一行要么都各自一行
BinPackParameters: false
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'
@ -95,11 +100,11 @@ AlignTrailingComments: true
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: Empty
# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false
# false表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: false
# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Left
# false表示所有形参要么都在同一行要么都各自一行
BinPackParameters: false
# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros:
@ -107,6 +112,7 @@ ForEachMacros:
- Q_FOREACH
- BOOST_FOREACH
IndentCaseLabels: true
IncludeBlocks: Preserve
# 对#include进行排序匹配了某正则表达式的#include拥有对应的优先级匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前)
@ -120,5 +126,4 @@ IncludeCategories:
Priority: 1
- Regex: '.*'
Priority: 1
...

View File

@ -1,19 +1,19 @@
#include "Logger/Logger.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Logger/Logger.h"
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Logger::initLog();
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject* obj, const QUrl& objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();

View File

@ -1,7 +1,7 @@
#include "Logger/Logger.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Logger/Logger.h"
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
@ -9,12 +9,12 @@ int main(int argc, char *argv[])
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject* obj, const QUrl& objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();

View File

@ -27,7 +27,8 @@ static void showSomeLogger()
// u8是c++11标准支持的字符串字面量写法可以参考https://zh.cppreference.com/w/cpp/language/string_literal
// QStringLiteral是Qt特有的宏用来在编译期生成字符串字面量
// QString::fromLocal8Bit可以在运行过程中动态处理中文字符串。
for (int i = 0; i < 1000; ++i) {
for (int i = 0; i < 1000; ++i)
{
gCount++;
int count = gCount;
LOG_DEBUG << currentThreadId() << u8"山有木兮木有枝,心悦君兮君不知。";
@ -44,18 +45,20 @@ static void logThread()
vector<std::thread> threads;
//创建N个线程
for (unsigned long long i = 0; i < N; ++i) {
for (unsigned long long i = 0; i < N; ++i)
{
threads.emplace_back(thread(showSomeLogger));
}
// join,等线程结束。
for (unsigned long long i = 0; i < N; ++i) {
for (unsigned long long i = 0; i < N; ++i)
{
threads[i].join();
}
LOG_INFO << currentThreadId() << u8"故事到这就结束了总共输出log" << gCount;
qApp->exit();
}
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);

View File

@ -1,12 +1,13 @@
#pragma once
#include "Logger/Logger.h"
#include <QDebug>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QString>
#include "Logger/Logger.h"
namespace TaoCommon {
namespace TaoCommon
{
static bool readFile(const QString& filePath, QByteArray& content, QString* errStr = nullptr)
{
@ -40,7 +41,7 @@ static bool readJson(const QByteArray& data, QJsonDocument& doc, QString* errStr
static bool readJson(const QByteArray& data, QJsonArray& array, QString* errStr = nullptr)
{
QJsonDocument doc;
bool ok = readJson(data, doc, errStr);
bool ok = readJson(data, doc, errStr);
if (ok)
{
array = doc.array();
@ -50,7 +51,7 @@ static bool readJson(const QByteArray& data, QJsonArray& array, QString* errStr
static bool readJson(const QByteArray& data, QJsonObject& object, QString* errStr = nullptr)
{
QJsonDocument doc;
bool ok = readJson(data, doc, errStr);
bool ok = readJson(data, doc, errStr);
if (ok)
{
object = doc.object();
@ -112,5 +113,4 @@ static bool writeJsonFile(const QString& filePath, const QJsonObject& jsonObj, Q
return writeJsonFile(filePath, QJsonDocument(jsonObj), errStr);
}
} // namespace TaoCommon

View File

@ -1,76 +1,82 @@
#pragma once
// json 序列化
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVariant>
#include <QVariantList>
#include <QVariantMap>
///@brief 序列化. object to Json, object to Variant or VariantMap
#define JsonSerialize_Begin() \
public: \
operator QVariant() const { return QVariant::fromValue(this->operator QVariantMap()); } \
operator QJsonObject() const \
{ \
return QJsonObject::fromVariantMap(this->operator QVariantMap()); \
} \
operator QVariantMap() const \
{ \
#define JsonSerialize_Begin() \
public: \
operator QVariant() const \
{ \
return QVariant::fromValue(this->operator QVariantMap()); \
} \
operator QJsonObject() const \
{ \
return QJsonObject::fromVariantMap(this->operator QVariantMap()); \
} \
operator QVariantMap() const \
{ \
QVariantMap vmap;
#define JsonSerialize_End() \
return vmap; \
#define JsonSerialize_End() \
return vmap; \
}
///@brief 序列化属性映射
#define JsonPureProperty(NAME) vmap.unite((QVariantMap)m_##NAME);
#define JsonProperty(NAME) \
vmap[#NAME] = QVariant::fromValue(m_##NAME); \
if (vmap.value(#NAME).isNull()) \
#define JsonProperty(NAME) \
vmap[#NAME] = QVariant::fromValue(m_##NAME); \
if (vmap.value(#NAME).isNull()) \
vmap.remove(#NAME);
#define JsonContainerProperty(NAME) \
{ \
QVariantList lst; \
lst.reserve(m_##NAME.size()); \
for (const auto &t : m_##NAME) { \
lst << QVariant::fromValue(t); \
} \
vmap[#NAME] = lst; \
#define JsonContainerProperty(NAME) \
{ \
QVariantList lst; \
lst.reserve(m_##NAME.size()); \
for (const auto& t : m_##NAME) \
{ \
lst << QVariant::fromValue(t); \
} \
vmap[#NAME] = lst; \
}
///@brief 反序列化 object from json
#define JsonDeserialize_Begin(class_name) \
public: \
class_name(const QJsonObject &other) \
{ \
#define JsonDeserialize_Begin(class_name) \
public: \
class_name(const QJsonObject& other) \
{ \
QVariantMap vmap = other.toVariantMap();
#define JsonDeserialize_End() }
///@brief 部分反序列化
#define JsonPartialDeserialize_Begin(class_name) \
public: \
class_name &operator=(const QJsonObject &other) \
{ \
#define JsonPartialDeserialize_Begin(class_name) \
public: \
class_name& operator=(const QJsonObject& other) \
{ \
QVariantMap vmap = other.toVariantMap();
#define JsonPartialDeserialize_End() \
return *this; \
#define JsonPartialDeserialize_End() \
return *this; \
}
#define JsonDeserializeContainerProperty(NAME) \
if (vmap.value(#NAME).canConvert<QVariantList>()) { \
const auto &list = vmap.value(#NAME).value<QVariantList>(); \
m_##NAME.clear(); \
m_##NAME.reserve(list.size()); \
for (const auto &v : list) { \
m_##NAME.push_back(v.value<decltype(m_##NAME)::value_type>()); \
} \
#define JsonDeserializeContainerProperty(NAME) \
if (vmap.value(#NAME).canConvert<QVariantList>()) \
{ \
const auto& list = vmap.value(#NAME).value<QVariantList>(); \
m_##NAME.clear(); \
m_##NAME.reserve(list.size()); \
for (const auto& v : list) \
{ \
m_##NAME.push_back(v.value<decltype(m_##NAME)::value_type>()); \
} \
}
#define JsonDeserializeProperty(NAME) m_##NAME = vmap.value(#NAME).value<decltype(m_##NAME)>();
@ -149,8 +155,3 @@ operator QVariant()
* QVariantMap map = info;
*
**/

View File

@ -1,39 +1,42 @@
#pragma once
#include <cmath>
#include <QtGlobal>
#include <algorithm>
//inRange 检查 value 小于等于 max 大于等于min
#include <cmath>
// inRange 检查 value 小于等于 max 大于等于min
//inRange<T>通用模版函数
template<typename T>
static bool inRange(const T &value, const T &min, const T &max)
// inRange<T>通用模版函数
template <typename T>
static bool inRange(const T& value, const T& min, const T& max)
{
if (min <= value && value <= max) {
if (min <= value && value <= max)
{
return true;
}
return false;
}
// inRange<double> 模版偏特化遇到double时使用std的 "浮点数比较" 代替 "常规比较", 规避精度误差
template<>
static bool inRange<double>(const double &value, const double &min, const double &max)
template <>
static bool inRange<double>(const double& value, const double& min, const double& max)
{
if (std::isgreaterequal(value, min) && std::islessequal(value, max)) {
if (std::isgreaterequal(value, min) && std::islessequal(value, max))
{
return true;
}
return false;
}
// inRange<float> 模版偏特化遇到float时使用std的"浮点数比较" 代替 "常规比较", 规避精度误差
template<>
static bool inRange<float>(const float &value, const float &min, const float &max)
template <>
static bool inRange<float>(const float& value, const float& min, const float& max)
{
if (std::isgreaterequal(value, min) && std::islessequal(value, max)) {
if (std::isgreaterequal(value, min) && std::islessequal(value, max))
{
return true;
}
return false;
}
//clamp, 限制 value在 [min - Max]区间.
template<typename T>
static T clamp(const T &value, const T &min, const T &max)
// clamp, 限制 value在 [min - Max]区间.
template <typename T>
static T clamp(const T& value, const T& min, const T& max)
{
return std::max(min,std::min(value, max));
return std::max(min, std::min(value, max));
}

View File

@ -6,142 +6,168 @@
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
namespace TaoCommon {
namespace TaoCommon
{
//对象存储器
template<typename Key, typename Value>
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()) {
if (itor == m_objMap.end())
{
return nullptr;
} else {
}
else
{
return itor->second;
}
}
template<class CallbackType>
void forEach(const CallbackType &callback) const
template <class CallbackType>
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>
template <typename ObjectType>
class CObjectMap
{
public:
virtual ~CObjectMap() { clear(); }
template<typename DeriveObjectType>
DeriveObjectType *getObject() const
virtual ~CObjectMap()
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
clear();
}
template <typename DeriveObjectType>
DeriveObjectType* getObject() const
{
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>
template <typename ObjectType>
class CLevelObjectMap
{
public:
virtual ~CLevelObjectMap() { clear(); }
template<typename DeriveObjectType>
DeriveObjectType *getObject() const
virtual ~CLevelObjectMap()
{
static_assert(std::is_base_of<ObjectType, DeriveObjectType>::value,
"DeriveObjectType must be derive from ObjectType");
clear();
}
template <typename DeriveObjectType>
DeriveObjectType* getObject() const
{
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()) {
if (itor != subMap.end())
{
return std::static_pointer_cast<DeriveObjectType>(itor->second).get();
}
}
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()) {
if (itor != subMap.end())
{
auto retItor = subMap.erase(itor);
return retItor != subMap.end();
}
}
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

@ -11,7 +11,7 @@
const int static headerLength = sizeof(quint32);
//封包。 入参为数据,返回值是 数据前面加一个头. 这就是一个数据包了
static QByteArray pack(const QByteArray &data)
static QByteArray pack(const QByteArray& data)
{
QByteArray header(headerLength, 0);
QDataStream os(&header, QIODevice::WriteOnly);
@ -19,17 +19,19 @@ static QByteArray pack(const QByteArray &data)
return header + data;
}
//拆包。入参为连续的数据,返回值是拆出来的所有包列表
static QByteArrayList unpack(const QByteArray &data)
static QByteArrayList unpack(const QByteArray& data)
{
QByteArrayList list;
QDataStream inStream(data);
quint32 sum = data.size();
quint32 pos = 0;
while (pos + headerLength < sum) {
while (pos + headerLength < sum)
{
quint32 packageLen = 0;
packageLen = 0;
inStream >> packageLen;
if (packageLen + headerLength > sum - pos) {
if (packageLen + headerLength > sum - pos)
{
break;
}
QByteArray subPackage = data.mid(pos + headerLength, packageLen);

View File

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

View File

@ -5,7 +5,7 @@
#include <QRegion>
//无边框窗口,主要用来实现自定义标题栏。
//Windows平台支持拖动和改变大小支持Aero效果
// Windows平台支持拖动和改变大小支持Aero效果
//非Windows平台去掉边框不做其它处理。由Qml模拟resize和拖动。
class TaoFrameLessViewPrivate;
class TAO_API TaoFrameLessView : public QQuickView
@ -15,14 +15,14 @@ class TAO_API TaoFrameLessView : public QQuickView
Q_PROPERTY(bool isMax READ isMax NOTIFY isMaxChanged)
Q_PROPERTY(bool isFull READ isFull NOTIFY isFullChanged)
public:
explicit TaoFrameLessView(QWindow *parent = nullptr);
explicit TaoFrameLessView(QWindow* parent = nullptr);
~TaoFrameLessView();
void moveToScreenCenter();
bool isMax() const;
bool isFull() const;
QQuickItem *titleItem() const;
QQuickItem* titleItem() const;
static QRect calcCenterGeo(const QRect &screenGeo, const QSize &normalSize);
static QRect calcCenterGeo(const QRect& screenGeo, const QSize& normalSize);
public slots:
void setIsMax(bool isMax);
void setIsFull(bool isFull);
@ -34,16 +34,16 @@ signals:
void mousePressed(int xPos, int yPos, int button);
protected:
void showEvent(QShowEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
# else
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
# endif
void showEvent(QShowEvent* e) override;
void resizeEvent(QResizeEvent* e) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
#else
bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;
#endif
void mousePressEvent(QMouseEvent* event) override
{
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
emit mousePressed(event->position().x(), event->position().y(), event->button());
#else
emit mousePressed(event->x(), event->y(), event->button());
@ -52,5 +52,5 @@ protected:
}
private:
TaoFrameLessViewPrivate *d;
TaoFrameLessViewPrivate* d;
};

View File

@ -9,9 +9,11 @@ class TaoFrameLessViewPrivate
public:
bool m_isMax = false;
bool m_isFull = false;
QQuickItem *m_titleItem = nullptr;
QQuickItem* m_titleItem = nullptr;
};
TaoFrameLessView::TaoFrameLessView(QWindow *parent) : Super(parent), d(new TaoFrameLessViewPrivate)
TaoFrameLessView::TaoFrameLessView(QWindow* parent)
: Super(parent)
, d(new TaoFrameLessViewPrivate)
{
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
setResizeMode(SizeRootObjectToView);
@ -28,21 +30,23 @@ TaoFrameLessView::~TaoFrameLessView()
{
delete d;
}
void TaoFrameLessView::showEvent(QShowEvent *e)
void TaoFrameLessView::showEvent(QShowEvent* e)
{
Super::showEvent(e);
}
QRect TaoFrameLessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
QRect TaoFrameLessView::calcCenterGeo(const QRect& screenGeo, const QSize& normalSize)
{
int w = normalSize.width();
int h = normalSize.height();
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
if (screenGeo.width() < w) {
if (screenGeo.width() < w)
{
x = screenGeo.x();
w = screenGeo.width();
}
if (screenGeo.height() < h) {
if (screenGeo.height() < h)
{
y = screenGeo.y();
h = screenGeo.height();
}
@ -52,7 +56,8 @@ QRect TaoFrameLessView::calcCenterGeo(const QRect &screenGeo, const QSize &norma
void TaoFrameLessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
if (minimumWidth() > geo.width() || minimumHeight() > geo.height())
{
setMinimumSize(geo.size());
}
setGeometry(geo);
@ -66,7 +71,7 @@ bool TaoFrameLessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *TaoFrameLessView::titleItem() const
QQuickItem* TaoFrameLessView::titleItem() const
{
return d->m_titleItem;
}
@ -80,27 +85,27 @@ void TaoFrameLessView::setIsMax(bool isMax)
}
void TaoFrameLessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
if (d->m_isFull == isFull)
return;
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
void TaoFrameLessView::setTitleItem(QQuickItem *item)
void TaoFrameLessView::setTitleItem(QQuickItem* item)
{
d->m_titleItem = item;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
bool TaoFrameLessView::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
#else
bool TaoFrameLessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
bool TaoFrameLessView::nativeEvent(const QByteArray& eventType, void* message, long* result)
#endif
{
return Super::nativeEvent(eventType, message, result);
}
void TaoFrameLessView::resizeEvent(QResizeEvent *e)
void TaoFrameLessView::resizeEvent(QResizeEvent* e)
{
Super::resizeEvent(e);
}

View File

@ -3,48 +3,52 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QMutex>
#include <QDebug>
#include <QTextStream>
#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);
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)
void initLog(const QString& logPath, int logMaxCount, bool async)
{
if (async) {
if (async)
{
qInstallMessageHandler(outputMessageAsync);
} else {
}
else
{
qInstallMessageHandler(outputMessage);
}
gLogDir = QCoreApplication::applicationDirPath() + QStringLiteral("/") + logPath;
gLogMaxCount = logMaxCount;
QDir dir(gLogDir);
if (!dir.exists()) {
if (!dir.exists())
{
dir.mkpath(dir.absolutePath());
}
QStringList infoList = dir.entryList(QDir::Files, QDir::Name);
while (infoList.size() > gLogMaxCount) {
while (infoList.size() > gLogMaxCount)
{
dir.remove(infoList.first());
infoList.removeFirst();
}
}
static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context,
const QString &msg)
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' };
@ -67,8 +71,10 @@ static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context
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()) {
if (file.fileName() != newfileName)
{
if (file.isOpen())
{
file.close();
}
file.setFileName(newfileName);
@ -80,14 +86,16 @@ static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context
#else
textStream.setCodec("UTF-8");
#endif
if (!exist) {
if (!exist)
{
textStream << logTemplate << "\r\n";
}
}
textStream << htmlMessage;
textStream.flush();
count += htmlMessage.length();
if (count >= maxCount) {
if (count >= maxCount)
{
file.close();
file.open(QIODevice::WriteOnly | QIODevice::Append);
}
@ -99,7 +107,7 @@ static void outputMessageAsync(QtMsgType type, const QMessageLogContext &context
fprintf(stderr, "%s", message.toStdString().data());
#endif
}
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
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' };
@ -128,7 +136,8 @@ static void outputMessage(QtMsgType type, const QMessageLogContext &context, con
#else
textStream.setCodec("UTF-8");
#endif
if (!exist) {
if (!exist)
{
textStream << logTemplate << "\r\n";
}
textStream << htmlMessage;

View File

@ -1,23 +1,23 @@
#pragma once
#include "TaoCommonGlobal.h"
#include <QString>
#include <QDebug>
namespace Logger {
#include <QString>
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);
void TAO_API initLog(const QString& logPath = QStringLiteral("Log"), int logMaxCount = 1024, bool async = true);
} // namespace Logger

View File

@ -1,7 +1,8 @@
#pragma once
#include <QString>
#include <string>
namespace Logger {
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">

View File

@ -1,10 +1,8 @@
#include "QuickModel/QuickListItemBase.h"
QuickListItemBase::QuickListItemBase(QObject *parent)
QuickListItemBase::QuickListItemBase(QObject* parent)
: QObject(parent)
{
}
QuickListItemBase::~QuickListItemBase()
{
}
QuickListItemBase::~QuickListItemBase() { }

View File

@ -1,7 +1,7 @@
#pragma once
#include <QObject>
#include "TaoCommonGlobal.h"
#include <QObject>
class TAO_API QuickListItemBase : public QObject
{
Q_OBJECT
@ -10,9 +10,9 @@ class TAO_API QuickListItemBase : public QObject
Q_PROPERTY(bool isVisible READ isVisible WRITE setIsVisible NOTIFY isVisibleChanged)
Q_PROPERTY(bool isAlternate READ isAlternate WRITE setIsAlternate NOTIFY isAlternateChanged)
public:
explicit QuickListItemBase(QObject *parent = nullptr);
explicit QuickListItemBase(QObject* parent = nullptr);
~QuickListItemBase() override;
QuickListItemBase(const QuickListItemBase &other)
QuickListItemBase(const QuickListItemBase& other)
{
setIsChecked(other.isChecked());
setIsSelected(other.isSelected());
@ -20,7 +20,7 @@ public:
setIsAlternate(other.isAlternate());
}
QuickListItemBase &operator=(const QuickListItemBase &other)
QuickListItemBase& operator=(const QuickListItemBase& other)
{
setIsChecked(other.isChecked());
setIsSelected(other.isSelected());
@ -47,7 +47,7 @@ public:
return mIsAlternate;
}
// Model call this for search. return true if contents match key, others return false.
virtual bool match(const QString &key)
virtual bool match(const QString& key)
{
Q_UNUSED(key)
return true;
@ -73,7 +73,7 @@ public slots:
void setIsVisible(bool isVisible)
{
//if (mIsVisible == isVisible)
// if (mIsVisible == isVisible)
// return;
mIsVisible = isVisible;

View File

@ -2,7 +2,7 @@
#include <QDebug>
#include <algorithm>
QuickListModel::QuickListModel(QObject *parent)
QuickListModel::QuickListModel(QObject* parent)
: QuickModelBase(parent)
{
connect(&mSearchTimer, &QTimer::timeout, this, &QuickListModel::onSearch);
@ -10,9 +10,7 @@ QuickListModel::QuickListModel(QObject *parent)
mSearchTimer.setSingleShot(true);
}
QuickListModel::~QuickListModel()
{
}
QuickListModel::~QuickListModel() { }
void QuickListModel::check(int row, bool checked)
{
@ -24,7 +22,7 @@ void QuickListModel::check(int row, bool checked)
mDatas.at(row)->setIsChecked(checked);
if (mDatas.at(row)->isSelected())
{
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible() && obj->isSelected())
{
@ -40,7 +38,7 @@ void QuickListModel::check(int row, bool checked)
}
else
{
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible() && false == obj->isChecked())
{
@ -58,7 +56,7 @@ void QuickListModel::check(int row, bool checked)
}
void QuickListModel::setAllChecked(bool allChecked)
{
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible())
{
@ -72,13 +70,13 @@ void QuickListModel::setAllChecked(bool allChecked)
mAllChecked = allChecked;
emit allCheckedChanged(mAllChecked);
}
void QuickListModel::search(const QString &searchKey)
void QuickListModel::search(const QString& searchKey)
{
mSearchkey = searchKey.simplified();
//mSearchTimer.start(400);
// mSearchTimer.start(400);
onSearch();
}
void QuickListModel::searchImmediate(const QString &searchKey)
void QuickListModel::searchImmediate(const QString& searchKey)
{
mSearchkey = searchKey.simplified();
onSearch();
@ -87,40 +85,40 @@ void QuickListModel::onSearch()
{
emit beginSearch();
QList<QuickListItemBase *> newDatas;
QList<QuickListItemBase*> newDatas;
int vcount = 0;
for (const auto &obj : mAllDatas)
{
bool v = mVisibleCallback == NULL || mVisibleCallback(obj);
bool m = obj->match(mSearchkey);
int vcount = 0;
for (const auto& obj : mAllDatas)
{
bool v = mVisibleCallback == NULL || mVisibleCallback(obj);
bool m = obj->match(mSearchkey);
if (v && m)
{
newDatas.push_back(obj);
vcount++;
}
}
if (v && m)
{
newDatas.push_back(obj);
vcount++;
}
}
if (!compareDataChanged(mDatas, newDatas))
{
if (!compareDataChanged(mDatas, newDatas))
{
sortByRole();
emit endSearch();
return;
}
emit endSearch();
return;
}
mDatas = newDatas;
sortByRole();
//qWarning() << mSearchkey << vcount;
//emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0), QVector<int>{Qt::EditRole, Qt::DisplayRole});
mDatas = newDatas;
sortByRole();
// qWarning() << mSearchkey << vcount;
// emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0), QVector<int>{Qt::EditRole, Qt::DisplayRole});
beginResetModel();
endResetModel();
updateCalcInfo();
emit endSearch();
emit endSearch();
}
void QuickListModel::deselectAll()
{
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible())
{
@ -133,7 +131,7 @@ void QuickListModel::deselectAll()
void QuickListModel::selectAll()
{
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible())
{
@ -263,11 +261,11 @@ void QuickListModel::sortByRole()
{
return;
}
if (mSortOrder == Qt::SortOrder::AscendingOrder)
if (mSortOrder == Qt::SortOrder::AscendingOrder)
{
if (const auto &sortCall = mSortCallbacksAscend.value(mSortRole))
if (const auto& sortCall = mSortCallbacksAscend.value(mSortRole))
{
QList<QuickListItemBase *> copyObjs;
QList<QuickListItemBase*> copyObjs;
copyObjs = mDatas;
std::sort(copyObjs.begin(), copyObjs.end(), sortCall);
mDatas = copyObjs;
@ -277,9 +275,9 @@ void QuickListModel::sortByRole()
}
else
{
if (const auto &sortCall = mSortCallbacksDescend.value(mSortRole))
if (const auto& sortCall = mSortCallbacksDescend.value(mSortRole))
{
QList<QuickListItemBase *> copyObjs;
QList<QuickListItemBase*> copyObjs;
copyObjs = mDatas;
std::sort(copyObjs.begin(), copyObjs.end(), sortCall);
mDatas = copyObjs;
@ -289,7 +287,7 @@ void QuickListModel::sortByRole()
}
}
void QuickListModel::setHeaderRoles(const QStringList &headerRoles)
void QuickListModel::setHeaderRoles(const QStringList& headerRoles)
{
if (mHeaderRoles == headerRoles)
return;
@ -307,7 +305,7 @@ void QuickListModel::setSortOrder(Qt::SortOrder sortOrder)
emit sortOrderChanged(mSortOrder);
}
void QuickListModel::setSortRole(const QString &sortRole)
void QuickListModel::setSortRole(const QString& sortRole)
{
if (mSortRole == sortRole)
return;
@ -321,7 +319,7 @@ void QuickListModel::updateAllCheck()
bool allCheck = false;
if (!mDatas.empty())
{
allCheck = std::all_of(mDatas.begin(), mDatas.end(), [](QuickListItemBase *obj) { return obj->isVisible() && obj->isChecked(); });
allCheck = std::all_of(mDatas.begin(), mDatas.end(), [](QuickListItemBase* obj) { return obj->isVisible() && obj->isChecked(); });
}
if (mAllChecked == allCheck)
return;
@ -332,25 +330,25 @@ void QuickListModel::updateAllCheck()
void QuickListModel::updateVisibleCount()
{
int count = mDatas.count();// std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase *obj) { return obj->isVisible(); });
int count = mDatas.count(); // std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase *obj) { return obj->isVisible(); });
setVisibledCount(count);
}
void QuickListModel::updateSelectedCount()
{
int count = std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase *obj) { return obj->isVisible() && obj->isSelected(); });
int count = std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase* obj) { return obj->isVisible() && obj->isSelected(); });
setSelectedCount(count);
}
void QuickListModel::updateCheckedCount()
{
int count = std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase *obj) { return obj->isVisible() && obj->isChecked(); });
int count = std::count_if(mDatas.begin(), mDatas.end(), [](QuickListItemBase* obj) { return obj->isVisible() && obj->isChecked(); });
setCheckedCount(count);
}
void QuickListModel::updateAlternate()
{
bool alter = false;
for (const auto &obj : mDatas)
for (const auto& obj : mDatas)
{
if (obj->isVisible())
{

View File

@ -4,7 +4,7 @@
#include "QuickModelBase.hpp"
#include "TaoCommonGlobal.h"
#include <QTimer>
class TAO_API QuickListModel : public QuickModelBase<QuickListItemBase *>
class TAO_API QuickListModel : public QuickModelBase<QuickListItemBase*>
{
Q_OBJECT
Q_PROPERTY(bool allChecked READ allChecked WRITE setAllChecked NOTIFY allCheckedChanged)
@ -17,8 +17,8 @@ class TAO_API QuickListModel : public QuickModelBase<QuickListItemBase *>
Q_PROPERTY(QString sortRole READ sortRole WRITE setSortRole NOTIFY sortRoleChanged)
public:
using Super = QuickModelBase<QuickListItemBase *>;
explicit QuickListModel(QObject *parent = nullptr);
using Super = QuickModelBase<QuickListItemBase*>;
explicit QuickListModel(QObject* parent = nullptr);
~QuickListModel() override;
Q_INVOKABLE QVariant data(int row) const
{
@ -33,20 +33,20 @@ public:
//[end] check
//[begin] search. control visible
Q_INVOKABLE void search(const QString &searchKey);
const QString & searchKey() const
Q_INVOKABLE void search(const QString& searchKey);
const QString& searchKey() const
{
return mSearchkey;
}
Q_INVOKABLE void searchImmediate(const QString &searchKey);
Q_INVOKABLE void searchImmediate(const QString& searchKey);
Q_INVOKABLE void clearSearchKey()
{
mSearchkey.clear();
}
//[end] search
using VisibleCallback = std::function<bool(QuickListItemBase *)>;
void setVisibleFilter(const VisibleCallback &callback)
using VisibleCallback = std::function<bool(QuickListItemBase*)>;
void setVisibleFilter(const VisibleCallback& callback)
{
mVisibleCallback = callback;
}
@ -66,7 +66,7 @@ public:
Q_INVOKABLE void doRelease();
//[begin] sort
const QStringList &headerRoles() const
const QStringList& headerRoles() const
{
return mHeaderRoles;
}
@ -76,21 +76,21 @@ public:
return mSortOrder;
}
const QString &sortRole() const
const QString& sortRole() const
{
return mSortRole;
}
using SortCallback = std::function<bool(QuickListItemBase *, QuickListItemBase *)>;
using SortCallback = std::function<bool(QuickListItemBase*, QuickListItemBase*)>;
// Map <key, callBack> ,key should match to headerRoles
void setSortCallbacksAscend(const QMap<QString, SortCallback> &callbacksMap)
void setSortCallbacksAscend(const QMap<QString, SortCallback>& callbacksMap)
{
mSortCallbacksAscend = callbacksMap;
}
void setSortCallbacksDescend(const QMap<QString, SortCallback> &callbacksMap)
void setSortCallbacksDescend(const QMap<QString, SortCallback>& callbacksMap)
{
mSortCallbacksDescend = callbacksMap;
}
Q_INVOKABLE virtual void sortByRole();
//[end] sort
@ -120,11 +120,11 @@ public:
public slots:
void setAllChecked(bool allChecked);
void setHeaderRoles(const QStringList &headerRoles);
void setHeaderRoles(const QStringList& headerRoles);
void setSortOrder(Qt::SortOrder sortOrder);
void setSortRole(const QString &sortRole);
void setSortRole(const QString& sortRole);
void setVisibledCount(int visibledCount);
void setSelectedCount(int selectedCount);
@ -141,11 +141,11 @@ signals:
void checkedCountChanged(int checkedCount);
void headerRolesChanged(const QStringList &headerRoles);
void headerRolesChanged(const QStringList& headerRoles);
void sortOrderChanged(Qt::SortOrder sortOrder);
void sortRoleChanged(const QString &sortRole);
void sortRoleChanged(const QString& sortRole);
void signalUpdateCalcCount();
@ -162,18 +162,18 @@ protected:
void updateAlternate();
protected:
bool mAllChecked = false;
bool mIsPressed = false;
Qt::SortOrder mSortOrder = Qt::AscendingOrder;
int mVisibledCount = 0;
int mSelectedCount = 0;
int mCheckedCount = 0;
int mLastPressedRow = -1;
QStringList mHeaderRoles;
QString mSortRole;
bool mAllChecked = false;
bool mIsPressed = false;
Qt::SortOrder mSortOrder = Qt::AscendingOrder;
int mVisibledCount = 0;
int mSelectedCount = 0;
int mCheckedCount = 0;
int mLastPressedRow = -1;
QStringList mHeaderRoles;
QString mSortRole;
QMap<QString, SortCallback> mSortCallbacksAscend;
QMap<QString, SortCallback> mSortCallbacksDescend;
QString mSearchkey;
QTimer mSearchTimer;
VisibleCallback mVisibleCallback;
QString mSearchkey;
QTimer mSearchTimer;
VisibleCallback mVisibleCallback;
};

View File

@ -1,46 +1,46 @@
#pragma once
#include "TaoCommonGlobal.h"
#include <QAbstractListModel>
#include <QList>
#include <QSet>
#include "TaoCommonGlobal.h"
template <class T>
class QuickModelBase : public QAbstractListModel
{
public:
using Super = QAbstractListModel;
explicit QuickModelBase(QObject *parent = nullptr);
explicit QuickModelBase(const QList<T> &datas, QObject *parent = nullptr);
explicit QuickModelBase(QObject* parent = nullptr);
explicit QuickModelBase(const QList<T>& datas, QObject* parent = nullptr);
virtual ~QuickModelBase() override;
public:
//[begin] query data
int rowCount(const QModelIndex &parent) const override;
int rowCount(const QModelIndex& parent) const override;
QVariant data(int row) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
//[end] query data
//[begin] reset data
void resetData(const QList<T> &datas);
const QList<T> &datas() const
void resetData(const QList<T>& datas);
const QList<T>& datas() const
{
return mDatas;
}
const QSet<T> &allDatas() const
{
return mAllDatas;
}
const QSet<T>& allDatas() const
{
return mAllDatas;
}
//[begin] add data
void append(const QList<T> &datas);
void append(const QList<T>& datas);
void prepend(T data);
void insert(int row, const QList<T> &datas);
void insert(int row, const QList<T>& datas);
//[end] add data
//[begin] remove data
void clear();
void removeAt(int row);
void subtract(const QSet<T> &other);
void subtract(const QSet<T>& other);
//[end] remove data
//[begin] update data
@ -48,71 +48,71 @@ public:
//[end] update data
public:
virtual void updateCalcInfo()
virtual void updateCalcInfo() { }
bool compareDataChanged(const QList<T>& data1, const QList<T>& data2)
{
bool changed = false;
QSet<T> set1;
for (auto it = data1.begin(); it != data1.end(); it++)
set1.insert(*it);
QSet<T> set2;
for (auto it = data2.begin(); it != data2.end() && !changed; it++)
{
if (set1.find(*it) == set1.end())
{
changed = true;
break;
}
set2.insert(*it);
}
for (auto it = set1.begin(); it != set1.end() && !changed; it++)
{
if (set2.find(*it) == set2.end())
{
changed = true;
break;
}
}
return changed;
}
bool compareDataChanged(const QList<T>& data1, const QList<T>& data2)
{
bool changed = false;
QSet<T> set1;
for (auto it = data1.begin(); it != data1.end(); it++) set1.insert(*it);
QSet<T> set2;
for (auto it = data2.begin(); it != data2.end() && !changed; it++)
{
if (set1.find(*it) == set1.end())
{
changed = true;
break;
}
set2.insert(*it);
}
for (auto it = set1.begin(); it != set1.end() && !changed; it++)
{
if (set2.find(*it) == set2.end())
{
changed = true;
break;
}
}
return changed;
}
protected:
QList<T> mDatas;
QSet<T> mAllDatas;
QSet<T> mAllDatas;
};
template <class T>
QuickModelBase<T>::QuickModelBase(QObject *parent)
QuickModelBase<T>::QuickModelBase(QObject* parent)
: Super(parent)
{
}
template <class T>
QuickModelBase<T>::QuickModelBase(const QList<T> &datas, QObject *parent)
QuickModelBase<T>::QuickModelBase(const QList<T>& datas, QObject* parent)
: Super(parent)
, mDatas(datas)
{
for (auto it = datas.begin(); it != datas.end(); it++) mAllDatas.insert(*it);
for (auto it = datas.begin(); it != datas.end(); it++)
mAllDatas.insert(*it);
}
template <class T>
QuickModelBase<T>::~QuickModelBase()
{
mDatas.clear();
mAllDatas.clear();
mAllDatas.clear();
}
template <class T>
int QuickModelBase<T>::rowCount(const QModelIndex &parent) const
int QuickModelBase<T>::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return mDatas.count();
}
template <class T>
QVariant QuickModelBase<T>::data(const QModelIndex &index, int role) const
QVariant QuickModelBase<T>::data(const QModelIndex& index, int role) const
{
if (index.row() < 0 || index.row() >= mDatas.size())
{
@ -133,20 +133,21 @@ QVariant QuickModelBase<T>::data(int row) const
return data(index(row), Qt::DisplayRole);
}
template <class T>
void QuickModelBase<T>::resetData(const QList<T> &datas)
void QuickModelBase<T>::resetData(const QList<T>& datas)
{
auto oldObjs = mAllDatas;
mAllDatas.clear();
auto oldObjs = mAllDatas;
mAllDatas.clear();
beginResetModel();
mDatas = datas;
for (auto it = datas.begin(); it != datas.end(); it++) mAllDatas.insert(*it);
for (auto it = datas.begin(); it != datas.end(); it++)
mAllDatas.insert(*it);
endResetModel();
qDeleteAll(oldObjs);
updateCalcInfo();
}
template <class T>
void QuickModelBase<T>::append(const QList<T> &datas)
void QuickModelBase<T>::append(const QList<T>& datas)
{
if (datas.count() <= 0)
{
@ -154,7 +155,8 @@ void QuickModelBase<T>::append(const QList<T> &datas)
}
beginInsertRows({}, mDatas.count(), mDatas.count() + datas.count() - 1);
mDatas.append(datas);
for (auto it = datas.begin(); it != datas.end(); it++) mAllDatas.insert(*it);
for (auto it = datas.begin(); it != datas.end(); it++)
mAllDatas.insert(*it);
endInsertRows();
updateCalcInfo();
}
@ -163,12 +165,12 @@ void QuickModelBase<T>::prepend(T data)
{
beginInsertRows({}, 0, 0);
mDatas.prepend(data);
mAllDatas.insert(data);
mAllDatas.insert(data);
endInsertRows();
updateCalcInfo();
}
template <class T>
void QuickModelBase<T>::insert(int row, const QList<T> &datas)
void QuickModelBase<T>::insert(int row, const QList<T>& datas)
{
if (row < 0 || row > mDatas.size())
{
@ -176,10 +178,10 @@ void QuickModelBase<T>::insert(int row, const QList<T> &datas)
}
beginInsertRows({}, row, row + datas.count() - 1);
int srow = row;
for (const auto &obj : datas)
for (const auto& obj : datas)
{
mDatas.insert(srow, obj);
mAllDatas.insert(obj);
mAllDatas.insert(obj);
srow++;
}
endInsertRows();
@ -188,19 +190,19 @@ void QuickModelBase<T>::insert(int row, const QList<T> &datas)
template <class T>
void QuickModelBase<T>::clear()
{
int mdatacount = mDatas.count();
int mdatacount = mDatas.count();
if (mdatacount > 0)
{
beginRemoveRows({}, 0, mdatacount - 1);
beginRemoveRows({}, 0, mdatacount - 1);
}
qDeleteAll(mAllDatas);
mDatas.clear();
mAllDatas.clear();
mAllDatas.clear();
if (mdatacount > 0)
{
endRemoveRows();
}
if (mdatacount > 0)
{
endRemoveRows();
}
updateCalcInfo();
}
template <class T>
@ -213,23 +215,23 @@ void QuickModelBase<T>::removeAt(int row)
beginRemoveRows({}, row, row);
auto obj = mDatas.at(row);
mDatas.removeAt(row);
mAllDatas.remove(obj);
mAllDatas.remove(obj);
endRemoveRows();
obj->deleteLater();
updateCalcInfo();
}
template <class T>
void QuickModelBase<T>::subtract(const QSet<T> &other)
void QuickModelBase<T>::subtract(const QSet<T>& other)
{
if (other.size() == 0)
return;
beginResetModel();
mAllDatas.subtract(other);
if (other.size() == 0)
return;
beginResetModel();
mAllDatas.subtract(other);
mDatas = mAllDatas.values();
endResetModel();
qDeleteAll(other);
updateCalcInfo();
endResetModel();
qDeleteAll(other);
updateCalcInfo();
}
template <class T>
@ -241,8 +243,8 @@ void QuickModelBase<T>::updateData(int row, T data)
}
auto oldObj = mDatas.at(row);
mDatas[row] = data;
mAllDatas.remove(oldObj);
mAllDatas.insert(data);
mAllDatas.remove(oldObj);
mAllDatas.insert(data);
emit dataChanged(index(row, 0), index(row, 0));
oldObj->deleteLater();
updateCalcInfo();

View File

@ -1,18 +1,18 @@
#pragma once
#include "TaoCommonGlobal.h"
#include <QObject>
#include <QVariant>
#include <QVector>
#include "TaoCommonGlobal.h"
class TAO_API QuickTreeItem : public QObject
{
Q_OBJECT
public:
explicit QuickTreeItem(QuickTreeItem *parentItem = nullptr)
explicit QuickTreeItem(QuickTreeItem* parentItem = nullptr)
: m_parentItem(parentItem)
{
}
explicit QuickTreeItem(const QVector<QVariant> &data, QuickTreeItem *parentItem = nullptr)
explicit QuickTreeItem(const QVector<QVariant>& data, QuickTreeItem* parentItem = nullptr)
: m_itemData(data)
, m_parentItem(parentItem)
{
@ -23,19 +23,19 @@ public:
qDeleteAll(m_childItems);
}
void appendChild(QuickTreeItem *child)
void appendChild(QuickTreeItem* child)
{
m_childItems.append(child);
}
void prependChild(QuickTreeItem *child)
{
void prependChild(QuickTreeItem* child)
{
m_childItems.prepend(child);
}
void appendChildren(const QVector<QuickTreeItem *> &children)
}
void appendChildren(const QVector<QuickTreeItem*>& children)
{
m_childItems.append(children);
}
void insert(int row, const QVector<QuickTreeItem *> &children)
void insert(int row, const QVector<QuickTreeItem*>& children)
{
if (0 <= row && 0 < m_childItems.size())
{
@ -45,7 +45,7 @@ public:
}
}
}
void insert(int row, QuickTreeItem *child)
void insert(int row, QuickTreeItem* child)
{
if (0 <= row && row < m_childItems.size())
{
@ -67,7 +67,7 @@ public:
}
}
QuickTreeItem *child(int row)
QuickTreeItem* child(int row)
{
if (row < 0 || row >= m_childItems.size())
return nullptr;
@ -90,11 +90,11 @@ public:
}
return {};
}
void setDatas(const QVector<QVariant> &datas)
void setDatas(const QVector<QVariant>& datas)
{
m_itemData = datas;
}
void setData(int index, const QVariant &data)
void setData(int index, const QVariant& data)
{
if (0 <= index && index < m_itemData.size())
{
@ -104,17 +104,17 @@ public:
int row() const
{
if (m_parentItem)
return m_parentItem->m_childItems.indexOf(const_cast<QuickTreeItem *>(this));
return m_parentItem->m_childItems.indexOf(const_cast<QuickTreeItem*>(this));
return 0;
}
QuickTreeItem *parentItem() const
QuickTreeItem* parentItem() const
{
return m_parentItem;
}
private:
QVector<QuickTreeItem *> m_childItems;
QVector<QVariant> m_itemData;
QuickTreeItem * m_parentItem = nullptr;
QVector<QuickTreeItem*> m_childItems;
QVector<QVariant> m_itemData;
QuickTreeItem* m_parentItem = nullptr;
};

View File

@ -1,5 +1,6 @@
#include "QuickTreeModel.h"
QuickTreeModel::QuickTreeModel(QObject *parent) :QAbstractItemModel(parent)
QuickTreeModel::QuickTreeModel(QObject* parent)
: QAbstractItemModel(parent)
{
m_rootItem = new QuickTreeItem(nullptr);
QVector<QVariant> datas;
@ -15,7 +16,7 @@ QuickTreeModel::~QuickTreeModel()
delete m_rootItem;
}
QVariant QuickTreeModel::data(const QModelIndex &index, int role) const
QVariant QuickTreeModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
@ -23,17 +24,17 @@ QVariant QuickTreeModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole)
return QVariant();
QuickTreeItem *item = static_cast<QuickTreeItem*>(index.internalPointer());
QuickTreeItem* item = static_cast<QuickTreeItem*>(index.internalPointer());
return item->data(index.column());
}
Qt::ItemFlags QuickTreeModel::flags(const QModelIndex &index) const
Qt::ItemFlags QuickTreeModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::NoItemFlags;
return QAbstractItemModel::flags(index);
return QAbstractItemModel::flags(index);
}
QVariant QuickTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
@ -44,31 +45,31 @@ QVariant QuickTreeModel::headerData(int section, Qt::Orientation orientation, in
return QVariant();
}
QModelIndex QuickTreeModel::index(int row, int column, const QModelIndex &parent) const
QModelIndex QuickTreeModel::index(int row, int column, const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
QuickTreeItem *parentItem;
QuickTreeItem* parentItem;
if (!parent.isValid())
parentItem = m_rootItem;
else
parentItem = static_cast<QuickTreeItem*>(parent.internalPointer());
QuickTreeItem *childItem = parentItem->child(row);
QuickTreeItem* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
return QModelIndex();
}
QModelIndex QuickTreeModel::parent(const QModelIndex &index) const
QModelIndex QuickTreeModel::parent(const QModelIndex& index) const
{
if (!index.isValid())
return QModelIndex();
QuickTreeItem *childItem = static_cast<QuickTreeItem*>(index.internalPointer());
QuickTreeItem *parentItem = childItem->parentItem();
QuickTreeItem* childItem = static_cast<QuickTreeItem*>(index.internalPointer());
QuickTreeItem* parentItem = childItem->parentItem();
if (parentItem == m_rootItem)
return QModelIndex();
@ -76,9 +77,9 @@ QModelIndex QuickTreeModel::parent(const QModelIndex &index) const
return createIndex(parentItem->row(), 0, parentItem);
}
int QuickTreeModel::rowCount(const QModelIndex &parent) const
int QuickTreeModel::rowCount(const QModelIndex& parent) const
{
QuickTreeItem *parentItem;
QuickTreeItem* parentItem;
if (parent.column() > 0)
return 0;
@ -90,7 +91,7 @@ int QuickTreeModel::rowCount(const QModelIndex &parent) const
return parentItem->childCount();
}
int QuickTreeModel::columnCount(const QModelIndex &parent) const
int QuickTreeModel::columnCount(const QModelIndex& parent) const
{
if (parent.isValid())
return static_cast<QuickTreeItem*>(parent.internalPointer())->columnCount();

View File

@ -1,47 +1,47 @@
#pragma once
#include "QuickTreeItem.h"
#include "TaoCommonGlobal.h"
#include <QAbstractItemModel>
#include <QSet>
#include <QVector>
#include "TaoCommonGlobal.h"
#include "QuickTreeItem.h"
class TAO_API QuickTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit QuickTreeModel(QObject *parent = nullptr);
explicit QuickTreeModel(QObject* parent = nullptr);
~QuickTreeModel();
QuickTreeItem *rootItem() const
QuickTreeItem* rootItem() const
{
return m_rootItem;
}
QVariant data(const QModelIndex &index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex& index) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
//[begin] add data
void appendChild(QuickTreeItem *data)
void appendChild(QuickTreeItem* data)
{
beginInsertRows({}, m_rootItem->childCount(), m_rootItem->childCount() + 1);
m_rootItem->appendChild(data);
endInsertRows();
}
void appendChildren(const QVector<QuickTreeItem *> &datas)
void appendChildren(const QVector<QuickTreeItem*>& datas)
{
beginInsertRows({}, m_rootItem->childCount(), m_rootItem->childCount() + datas.size() - 1);
m_rootItem->appendChildren(datas);
endInsertRows();
}
void prependChild(QuickTreeItem *data)
{
void prependChild(QuickTreeItem* data)
{
beginInsertRows({}, 0, 0);
m_rootItem->prependChild(data);
endInsertRows();
}
void insert(int row, const QVector<QuickTreeItem *> &datas)
}
void insert(int row, const QVector<QuickTreeItem*>& datas)
{
if (row < 0 || row > m_rootItem->childCount())
{
@ -83,5 +83,5 @@ public:
// //[end] update data
private:
QuickTreeItem *m_rootItem;
QuickTreeItem* m_rootItem;
};

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
# else
# define TAO_API Q_DECL_IMPORT
# endif
#if defined(TaoCommon_Library)
#define TAO_API Q_DECL_EXPORT
#else
# define TAO_API
#define TAO_API Q_DECL_IMPORT
#endif
#else
#define TAO_API
#endif

View File

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

View File

@ -1,19 +1,23 @@
#include "ThreadPool.h"
#include <QThreadPool>
namespace TaoCommon {
ThreadObject::ThreadObject(const WorkCallback &work) : m_workCall(work) {}
namespace TaoCommon
{
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)
void ThreadPool::work(const WorkCallback& workCall, const WorkResultCallback& resultCall)
{
ThreadObject *obj = new ThreadObject(workCall);
ThreadObject* obj = new ThreadObject(workCall);
obj->setAutoDelete(true);
connect(obj, &ThreadObject::readyResult, this, resultCall);
QThreadPool::globalInstance()->start(obj);
}
}
} // namespace TaoCommon

View File

@ -3,17 +3,20 @@
#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
class ThreadObject
: public QObject
, public QRunnable
{
Q_OBJECT
public:
explicit ThreadObject(const WorkCallback &work);
explicit ThreadObject(const WorkCallback& work);
void run() override;
signals:
void readyResult(bool);
@ -25,15 +28,15 @@ class TAO_API ThreadPool : public QObject
{
Q_OBJECT
public:
static ThreadPool *getInstance()
static ThreadPool* getInstance()
{
static ThreadPool poll;
return &poll;
}
// workCall in sub thread, resultCall in main thread
void work(const WorkCallback &workCall, const WorkResultCallback &resultCall);
void work(const WorkCallback& workCall, const WorkResultCallback& resultCall);
private:
ThreadPool() {}
ThreadPool() { }
};
} // namespace TaoCommon

View File

@ -3,7 +3,8 @@
#include "ThreadCommon.h"
#include <QMap>
#include <QThread>
namespace TaoCommon {
namespace TaoCommon
{
// 对Qt Worker-Controller 线程模型的简单封装,适合精确控制的任务。
// 用法: ThreadController::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
@ -13,8 +14,10 @@ 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)
ThreadWorker(uint64_t id, const WorkCallback& workCall, QObject* parent = nullptr)
: QObject(parent)
, m_id(id)
, m_workCall(workCall)
{
}
@ -35,7 +38,7 @@ class TAO_API ThreadController : public QObject
{
Q_OBJECT
public:
static ThreadController *getInstance()
static ThreadController* getInstance()
{
static ThreadController controller;
return &controller;
@ -43,8 +46,10 @@ public:
~ThreadController()
{
for (const auto &k : m_threadMap.keys()) {
if (m_threadMap.value(k)->isRunning()) {
for (const auto& k : m_threadMap.keys())
{
if (m_threadMap.value(k)->isRunning())
{
m_threadMap.value(k)->quit();
m_threadMap.value(k)->wait();
}
@ -53,27 +58,28 @@ public:
m_threadMap.clear();
m_resultCallback.clear();
}
uint64_t work(const WorkCallback &workCall, const WorkResultCallback &resultCall)
uint64_t work(const WorkCallback& workCall, const WorkResultCallback& resultCall)
{
QThread *thread = new QThread;
QThread* thread = new QThread;
m_rollId++;
ThreadWorker *obj = new ThreadWorker(m_rollId, workCall);
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);
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()) {
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->terminate();
}
}
@ -82,8 +88,10 @@ public:
void quit(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end()) {
if ((*it)->isRunning()) {
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
@ -91,13 +99,18 @@ public:
}
m_resultCallback.remove(id);
}
QList<uint64_t> getAllWorkId() const { return m_threadMap.keys(); }
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()) {
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
@ -105,18 +118,22 @@ protected slots:
m_threadMap.remove(id);
}
auto caller = m_resultCallback.find(id);
if (caller != m_resultCallback.end()) {
if (caller != m_resultCallback.end())
{
(*caller)(ok);
m_resultCallback.remove(id);
}
}
protected:
ThreadController(QObject *parent = nullptr) : QObject(parent) {}
ThreadController(QObject* parent = nullptr)
: QObject(parent)
{
}
private:
uint64_t m_rollId = 0;
QMap<uint64_t, QThread *> m_threadMap;
QMap<uint64_t, QThread*> m_threadMap;
QMap<uint64_t, WorkResultCallback> m_resultCallback;
};
} // namespace LCIM
} // namespace TaoCommon

View File

@ -1,31 +1,36 @@
#include "Trans.h"
#include "Common/FileReadWrite.h"
#include <QDir>
#include <QQmlContext>
#include <QCoreApplication>
#include <QDir>
#include <QLocale>
#include <QQuickView>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickView>
const static auto cEnglisthStr = u8"English";
const static auto cChineseStr = u8"简体中文";
Trans::Trans(QObject *parent) : QTranslator(parent) {}
Trans::Trans(QObject* parent)
: QTranslator(parent)
{
}
void Trans::beforeUiReady(QQmlContext *ctx, const QString &folder)
void Trans::beforeUiReady(QQmlContext* ctx, const QString& folder)
{
m_ctx = ctx;
ctx->setContextProperty("trans", this);
if (folder.isEmpty()) {
if (folder.isEmpty())
{
loadFolder(qApp->applicationDirPath() + "/Trans");
} else {
}
else
{
loadFolder(folder);
}
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)
@ -34,41 +39,48 @@ 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)
{
qWarning() << "Trans loadFolder" << folder;
QDir dir(folder);
auto infos = dir.entryInfoList({ "language_*.json" }, QDir::Files);
QString lang;
for (const auto &info : infos) {
for (const auto& info : infos)
{
load(lang, info.absoluteFilePath());
}
initEnglish();
auto langs = m_map.keys();
if (langs.contains(cChineseStr)) {
if (langs.contains(cChineseStr))
{
langs.removeAll(cChineseStr);
langs.push_front(cChineseStr);
}
setLanguages(langs);
if (m_map.contains(cChineseStr)) {
if (m_map.contains(cChineseStr))
{
setCurrentLang(cChineseStr);
} else {
}
else
{
setCurrentLang(cEnglisthStr);
}
emit folderLoaded(folder);
}
bool Trans::load(QString &lang, const QString &filePath)
bool Trans::load(QString& lang, const QString& filePath)
{
lang.clear();
QJsonObject rootObj;
if (!TaoCommon::readJsonFile(filePath, rootObj)) {
if (!TaoCommon::readJsonFile(filePath, rootObj))
{
return false;
}
lang = rootObj.value("lang").toString();
const auto &trans = rootObj.value("trans").toArray();
for (const 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,42 +90,47 @@ 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;
}
void Trans::initEnglish()
{
if (!m_map.contains(cEnglisthStr)) {
if (!m_map.contains(cEnglisthStr))
{
QHash<QString, QString> map;
if (m_map.contains(cChineseStr)) {
if (m_map.contains(cChineseStr))
{
map = m_map.value(cChineseStr);
} else {
}
else
{
map = m_map.value(m_map.keys().first());
}
for (const 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;
@ -128,7 +145,7 @@ void Trans::setCurrentLang(const QString &currentLang)
#endif
}
void Trans::setLanguages(const QStringList &languages)
void Trans::setLanguages(const QStringList& languages)
{
if (m_languages == languages)
return;

View File

@ -1,11 +1,11 @@
#pragma once
#include <QObject>
#include "TaoCommonGlobal.h"
#include <QHash>
#include <QList>
#include <QObject>
#include <QString>
#include <QTranslator>
#include "TaoCommonGlobal.h"
class QQmlContext;
class TAO_API Trans : public QTranslator
{
@ -14,43 +14,42 @@ class TAO_API Trans : public QTranslator
Q_PROPERTY(QStringList languages READ languages NOTIFY languagesChanged)
Q_PROPERTY(QString transString READ transString NOTIFY transStringChanged)
public:
Trans(QObject *parent = nullptr);
Trans(QObject* parent = nullptr);
Q_INVOKABLE void loadFolder(const QString &folder);
Q_INVOKABLE void loadFolder(const QString& folder);
Q_INVOKABLE bool load(QString &lang, const QString &filePath);
Q_INVOKABLE bool load(QString& lang, const QString& filePath);
public:
void beforeUiReady(QQmlContext *ctx, const QString &folder = {});
void beforeUiReady(QQmlContext* ctx, const QString& folder = {});
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 QString& currentLang() const;
const QStringList &languages() const;
const QStringList& languages() const;
const QString &transString() const;
const QString& transString() const;
public slots:
QString trans(const QString &source) const;
void setCurrentLang(const QString &currentLang);
QString trans(const QString& source) const;
void setCurrentLang(const QString& currentLang);
signals:
void currentLangChanged(const QString &currentLang);
void currentLangChanged(const QString& currentLang);
void languagesChanged(const QStringList &languages);
void languagesChanged(const QStringList& languages);
void langLoaded(const QString &lang);
void langLoaded(const QString& lang);
void folderLoaded(const QString &folder);
void folderLoaded(const QString& folder);
void transStringChanged();
protected:
void setLanguages(const QStringList &languages);
void setLanguages(const QStringList& languages);
void initEnglish();
@ -60,5 +59,5 @@ private:
QHash<QString, QHash<QString, QString>> m_map;
QStringList m_languages;
QString m_transString;
QQmlContext *m_ctx = nullptr;
QQmlContext* m_ctx = nullptr;
};

8
clang-foramt-All.ps1 Normal file
View File

@ -0,0 +1,8 @@
$scriptDir=$PSScriptRoot
$currentDir=Get-Location
Write-Host "currentDir" $currentDir
Write-Host "scriptDir" $scriptDir
$names="*.h","*.cpp","*.c","*.hpp"
Get-ChildItem -Include $names -Recurse $currentDir | ForEach-Object {
clang-format -i $_.FullName
}

View File

@ -1,16 +1,16 @@
#include <QQuickView>
#include <QQmlEngine>
#include <QQmlContext>
#include <QGuiApplication>
int main(int argc, char **argv)
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickView>
int main(int argc, char** argv)
{
QGuiApplication app(argc, argv);
QQuickView view;
view.engine()->addImportPath(TaoQuickImportPath);
view.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImagePath);
QGuiApplication app(argc, argv);
QQuickView view;
view.engine()->addImportPath(TaoQuickImportPath);
view.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImagePath);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}

View File

@ -1,22 +1,26 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath(TaoQuickImportPath);
engine.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImagePath);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
QQmlApplicationEngine engine;
engine.addImportPath(TaoQuickImportPath);
engine.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImagePath);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject* obj, const QUrl& objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
return app.exec();
}

View File

@ -1,35 +1,31 @@
#include "AppInfo.h"
#include "Ver-u8.h"
#include <QQmlContext>
#include <QSysInfo>
#include "Ver-u8.h"
AppInfo::AppInfo(QObject *parent) : QObject(parent)
AppInfo::AppInfo(QObject* parent)
: QObject(parent)
{
m_appName = VER_PRODUCTNAME_STR;
m_appVersion = TaoVer;
m_latestVersion = TaoVer;
m_buildDateTime = TaoDATETIME;
m_buildRevision = TaoREVISIONSTR;
m_copyRight = VER_LEGALCOPYRIGHT_STR;
m_descript = QString::fromLocal8Bit(VER_FILEDESCRIPTION_STR);
m_compilerVendor = QString("%1(%2 %3)").arg(QT_VERSION_STR).arg(CXX_COMPILER_ID).arg(QSysInfo::buildCpuArchitecture());
m_appName = VER_PRODUCTNAME_STR;
m_appVersion = TaoVer;
m_latestVersion = TaoVer;
m_buildDateTime = TaoDATETIME;
m_buildRevision = TaoREVISIONSTR;
m_copyRight = VER_LEGALCOPYRIGHT_STR;
m_descript = QString::fromLocal8Bit(VER_FILEDESCRIPTION_STR);
m_compilerVendor = QString("%1(%2 %3)").arg(QT_VERSION_STR).arg(CXX_COMPILER_ID).arg(QSysInfo::buildCpuArchitecture());
}
void AppInfo::beforeUiReady(QQmlContext *ctx)
void AppInfo::beforeUiReady(QQmlContext* ctx)
{
ctx->setContextProperty("appInfo", this);
ctx->setContextProperty("appInfo", this);
}
void AppInfo::afterUiReady()
{
// auto json = QJsonDocument(*this).toJson(QJsonDocument::Indented);
// json.replace("\\n\\r","\\\n");
// qWarning() << json;
// auto json = QJsonDocument(*this).toJson(QJsonDocument::Indented);
// json.replace("\\n\\r","\\\n");
// qWarning() << json;
}
AppInfo::~AppInfo()
{
}
AppInfo::~AppInfo() { }

View File

@ -1,78 +1,47 @@
#pragma once
#include <QObject>
#include <QString>
#include <QQmlContext>
#include "Common/PropertyHelper.h"
#include "Common/JsonSerialize.h"
#include "Common/PropertyHelper.h"
#include <QObject>
#include <QQmlContext>
#include <QString>
class AppInfo : public QObject
{
Q_OBJECT
Q_OBJECT
AUTO_PROPERTY(QString, appName, "")
AUTO_PROPERTY(QString, appVersion, "")
AUTO_PROPERTY(QString, latestVersion, "")
AUTO_PROPERTY(QString, buildDateTime, "")
AUTO_PROPERTY(QString, buildRevision, "")
AUTO_PROPERTY(QString, copyRight, "")
AUTO_PROPERTY(QString, descript, "")
AUTO_PROPERTY(QString, compilerVendor, "")
AUTO_PROPERTY(bool, splashShow, false)
AUTO_PROPERTY(float, scale, 1.0f)
AUTO_PROPERTY(double, ratio, 14.0 / 9.0)
AUTO_PROPERTY(QStringList, customs, {})
AUTO_PROPERTY(QString, appName, "")
AUTO_PROPERTY(QString, appVersion, "")
AUTO_PROPERTY(QString, latestVersion, "")
AUTO_PROPERTY(QString, buildDateTime, "")
AUTO_PROPERTY(QString, buildRevision, "")
AUTO_PROPERTY(QString, copyRight, "")
AUTO_PROPERTY(QString, descript, "")
AUTO_PROPERTY(QString, compilerVendor, "")
AUTO_PROPERTY(bool, splashShow, false)
AUTO_PROPERTY(float, scale, 1.0f)
AUTO_PROPERTY(double, ratio, 14.0 / 9.0)
AUTO_PROPERTY(QStringList, customs, {})
JsonSerialize_Begin()
JsonProperty(appName)
JsonProperty(appVersion)
JsonProperty(latestVersion)
JsonProperty(buildDateTime)
JsonProperty(buildRevision)
JsonProperty(copyRight)
JsonProperty(descript)
JsonProperty(compilerVendor)
JsonProperty(splashShow)
JsonProperty(scale)
JsonProperty(ratio)
JsonContainerProperty(customs)
JsonSerialize_End()
JsonSerialize_Begin() JsonProperty(appName) JsonProperty(appVersion) JsonProperty(latestVersion) JsonProperty(buildDateTime) JsonProperty(buildRevision)
JsonProperty(copyRight) JsonProperty(descript) JsonProperty(compilerVendor) JsonProperty(splashShow) JsonProperty(scale) JsonProperty(ratio)
JsonContainerProperty(customs) JsonSerialize_End()
JsonDeserialize_Begin(AppInfo)
JsonDeserializeProperty(appName)
JsonDeserializeProperty(appVersion)
JsonDeserializeProperty(latestVersion)
JsonDeserializeProperty(buildDateTime)
JsonDeserializeProperty(buildRevision)
JsonDeserializeProperty(copyRight)
JsonDeserializeProperty(descript)
JsonDeserializeProperty(compilerVendor)
JsonDeserializeProperty(splashShow)
JsonDeserializeProperty(scale)
JsonDeserializeProperty(ratio)
JsonDeserializeContainerProperty(customs)
JsonDeserialize_End()
JsonDeserialize_Begin(AppInfo) JsonDeserializeProperty(appName) JsonDeserializeProperty(appVersion) JsonDeserializeProperty(latestVersion)
JsonDeserializeProperty(buildDateTime) JsonDeserializeProperty(buildRevision) JsonDeserializeProperty(copyRight)
JsonDeserializeProperty(descript) JsonDeserializeProperty(compilerVendor) JsonDeserializeProperty(splashShow)
JsonDeserializeProperty(scale) JsonDeserializeProperty(ratio) JsonDeserializeContainerProperty(customs) JsonDeserialize_End()
JsonPartialDeserialize_Begin(AppInfo) JsonDeserializeProperty(appName) JsonDeserializeProperty(appVersion)
JsonDeserializeProperty(latestVersion) JsonDeserializeProperty(buildDateTime) JsonDeserializeProperty(buildRevision)
JsonDeserializeProperty(copyRight) JsonDeserializeProperty(descript) JsonDeserializeProperty(compilerVendor)
JsonDeserializeProperty(splashShow) JsonDeserializeProperty(scale) JsonDeserializeProperty(ratio)
JsonDeserializeContainerProperty(customs) JsonPartialDeserialize_End()
JsonPartialDeserialize_Begin(AppInfo)
JsonDeserializeProperty(appName)
JsonDeserializeProperty(appVersion)
JsonDeserializeProperty(latestVersion)
JsonDeserializeProperty(buildDateTime)
JsonDeserializeProperty(buildRevision)
JsonDeserializeProperty(copyRight)
JsonDeserializeProperty(descript)
JsonDeserializeProperty(compilerVendor)
JsonDeserializeProperty(splashShow)
JsonDeserializeProperty(scale)
JsonDeserializeProperty(ratio)
JsonDeserializeContainerProperty(customs)
JsonPartialDeserialize_End()
public : explicit AppInfo(QObject* parent = nullptr);
virtual ~AppInfo() override;
public:
explicit AppInfo(QObject *parent = nullptr);
virtual ~AppInfo() override;
public:
void beforeUiReady(QQmlContext *ctx);
void beforeUiReady(QQmlContext* ctx);
void afterUiReady();
void afterUiReady();
};

View File

@ -1,24 +1,29 @@
#include "DeviceAddItem.h"
#include <QHostAddress>
DeviceAddItem::DeviceAddItem(QObject *parent) : QuickListItemBase(parent)
DeviceAddItem::DeviceAddItem(QObject* parent)
: QuickListItemBase(parent)
{
connect(this, &DeviceAddItem::addressChanged, this, [this]() { m_ipv4Address = QHostAddress(address()).toIPv4Address(); });
connect(this, &DeviceAddItem::addressChanged, this, [this]() { m_ipv4Address = QHostAddress(address()).toIPv4Address(); });
}
DeviceAddItem::~DeviceAddItem() { }
bool DeviceAddItem::match(const QString &key)
bool DeviceAddItem::match(const QString& key)
{
if (key.isEmpty()) {
return true;
}
if (m_name.contains(key, Qt::CaseInsensitive)) {
return true;
}
if (m_address.contains(key, Qt::CaseInsensitive)) {
return true;
}
if (m_modelString.contains(key, Qt::CaseInsensitive)) {
return true;
}
return false;
if (key.isEmpty())
{
return true;
}
if (m_name.contains(key, Qt::CaseInsensitive))
{
return true;
}
if (m_address.contains(key, Qt::CaseInsensitive))
{
return true;
}
if (m_modelString.contains(key, Qt::CaseInsensitive))
{
return true;
}
return false;
}

View File

@ -5,20 +5,23 @@
#include <QObject>
class DeviceAddItem : public QuickListItemBase
{
Q_OBJECT
Q_OBJECT
AUTO_PROPERTY(QString, name, "")
AUTO_PROPERTY(QString, address, "")
AUTO_PROPERTY(QString, modelString, "")
AUTO_PROPERTY(bool, online, false)
AUTO_PROPERTY(QString, name, "")
AUTO_PROPERTY(QString, address, "")
AUTO_PROPERTY(QString, modelString, "")
AUTO_PROPERTY(bool, online, false)
public:
explicit DeviceAddItem(QObject *parent = nullptr);
virtual ~DeviceAddItem() override;
explicit DeviceAddItem(QObject* parent = nullptr);
virtual ~DeviceAddItem() override;
bool match(const QString &key) override;
quint32 toIPv4Address() const { return m_ipv4Address; }
bool match(const QString& key) override;
quint32 toIPv4Address() const
{
return m_ipv4Address;
}
private:
quint32 m_ipv4Address = 0;
quint32 m_ipv4Address = 0;
};

View File

@ -2,233 +2,265 @@
#include "DeviceAddItem.h"
#include <QCoreApplication>
#include <QEventLoop>
#include <QHostAddress>
#include <QFile>
#include <QHostAddress>
#include <QString>
#include <chrono>
#include <random>
const static QString nameTemplate("item %1");
const static QString ipTemplate("%1.%2.%3.%4");
const static QString modelTemplate("model %1");
const static QString nameTemplate("item %1");
const static QString ipTemplate("%1.%2.%3.%4");
const static QString modelTemplate("model %1");
const static QStringList sHeaderRoles = { "name", "address", "modelString" };
class DeviceAddModelPrivate
{
public:
std::default_random_engine randomEngine;
std::uniform_int_distribution<uint32_t> u65535 { 0, 0xffffffff };
std::default_random_engine randomEngine;
std::uniform_int_distribution<uint32_t> u65535 { 0, 0xffffffff };
};
DeviceAddModel::DeviceAddModel(QObject *parent) : QuickListModel(parent), d(new DeviceAddModelPrivate)
DeviceAddModel::DeviceAddModel(QObject* parent)
: QuickListModel(parent)
, d(new DeviceAddModelPrivate)
{
setHeaderRoles(sHeaderRoles);
setHeaderRoles(sHeaderRoles);
}
DeviceAddModel::~DeviceAddModel()
{
delete d;
delete d;
}
void DeviceAddModel::sortByRole()
{
if (mDatas.count() <= 1) {
return;
}
int index = sHeaderRoles.indexOf(mSortRole);
switch (index) {
case 0: {
sortByName(mSortOrder);
break;
}
case 1: {
sortByAddress(mSortOrder);
break;
}
case 2: {
sortByModel(mSortOrder);
break;
}
default:
break;
}
updateAlternate();
if (mDatas.count() <= 1)
{
return;
}
int index = sHeaderRoles.indexOf(mSortRole);
switch (index)
{
case 0:
{
sortByName(mSortOrder);
break;
}
case 1:
{
sortByAddress(mSortOrder);
break;
}
case 2:
{
sortByModel(mSortOrder);
break;
}
default:
break;
}
updateAlternate();
}
void DeviceAddModel::initData()
{
const int N = 50000;
const int N = 50000;
QList<QuickListItemBase *> objs;
objs.reserve(N);
auto c1 = std::chrono::high_resolution_clock::now();
QList<QuickListItemBase*> objs;
objs.reserve(N);
auto c1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) {
auto item = genOne(i);
objs.append(item);
// if (i % 5 == 0)
// {
// qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
// }
}
for (int i = 0; i < N; ++i)
{
auto item = genOne(i);
objs.append(item);
// if (i % 5 == 0)
// {
// qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
// }
}
auto c2 = std::chrono::high_resolution_clock::now();
auto micro = std::chrono::duration_cast<std::chrono::milliseconds>(c2 - c1).count();
qWarning() << "general" << N << "cost" << micro << "ms";
resetData(objs);
auto c2 = std::chrono::high_resolution_clock::now();
auto micro = std::chrono::duration_cast<std::chrono::milliseconds>(c2 - c1).count();
qWarning() << "general" << N << "cost" << micro << "ms";
resetData(objs);
}
void DeviceAddModel::addOne()
{
auto item = genOne(d->u65535(d->randomEngine));
append({ item });
auto item = genOne(d->u65535(d->randomEngine));
append({ item });
}
void DeviceAddModel::addMulti(int count)
{
QList<QuickListItemBase *> objs;
objs.reserve(count);
QList<QuickListItemBase*> objs;
objs.reserve(count);
for (int i = 0; i < count; ++i) {
auto item = genOne(d->u65535(d->randomEngine));
objs.push_back(item);
// if (i % 5 == 0)
// {
// qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
// }
}
append(objs);
for (int i = 0; i < count; ++i)
{
auto item = genOne(d->u65535(d->randomEngine));
objs.push_back(item);
// if (i % 5 == 0)
// {
// qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
// }
}
append(objs);
}
void DeviceAddModel::insertBeforeSelected()
{
if (mDatas.count() <= 0) {
auto item = genOne(d->u65535(d->randomEngine));
insert(0, { item });
} else {
int pos = -1;
for (int i = 0; i < mDatas.count(); ++i) {
const auto &obj = mDatas.at(i);
if (obj->isVisible() && obj->isSelected()) {
pos = i;
break;
}
}
if (pos >= 0) {
auto item = genOne(d->u65535(d->randomEngine));
insert(pos, { item });
}
}
if (mDatas.count() <= 0)
{
auto item = genOne(d->u65535(d->randomEngine));
insert(0, { item });
}
else
{
int pos = -1;
for (int i = 0; i < mDatas.count(); ++i)
{
const auto& obj = mDatas.at(i);
if (obj->isVisible() && obj->isSelected())
{
pos = i;
break;
}
}
if (pos >= 0)
{
auto item = genOne(d->u65535(d->randomEngine));
insert(pos, { item });
}
}
}
void DeviceAddModel::insertBeforeRow(int row)
{
auto item = genOne(d->u65535(d->randomEngine));
insert(row, { item });
auto item = genOne(d->u65535(d->randomEngine));
insert(row, { item });
}
void DeviceAddModel::clearAll()
{
clear();
clear();
}
void DeviceAddModel::removeSelected()
{
for (int i = 0; i < mDatas.count();) {
const auto &obj = mDatas.at(i);
if (obj->isVisible() && obj->isSelected()) {
removeAt(i);
} else {
++i;
}
}
for (int i = 0; i < mDatas.count();)
{
const auto& obj = mDatas.at(i);
if (obj->isVisible() && obj->isSelected())
{
removeAt(i);
}
else
{
++i;
}
}
}
void DeviceAddModel::removeChecked()
{
for (int i = 0; i < mDatas.count();) {
const auto &obj = mDatas.at(i);
if (obj->isVisible() && obj->isChecked()) {
removeAt(i);
} else {
++i;
}
}
for (int i = 0; i < mDatas.count();)
{
const auto& obj = mDatas.at(i);
if (obj->isVisible() && obj->isChecked())
{
removeAt(i);
}
else
{
++i;
}
}
}
void DeviceAddModel::removeRow(int row)
{
removeAt(row);
removeAt(row);
}
void DeviceAddModel::sortByName(Qt::SortOrder order)
{
QList<QuickListItemBase *> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder) {
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return (static_cast<DeviceAddItem *>(obj1))->name() < (static_cast<DeviceAddItem *>(obj2))->name();
});
} else {
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return (static_cast<DeviceAddItem *>(obj1))->name() > (static_cast<DeviceAddItem *>(obj2))->name();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
QList<QuickListItemBase*> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder)
{
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return (static_cast<DeviceAddItem*>(obj1))->name() < (static_cast<DeviceAddItem*>(obj2))->name();
});
}
else
{
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return (static_cast<DeviceAddItem*>(obj1))->name() > (static_cast<DeviceAddItem*>(obj2))->name();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
}
void DeviceAddModel::sortByAddress(Qt::SortOrder order)
{
QList<QuickListItemBase *> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder) {
std::sort(copyObjs.begin(), copyObjs.end(), [=](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return static_cast<DeviceAddItem *>(obj1)->toIPv4Address() < static_cast<DeviceAddItem *>(obj2)->toIPv4Address();
});
} else {
std::sort(copyObjs.begin(), copyObjs.end(), [=](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return static_cast<DeviceAddItem *>(obj1)->toIPv4Address() > static_cast<DeviceAddItem *>(obj2)->toIPv4Address();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
QList<QuickListItemBase*> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder)
{
std::sort(copyObjs.begin(), copyObjs.end(), [=](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return static_cast<DeviceAddItem*>(obj1)->toIPv4Address() < static_cast<DeviceAddItem*>(obj2)->toIPv4Address();
});
}
else
{
std::sort(copyObjs.begin(), copyObjs.end(), [=](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return static_cast<DeviceAddItem*>(obj1)->toIPv4Address() > static_cast<DeviceAddItem*>(obj2)->toIPv4Address();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
}
void DeviceAddModel::sortByModel(Qt::SortOrder order)
{
QList<QuickListItemBase *> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder) {
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return (static_cast<DeviceAddItem *>(obj1))->modelString().toULongLong() < (static_cast<DeviceAddItem *>(obj2))->modelString().toULongLong();
});
} else {
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase *obj1, QuickListItemBase *obj2) -> bool {
return (static_cast<DeviceAddItem *>(obj1))->modelString().toULongLong() > (static_cast<DeviceAddItem *>(obj2))->modelString().toULongLong();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
QList<QuickListItemBase*> copyObjs = mDatas;
if (order == Qt::SortOrder::AscendingOrder)
{
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return (static_cast<DeviceAddItem*>(obj1))->modelString().toULongLong() < (static_cast<DeviceAddItem*>(obj2))->modelString().toULongLong();
});
}
else
{
std::sort(copyObjs.begin(), copyObjs.end(), [](QuickListItemBase* obj1, QuickListItemBase* obj2) -> bool {
return (static_cast<DeviceAddItem*>(obj1))->modelString().toULongLong() > (static_cast<DeviceAddItem*>(obj2))->modelString().toULongLong();
});
}
mDatas = copyObjs;
emit dataChanged(index(0, 0), index(mDatas.count() - 1, 0));
}
DeviceAddItem *DeviceAddModel::genOne(uint32_t value)
DeviceAddItem* DeviceAddModel::genOne(uint32_t value)
{
auto item = new DeviceAddItem;
item->set_online(value % 2 == 0);
item->set_name(nameTemplate.arg(value));
auto item = new DeviceAddItem;
item->set_online(value % 2 == 0);
item->set_name(nameTemplate.arg(value));
int ip4 = value % 256;
int ip3 = value / 256 % 256;
int ip2 = value / 256 / 256 % 256;
int ip1 = value / 256 / 256 / 256 % 256;
item->set_address(ipTemplate.arg(ip1).arg(ip2).arg(ip3).arg(ip4));
item->set_modelString(modelTemplate.arg(value % 2 == 0 ? value : 0xffffffff - value));
return item;
int ip4 = value % 256;
int ip3 = value / 256 % 256;
int ip2 = value / 256 / 256 % 256;
int ip1 = value / 256 / 256 / 256 % 256;
item->set_address(ipTemplate.arg(ip1).arg(ip2).arg(ip3).arg(ip4));
item->set_modelString(modelTemplate.arg(value % 2 == 0 ? value : 0xffffffff - value));
return item;
}
void DeviceAddModel::doUpdateName(int row, const QString &name)
void DeviceAddModel::doUpdateName(int row, const QString& name)
{
if (row < 0 || row >= rowCount({})) {
return;
}
const auto &n = name.simplified();
if (n.isEmpty()) {
return;
}
static_cast<DeviceAddItem *>(mDatas.at(row))->set_name(name);
if (row < 0 || row >= rowCount({}))
{
return;
}
const auto& n = name.simplified();
if (n.isEmpty())
{
return;
}
static_cast<DeviceAddItem*>(mDatas.at(row))->set_name(name);
}

View File

@ -1,38 +1,40 @@
#pragma once
#include <QObject>
#include "QuickModel/QuickListModel.h"
#include <QObject>
class DeviceAddModelPrivate;
class DeviceAddItem;
class DeviceAddModel : public QuickListModel
{
Q_OBJECT
Q_OBJECT
public:
explicit DeviceAddModel(QObject *parent = nullptr);
virtual ~DeviceAddModel() override;
Q_INVOKABLE virtual void sortByRole() override;
explicit DeviceAddModel(QObject* parent = nullptr);
virtual ~DeviceAddModel() override;
Q_INVOKABLE virtual void sortByRole() override;
public slots:
void doUpdateName(int row, const QString &name);
void doUpdateName(int row, const QString& name);
void initData();
void initData();
void addOne();
void addMulti(int count);
void addOne();
void addMulti(int count);
void insertBeforeSelected();
void insertBeforeRow(int row);
void insertBeforeSelected();
void insertBeforeRow(int row);
void clearAll();
void clearAll();
void removeSelected();
void removeChecked();
void removeRow(int row);
void removeSelected();
void removeChecked();
void removeRow(int row);
private:
void sortByName(Qt::SortOrder order);
void sortByAddress(Qt::SortOrder order);
void sortByModel(Qt::SortOrder order);
void sortByName(Qt::SortOrder order);
void sortByAddress(Qt::SortOrder order);
void sortByModel(Qt::SortOrder order);
DeviceAddItem* genOne(uint32_t value);
DeviceAddItem *genOne(uint32_t value);
private:
DeviceAddModelPrivate *d;
DeviceAddModelPrivate* d;
};

View File

@ -12,95 +12,95 @@
#include <QUrl>
#ifdef QMAKE_GEN_TAOMACRO
#include "taoMacro.h"
#include "taoMacro.h"
#endif
static void prepareApp()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
# if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
# endif
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QCoreApplication::setOrganizationName("JaredTao");
QCoreApplication::setOrganizationDomain("https://jaredtao.github.io");
QCoreApplication::setApplicationName("TaoQuickShow");
#endif
QCoreApplication::setOrganizationName("JaredTao");
QCoreApplication::setOrganizationDomain("https://jaredtao.github.io");
QCoreApplication::setApplicationName("TaoQuickShow");
}
int main(int argc, char **argv)
int main(int argc, char** argv)
{
prepareApp();
QGuiApplication app(argc, argv);
prepareApp();
QGuiApplication app(argc, argv);
#ifdef TAODEBUG
// qSetMessagePattern("[%{time h:mm:ss.zzz} %{function}] %{message}");
qSetMessagePattern("[%{time h:mm:ss.zzz} %{file} row(%{line}) %{function}] %{message}");
// qSetMessagePattern("[%{time h:mm:ss.zzz} %{function}] %{message}");
qSetMessagePattern("[%{time h:mm:ss.zzz} %{file} row(%{line}) %{function}] %{message}");
#else
Logger::initLog();
Logger::initLog();
#endif
const auto appPath = QDir::cleanPath(app.applicationDirPath());
qWarning() << "appPath" << appPath;
const auto appPath = QDir::cleanPath(app.applicationDirPath());
qWarning() << "appPath" << appPath;
Trans trans;
AppInfo appInfo;
QuickTool quickTool;
Trans trans;
AppInfo appInfo;
QuickTool quickTool;
TaoFrameLessView view;
view.setMinimumSize({ 800, 600 });
view.resize(1440, 960);
trans.beforeUiReady(view.rootContext(), transDir);
appInfo.beforeUiReady(view.rootContext());
TaoFrameLessView view;
view.setMinimumSize({ 800, 600 });
view.resize(1440, 960);
trans.beforeUiReady(view.rootContext(), transDir);
appInfo.beforeUiReady(view.rootContext());
view.engine()->addImportPath(qmlPath);
view.engine()->addImportPath(qmlPath);
#ifdef TaoQuickImport
view.engine()->addImportPath(TaoQuickImport);
qWarning() << "TaoQuickImportPath " << TaoQuickImport;
view.engine()->addImportPath(TaoQuickImport);
qWarning() << "TaoQuickImportPath " << TaoQuickImport;
#endif
#ifdef TaoQuickImage
view.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImage);
view.rootContext()->setContextProperty("taoQuickImagePath", TaoQuickImage);
#endif
#ifdef TAODEBUG
view.rootContext()->setContextProperty("isDebug", true);
view.rootContext()->setContextProperty("isDebug", true);
#else
view.rootContext()->setContextProperty("isDebug", QVariant(false));
view.rootContext()->setContextProperty("isDebug", QVariant(false));
#endif
#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0)
view.rootContext()->setContextProperty("hasShape", true);
view.rootContext()->setContextProperty("hasShape", true);
#else
view.rootContext()->setContextProperty("hasShape", false);
view.rootContext()->setContextProperty("hasShape", false);
#endif
view.rootContext()->setContextProperty("qmlPath", qmlPath);
view.rootContext()->setContextProperty("imgPath", imgPath);
view.rootContext()->setContextProperty("contentsPath", contentsPath);
view.rootContext()->setContextProperty("appPath", appPath);
view.rootContext()->setContextProperty("view", &view);
view.rootContext()->setContextProperty("quickTool", &quickTool);
view.rootContext()->setContextProperty("qmlPath", qmlPath);
view.rootContext()->setContextProperty("imgPath", imgPath);
view.rootContext()->setContextProperty("contentsPath", contentsPath);
view.rootContext()->setContextProperty("appPath", appPath);
view.rootContext()->setContextProperty("view", &view);
view.rootContext()->setContextProperty("quickTool", &quickTool);
DeviceAddModel model;
DeviceAddModel model;
view.rootContext()->setContextProperty("deviceAddModel", &model);
const QUrl url(qmlPath + QStringLiteral("main.qml"));
QObject::connect(&view, &QQuickView::statusChanged, &view, [&](QQuickView::Status status) {
if (status == QQuickView::Status::Ready) {
trans.afterUiReady();
appInfo.afterUiReady();
quickTool.setRootObjet(view.rootObject());
}
});
//qml call 'Qt.quit()' will emit engine::quit, here should call qApp->quit
QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
//qml clear content before quit
QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view.setSource({});});
view.rootContext()->setContextProperty("deviceAddModel", &model);
const QUrl url(qmlPath + QStringLiteral("main.qml"));
QObject::connect(&view, &QQuickView::statusChanged, &view, [&](QQuickView::Status status) {
if (status == QQuickView::Status::Ready)
{
trans.afterUiReady();
appInfo.afterUiReady();
quickTool.setRootObjet(view.rootObject());
}
});
// qml call 'Qt.quit()' will emit engine::quit, here should call qApp->quit
QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
// qml clear content before quit
QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view]() { view.setSource({}); });
view.setSource(url);
view.moveToScreenCenter();
view.show();
view.setSource(url);
view.moveToScreenCenter();
view.show();
return app.exec();
return app.exec();
}

View File

@ -3,28 +3,28 @@
/* Add C++ includes here */
#if defined __cplusplus
# include <QtGui>
# include <QtCore>
# include <QString>
# include <QObject>
# include <QHash>
# include <QMap>
# include <QFile>
# include <QDir>
# include <QBuffer>
# include <QTime>
# include <QTimer>
# include <QMutex>
# include <QByteArray>
# include <QThread>
# include <QDateTime>
# include <QTextStream>
# include <QDebug>
#include <QBuffer>
#include <QByteArray>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QHash>
#include <QMap>
#include <QMutex>
#include <QObject>
#include <QString>
#include <QTextStream>
#include <QThread>
#include <QTime>
#include <QTimer>
#include <QtCore>
#include <QtGui>
# include <QtMath>
# include <QPixmap>
# include <QImage>
# include <QPainter>
# include <QSettings>
#include <QImage>
#include <QPainter>
#include <QPixmap>
#include <QSettings>
#include <QtMath>
#endif

View File

@ -1,28 +1,27 @@
#pragma once
#define RELEASE_VER 1 // 0: beta version; 1: release version
#define RELEASE_DATE __DATE__ //yyyy-mm-dd; only used for RELEASE_VER=1
#define RELEASE_VER 1 // 0: beta version; 1: release version
#define RELEASE_DATE __DATE__ // yyyy-mm-dd; only used for RELEASE_VER=1
#define RELEASE_TIME __TIME__ //hh:mm:ss
#define RELEASE_TIME __TIME__ // hh:mm:ss
#define RELEASE_VER_MAIN TaoMAJ
#define RELEASE_VER_MAIN2 TaoMIN
#define RELEASE_VER_SUB TaoPAT
#define RELEASE_VER_SUB TaoPAT
#define FILE_VER_STR TaoREVISIONSTR
#define VER_COMPANYNAME_STR "JaredTao\0"
#define VER_COMPANYNAME_STR "JaredTao\0"
#define VER_FILEDESCRIPTION_STR "TaoQuickShow\0"
#define VER_INTERNALNAME_STR "jaredtao.github.io\0"
#define VER_LEGALCOPYRIGHT_STR "Copyright(C)2019-2029 JaredTao\0"
#define VER_LEGALTRADEMARKS_STR "JaredTao\0"
#define VER_ORIGINALFILENAME_STR "TaoQuickShow.exe\0"
#define VER_PRODUCTNAME_STR "TaoQuickShow\0"
#define VER_FILEDESCRIPTION_STR "TaoQuickShow\0"
#define VER_INTERNALNAME_STR "jaredtao.github.io\0"
#define VER_LEGALCOPYRIGHT_STR "Copyright(C)2019-2029 JaredTao\0"
#define VER_LEGALTRADEMARKS_STR "JaredTao\0"
#define VER_ORIGINALFILENAME_STR "TaoQuickShow.exe\0"
#define VER_PRODUCTNAME_STR "TaoQuickShow\0"
// version number (string)
#define TOSTRING2(arg) #arg
#define TOSTRING(arg) TOSTRING2(arg)
#define RELEASE_VER_STR TOSTRING(RELEASE_VER_MAIN) "." TOSTRING(RELEASE_VER_MAIN2) "." TOSTRING(RELEASE_VER_SUB)
#define TOSTRING(arg) TOSTRING2(arg)
#define RELEASE_VER_STR TOSTRING(RELEASE_VER_MAIN) "." TOSTRING(RELEASE_VER_MAIN2) "." TOSTRING(RELEASE_VER_SUB)