feat: 添加config文件读取接口

This commit is contained in:
hewenfei 2023-09-22 11:43:12 +08:00
parent 6b687d52ff
commit 4b0d98d167
19 changed files with 517 additions and 25 deletions

View File

@ -22,17 +22,17 @@ set(PROJECT_SOURCES
widget/widget-loader.cpp widget/widget-loader.h
widget/widget-metadata.cpp widget/widget-metadata.h
widget/widget-content.cpp widget/widget-content.h
widget/widget-container.cpp widget/widget-container.h
widget-ui/widget-item.cpp widget-ui/widget-item.h
widget-ui/widget-item-engine.cpp
widget-ui/widget-item-engine.h
widget-ui/widget-item-context.cpp
widget-ui/widget-item-context.h
widget-ui/widget-item-attached.cpp
widget-ui/widget-item-attached.h
widget-ui/widget-item-engine.cpp widget-ui/widget-item-engine.h
widget-ui/widget-item-context.cpp widget-ui/widget-item-context.h
widget-ui/widget-item-attached.cpp widget-ui/widget-item-attached.h
view/shared-engine-view.h view/shared-engine-view.cpp
config/config.h config/config.cpp
config/ini-config.h config/ini-config.cpp
config/json-config.h config/json-config.cpp
config/widget-config.cpp config/widget-config.h
config/widget-config-loader.cpp config/widget-config-loader.h
)
set(HEADERS widget/widget.h widget/widget-interface.h)
@ -49,7 +49,7 @@ set(PC_INSTALL_DIR "/usr/lib/pkgconfig")
target_include_directories(${PROJECT_NAME} PUBLIC $<INSTALL_INTERFACE:${HEADERS_INSTALL_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/widget>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/view>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}config>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/config>)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/ukui-panel-framework-config.cmake.in"

View File

@ -4,6 +4,8 @@ set(PROJECT_SOURCES
config.h config.cpp
ini-config.h ini-config.cpp
json-config.h json-config.cpp
widget-config.cpp widget-config.h
widget-config-loader.cpp widget-config-loader.h
)
add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES})

View File

@ -20,13 +20,13 @@ public:
};
explicit Config(const QString &filename, QObject *parent = nullptr);
QString filename() const;
virtual Config::Type type() const = 0;
Q_INVOKABLE QString filename() const;
Q_INVOKABLE virtual Config::Type type() const = 0;
virtual QVariant getValue(const QString &key) const = 0;
virtual void setValue(const QString &key, QVariant &value) = 0;
Q_INVOKABLE virtual QVariant getValue(const QString &key) const = 0;
Q_INVOKABLE virtual void setValue(const QString &key, const QVariant &value) = 0;
virtual void forceSync() const = 0;
Q_INVOKABLE virtual void forceSync() const = 0;
Q_SIGNALS:
void configChanged(const QString &key);

View File

@ -32,13 +32,13 @@ Config::Type IniConfig::type() const
QVariant IniConfig::getValue(const QString &key) const
{
if (d->settings) {
return {};
return d->settings->value(key);
}
return d->settings->value(key);
return {};
}
void IniConfig::setValue(const QString &key, QVariant &value)
void IniConfig::setValue(const QString &key, const QVariant &value)
{
if (d->settings) {
d->settings->setValue(key, value);

View File

@ -19,7 +19,7 @@ public:
Type type() const override;
QVariant getValue(const QString &key) const override;
void setValue(const QString &key, QVariant &value) override;
void setValue(const QString &key, const QVariant &value) override;
void forceSync() const override;

View File

@ -0,0 +1,135 @@
#include "widget-config-loader.h"
#include <QStandardPaths>
#include <QDir>
#include <QMap>
#include <QDebug>
#include <QVariant>
#include <QStringLiteral>
namespace UkuiPanel {
class WidgetConfigLoaderPrivate
{
public:
WidgetConfigLoaderPrivate() = default;
QString appid;
QString containerId;
// var
static QMap<QString, QMap<QString, WidgetConfig*>* > globalCache;
// func
static bool hasContainer(const QString &container);
static QString globalAppid();
static QString globalContainerId();
static QString constructFileName(const QString &widgetId);
static QString constructFilePath(const QString &appid, const QString &containerId);
static QString rootConfigPath();
static QString configPath();
};
QMap<QString, QMap<QString, WidgetConfig*>* > WidgetConfigLoaderPrivate::globalCache = QMap<QString, QMap<QString, WidgetConfig*>* >();
bool WidgetConfigLoaderPrivate::hasContainer(const QString &container)
{
return globalCache.contains(container);
}
QString WidgetConfigLoaderPrivate::constructFileName(const QString &widgetId)
{
return widgetId + QStringLiteral(".conf");
}
QString WidgetConfigLoaderPrivate::rootConfigPath()
{
return constructFilePath(globalAppid(), globalContainerId());
}
QString WidgetConfigLoaderPrivate::globalAppid()
{
return QStringLiteral("org.ukui");
}
QString WidgetConfigLoaderPrivate::globalContainerId()
{
return QStringLiteral("widget-config-global");
}
QString WidgetConfigLoaderPrivate::constructFilePath(const QString &appid, const QString &containerId)
{
return QString(QDir::homePath() + QStringLiteral("/.config/%1/%2/")).arg(appid, containerId);
}
// ====== WidgetConfigLoader ====== //
WidgetConfigLoader::WidgetConfigLoader(const QString &appid, const QString &containerId) : d(new WidgetConfigLoaderPrivate)
{
d->appid = appid;
d->containerId = containerId;
}
WidgetConfig *WidgetConfigLoader::getConfig(const QString &widgetId)
{
return WidgetConfigLoader::loadConfig(widgetId, d->containerId, d->appid);
}
WidgetConfig *
WidgetConfigLoader::loadConfig(const QString &widgetId, const QString &containerId, const QString &appid)
{
if (widgetId.isEmpty()) {
return nullptr;
}
QString app = appid;
QString container = containerId;
if (appid.isEmpty() || containerId.isEmpty()) {
app = WidgetConfigLoaderPrivate::globalAppid();
container = WidgetConfigLoaderPrivate::globalContainerId();
}
QString cacheKey = app + "-" + container;
if (WidgetConfigLoaderPrivate::hasContainer(cacheKey)) {
const QMap<QString, WidgetConfig*> *map = WidgetConfigLoaderPrivate::globalCache.value(cacheKey);
if (map->contains(widgetId)) {
return map->value(widgetId);
}
}
QString configPath = WidgetConfigLoaderPrivate::constructFilePath(app, container);
if (!QFile::exists(configPath)) {
QDir().mkpath(configPath);
}
// not create.
QString filename = configPath + WidgetConfigLoaderPrivate::constructFileName(widgetId);
// QFile f(filename);
// if (!f.exists()) {
// f.open(QFile::WriteOnly);
// f.close();
// }
auto widgetConfig = new WidgetConfig(filename);
if (WidgetConfigLoaderPrivate::hasContainer(cacheKey)) {
WidgetConfigLoaderPrivate::globalCache.value(cacheKey)->insert(widgetId, widgetConfig);
} else {
auto map = new QMap<QString, WidgetConfig*>;
map->insert(widgetId, widgetConfig);
WidgetConfigLoaderPrivate::globalCache.insert(cacheKey, map);
}
return widgetConfig;
}
QString WidgetConfigLoader::configFileName(const QString &widgetId)
{
return WidgetConfigLoaderPrivate::constructFileName(widgetId);
}
QString WidgetConfigLoader::getConfigFileName(const QString &widgetId)
{
return WidgetConfigLoaderPrivate::constructFilePath(d->appid, d->containerId) + WidgetConfigLoader::configFileName(widgetId);
}
} // UkuiPanel

View File

@ -0,0 +1,29 @@
#ifndef UKUI_PANEL_WIDGET_CONFIG_LOADER_H
#define UKUI_PANEL_WIDGET_CONFIG_LOADER_H
#include <QObject>
#include "widget-config.h"
namespace UkuiPanel {
class WidgetConfigLoaderPrivate;
class WidgetConfigLoader
{
public:
static QString configFileName(const QString &widgetId);
static WidgetConfig *loadConfig(const QString &widgetId, const QString &containerId = QString(), const QString &appid = QString());
explicit WidgetConfigLoader(const QString &appid, const QString &containerId);
WidgetConfig *getConfig(const QString &widgetId);
QString getConfigFileName(const QString &widgetId);
private:
WidgetConfigLoaderPrivate *d {nullptr};
};
} // UkuiPanel
#endif //UKUI_PANEL_WIDGET_CONFIG_LOADER_H

View File

@ -0,0 +1,12 @@
#include "widget-config.h"
namespace UkuiPanel {
WidgetConfig::WidgetConfig(const QString &widgetId, QObject *parent) : IniConfig(widgetId, parent)
{
}
} // UkuiPanel

View File

@ -0,0 +1,24 @@
#ifndef UKUI_PANEL_WIDGET_CONFIG_H
#define UKUI_PANEL_WIDGET_CONFIG_H
#include "ini-config.h"
namespace UkuiPanel {
class WidgetConfigLoader;
class WidgetConfig : public IniConfig
{
Q_OBJECT
friend class WidgetConfigLoader;
public:
WidgetConfig() = delete;
private:
explicit WidgetConfig(const QString &file, QObject *parent = nullptr);
};
} // UkuiPanel
#endif //UKUI_PANEL_WIDGET_CONFIG_H

View File

@ -2,6 +2,7 @@ project(framework-test VERSION 4.1 LANGUAGES CXX)
include_directories(../widget-ui)
include_directories(../widget)
include_directories(../config)
set(QRC_FILES qml.qrc)
set(PROJECT_SOURCES

View File

@ -7,6 +7,8 @@
#include "widget.h"
#include "widget-loader.h"
#include "widget-item.h"
#include "widget-config-loader.h"
#include "widget-container.h"
int main(int argc, char *argv[])
{
@ -16,7 +18,7 @@ int main(int argc, char *argv[])
// widgets << "org.ukui.panel.taskmanager";
// widgets << "org.ukui.panel.test";
widgets << "org.ukui.menu.starter";
widgets << "org.ukui.panel.widget.test";
// widgets << "org.ukui.panel.widget.test";
auto view = new QQuickView;
view->setResizeMode(QQuickView::SizeRootObjectToView);
@ -24,6 +26,7 @@ int main(int argc, char *argv[])
view->setColor(QColor(Qt::transparent));
view->setSource(QUrl("qrc:///main.qml"));
UkuiPanel::WidgetContainer container("ukui-panel", "panel-0");
QList<UkuiPanel::Widget *> widgetList;
UkuiPanel::WidgetLoader loader;
for (const auto &id : widgets) {
@ -31,6 +34,7 @@ int main(int argc, char *argv[])
if (!widget) {
continue;
}
container.addWidget(widget);
widgetList << widget;
UkuiPanel::WidgetItem *widgetItem = UkuiPanel::WidgetItem::itemForWidget(widget);

View File

@ -1,7 +1,5 @@
project(framework-widget-ui VERSION 4.1 LANGUAGES CXX)
include_directories(../widget)
set(PROJECT_SOURCES
widget-item.cpp widget-item.h
widget-item-engine.cpp

View File

@ -5,6 +5,7 @@ set(PROJECT_SOURCES
widget-loader.cpp widget-loader.h
widget-metadata.cpp widget-metadata.h
widget-content.cpp widget-content.h
widget-container.cpp widget-container.h
)
add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES})

View File

@ -0,0 +1,161 @@
//
// Created by hxf on 23-9-18.
//
#include "widget-container.h"
#include "widget.h"
#include <QMap>
namespace UkuiPanel {
class WidgetContainerPrivate
{
public:
WidgetContainerPrivate() = default;
// prop
QString appid;
QString containerId;
bool visible {false};
QRect geometry;
QMargins margins {0, 0, 0, 0};
WidgetContainer::Orientation orientation {WidgetContainer::LeftToRight};
// widgets
QVector<Widget *> widgets;
};
WidgetContainer::WidgetContainer(const QString &appid, const QString &containerId, QObject *parent) : QObject(parent), d(new WidgetContainerPrivate)
{
d->appid = appid;
d->containerId = containerId;
qRegisterMetaType<WidgetContainer::Orientation>();
qRegisterMetaType<WidgetContainer*>("WidgetContainer*");
}
QString WidgetContainer::appid() const
{
return d->appid;
}
QString WidgetContainer::containerId() const
{
return d->containerId;
}
void WidgetContainer::addWidget(int index, Widget *widget)
{
if (!widget) {
return;
}
int idx;
int maxIdx = d->widgets.size();
if (index < 0 || index > maxIdx) {
idx = maxIdx;
} else {
idx = index;
}
d->widgets.insert(idx, widget);
widget->setContainer(this);
Q_EMIT widgetAdded(widget->id());
}
void WidgetContainer::addWidget(Widget *widget)
{
addWidget(-1, widget);
}
void WidgetContainer::removeWidget(Widget *widget)
{
if (!widget) {
return;
}
int idx = -1;
for (int i = 0; i < d->widgets.size(); ++i) {
if (d->widgets.at(i) == widget) {
idx = i;
break;
}
}
if (idx > 0) {
removeWidget(idx);
}
}
void WidgetContainer::removeWidget(int index)
{
if (index < 0 || index > (d->widgets.size() - 1)) {
return;
}
Widget *widget = d->widgets.takeAt(index);
widget->setContainer(nullptr);
Q_EMIT widgetRemoved(widget->id());
}
WidgetContainer::Orientation WidgetContainer::orientation() const
{
return d->orientation;
}
void WidgetContainer::setOrientation(WidgetContainer::Orientation o)
{
if (d->orientation == o) {
return;
}
d->orientation = o;
Q_EMIT orientationChanged();
}
bool WidgetContainer::visible() const
{
return false;
}
void WidgetContainer::setVisible(bool visible)
{
if (d->visible == visible) {
return;
}
d->visible = visible;
}
QRect WidgetContainer::geometry() const
{
return d->geometry;
}
void WidgetContainer::setGeometry(QRect geometry)
{
if (d->geometry == geometry) {
return;
}
d->geometry = geometry;
Q_EMIT geometryChanged();
}
QMargins WidgetContainer::margins() const
{
return d->margins;
}
void WidgetContainer::setMargins(QMargins margins)
{
if (d->margins == margins) {
return;
}
d->margins = margins;
Q_EMIT marginsChanged();
}
} // UkuiPanel

View File

@ -0,0 +1,75 @@
//
// Created by hxf on 23-9-18.
//
#ifndef UKUI_PANEL_WIDGET_CONTAINER_H
#define UKUI_PANEL_WIDGET_CONTAINER_H
#include <QObject>
#include <QString>
#include <QRect>
#include <QMargins>
namespace UkuiPanel {
class Widget;
class WidgetContainerPrivate;
class WidgetContainer : public QObject
{
Q_OBJECT
Q_PROPERTY(QString appid READ appid CONSTANT FINAL)
Q_PROPERTY(QString containerId READ containerId CONSTANT FINAL)
Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged FINAL)
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged FINAL)
Q_PROPERTY(QMargins margins READ margins NOTIFY marginsChanged FINAL)
Q_PROPERTY(WidgetContainer::Orientation orientation READ orientation NOTIFY orientationChanged FINAL)
public:
enum Orientation {
LeftToRight,
TopToBottom
};
Q_ENUM(Orientation)
explicit WidgetContainer(const QString &appid, const QString &containerId, QObject *parent = nullptr);
// prop
QString appid() const;
QString containerId() const;
bool visible() const;
void setVisible(bool visible);
QRect geometry() const;
void setGeometry(QRect geometry);
QMargins margins() const;
void setMargins(QMargins margins);
WidgetContainer::Orientation orientation() const;
void setOrientation(WidgetContainer::Orientation o);
// widgets
void addWidget(Widget *widget);
void addWidget(int index, Widget *widget);
void removeWidget(int index);
void removeWidget(Widget *widget);
Q_SIGNALS:
void widgetAdded(const QString &id);
void widgetRemoved(const QString &id);
void visibleChanged();
void geometryChanged();
void marginsChanged();
void orientationChanged();
private:
WidgetContainerPrivate *d {nullptr};
};
} // UkuiPanel
Q_DECLARE_METATYPE(UkuiPanel::WidgetContainer::Orientation)
#endif //UKUI_PANEL_WIDGET_CONTAINER_H

View File

@ -186,3 +186,13 @@ QVariantMap WidgetMetadata::contents() const
return value.toObject().toVariantMap();
}
QVariantMap WidgetMetadata::config() const
{
QJsonValue value = m_object.value(QLatin1String("Config"));
if (value.type() == QJsonValue::Undefined || value.type() != QJsonValue::Object) {
return {};
}
return value.toObject().toVariantMap();
}

View File

@ -30,6 +30,7 @@ public:
QString description() const;
QVariantList authors() const;
QVariantMap contents() const;
QVariantMap config() const;
private:
void init();

View File

@ -1,10 +1,10 @@
#include "widget.h"
#include "widget-container.h"
#include "widget-config-loader.h"
#include <QDebug>
#include <utility>
using namespace UkuiPanel;
@ -24,6 +24,8 @@ public:
WidgetContent content;
WidgetMetadata metaData;
WidgetContainer *container {nullptr};
};
WidgetPrivate::WidgetPrivate(const WidgetMetadata &m)
@ -48,12 +50,12 @@ WidgetPrivate::WidgetPrivate(const WidgetMetadata &m)
*/
Widget::Widget(const WidgetMetadata& metaData, QObject *parent) : QObject(parent), d(new WidgetPrivate(metaData))
{
qDebug() << "id:" << metaData.id();
qDebug() << "name:" << metaData.name();
qDebug() << "authors:" << metaData.authors();
qDebug() << "description:" << metaData.description();
// qDebug() << "load widget, id:" << metaData.id() << "name:" << metaData.name()
// << "authors:" << metaData.authors() << "description:" << metaData.description();
qRegisterMetaType<WidgetConfig *>("WidgetConfig*");
}
Widget::~Widget()
{
if (d) {
@ -155,3 +157,30 @@ QString Widget::uiError() const
{
return d->uiError;
}
// TODO: init config
WidgetConfig *Widget::config() const
{
if (!d->container) {
return nullptr;
}
QVariantMap m = d->metaData.config();
if (m.isEmpty()) {
return nullptr;
}
if (m.value("IsGlobal").toBool()) {
return WidgetConfigLoader::loadConfig(d->metaData.id());
}
return WidgetConfigLoader::loadConfig(d->metaData.id(), d->container->containerId(), d->container->appid());
}
void Widget::setContainer(WidgetContainer *container)
{
WidgetContainer *old = d->container;
d->container = container;
Q_EMIT containerChanged(old ? old->containerId() : "", d->container ? d->container->containerId() : "");
}

View File

@ -8,7 +8,9 @@
namespace UkuiPanel {
class WidgetConfig;
class WidgetPrivate;
class WidgetContainer;
/**
* "Widget"
@ -27,6 +29,7 @@ class Widget : public QObject
Q_PROPERTY(QString bugReport READ bugReport CONSTANT FINAL)
Q_PROPERTY(QString description READ description CONSTANT FINAL)
Q_PROPERTY(QVariantList authors READ authors CONSTANT FINAL)
Q_PROPERTY(WidgetConfig *config READ config CONSTANT FINAL)
public:
explicit Widget(const WidgetMetadata& metaData, QObject *parent=nullptr);
~Widget() override;
@ -58,6 +61,11 @@ public:
QString uiError() const;
bool hasUiError() const;
WidgetConfig *config() const;
private:
void setContainer(WidgetContainer *container);
Q_SIGNALS:
void iconChanged();
void nameChanged();
@ -66,9 +74,11 @@ Q_SIGNALS:
// widget生命周期信号
void widgetDeleted(Widget *widget);
void containerChanged(const QString &oldId, const QString &newId);
private:
WidgetPrivate *d {nullptr};
friend class WidgetContainer;
};
} // UkuiPanel