treeland/examples/test_set_treeland_wallpaper/personalizationmangerclient...

304 lines
8.5 KiB
C++

// Copyright (C) 2023 Dingyuan Zhang <lxz@mkacg.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "personalizationmangerclient.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
#include <QObject>
#include <QScreen>
#include <QStandardPaths>
#include <QTranslator>
#include <QtWaylandClient/QWaylandClientExtension>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
PersonalizationV1::PersonalizationV1()
: QWaylandClientExtensionTemplate<PersonalizationV1>(1)
{
connect(this, &PersonalizationV1::activeChanged, this, &PersonalizationV1::onActiveChanged);
m_cacheDirectory =
QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/wallpaper/";
QTranslator *translate = new QTranslator(this);
auto dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
for (const auto &dir : dirs) {
if (translate
->load(QLocale::system(), "wallpaper", ".", dir + "/ddm/translations", ".qm")) {
qApp->installTranslator(translate);
}
}
Q_FOREACH (QScreen *screen, qApp->screens()) {
WallpaperMetaData *meta = new WallpaperMetaData;
meta->screen = screen;
meta->output = screen->name();
m_screens.insert(meta->output, meta);
}
}
PersonalizationV1::~PersonalizationV1()
{
if (m_wallpaperContext) {
m_wallpaperContext->deleteLater();
}
if (m_modes.size() > 0) {
qDeleteAll(m_modes);
}
if (m_screens.size() > 0) {
qDeleteAll(m_screens);
}
}
void PersonalizationV1::onActiveChanged()
{
if (!isActive())
return;
if (!m_wallpaperContext) {
m_wallpaperContext = new PersonalizationWallpaper(get_wallpaper_context());
connect(m_wallpaperContext,
&PersonalizationWallpaper::metadataChanged,
this,
&PersonalizationV1::onMetadataChanged);
}
m_wallpaperContext->get_metadata();
}
void PersonalizationV1::addWallpaper(const QString &path)
{
if (!m_wallpaperContext)
return;
QString local_path = QUrl(path).toLocalFile();
QFileInfo file_info(local_path);
QString dest = m_cacheDirectory + file_info.fileName();
QDir dir(m_cacheDirectory);
if (!dir.exists()) {
dir.mkpath(m_cacheDirectory);
}
QFile::copy(local_path, dest);
}
void PersonalizationV1::removeWallpaper(const QString &path, const QString &group, int index)
{
if (m_modes[group]->currentIndex() == index)
return;
QString local_path = QUrl(path).toLocalFile();
QFile::remove(local_path);
m_modes[group]->remove(index);
}
void PersonalizationV1::changeWallpaper(const QString &path,
const QString &output,
const QString &group,
int index,
quint32 op,
bool isdark)
{
if (!m_wallpaperContext)
return;
QString dest = QUrl(path).toLocalFile();
if (dest.isEmpty())
return;
QFile file(dest);
if (file.open(QIODevice::ReadOnly)) {
m_modes[group]->setCurrentIndex(index);
setCurrentGroup(group);
auto meta_data = m_screens.value(output);
if (meta_data != nullptr) {
meta_data->imagePath = dest;
meta_data->output = output;
meta_data->currentIndex = index;
meta_data->options = op;
meta_data->isdark = isdark;
m_wallpaperContext->set_on(op);
m_wallpaperContext->set_isdark(isdark);
m_wallpaperContext->set_fd(file.handle(), converToJson(m_screens));
m_wallpaperContext->set_output(meta_data->output);
m_wallpaperContext->commit();
Q_EMIT wallpaperChanged(dest);
}
}
}
void PersonalizationV1::setBackground(const QString &path,
const QString &group,
int index,
bool isdark)
{
changeWallpaper(path,
m_currentOutput,
group,
index,
PersonalizationWallpaper::options_background,
isdark);
}
void PersonalizationV1::setLockscreen(const QString &path,
const QString &group,
int index,
bool isdark)
{
changeWallpaper(path,
m_currentOutput,
group,
index,
PersonalizationWallpaper::options_lockscreen,
isdark);
}
void PersonalizationV1::setBoth(const QString &path, const QString &group, int index)
{
changeWallpaper(path,
m_currentOutput,
group,
index,
PersonalizationWallpaper::options_background
| PersonalizationWallpaper::options_lockscreen);
}
QString PersonalizationV1::currentGroup()
{
if (m_currentOutput.isEmpty())
return QString();
const auto *meta = m_screens[m_currentOutput];
return meta->group;
}
void PersonalizationV1::setCurrentGroup(const QString &group)
{
if (m_currentOutput.isEmpty())
return;
auto meta = m_screens[m_currentOutput];
meta->group = group;
Q_EMIT currentGroupChanged(group);
}
QString PersonalizationV1::output()
{
return m_currentOutput;
}
void PersonalizationV1::setOutput(const QString &name)
{
m_currentOutput = name;
Q_EMIT outputChanged(m_currentOutput);
}
QStringList PersonalizationV1::outputModel()
{
return m_screens.keys();
}
QString PersonalizationV1::cacheDirectory()
{
return m_cacheDirectory;
}
WallpaperCardModel *PersonalizationV1::wallpaperModel(const QString &group, const QString &dir)
{
if (m_modes.contains(group))
return m_modes[group];
auto model = new WallpaperCardModel(this);
model->setDirectory(dir);
m_modes[group] = model;
return m_modes[group];
}
QString PersonalizationV1::converToJson(QMap<QString, WallpaperMetaData *> screens)
{
QMapIterator<QString, WallpaperMetaData *> it(screens);
QJsonObject json;
while (it.hasNext()) {
it.next();
QJsonObject content;
content.insert("Group", it.value()->group);
content.insert("ImagePath", it.value()->imagePath);
content.insert("Output", it.value()->output);
content.insert("CurrentIndex", it.value()->currentIndex);
content.insert("Options", QString::number(it.value()->options));
json[it.key()] = content;
}
QJsonDocument json_doc(json);
return json_doc.toJson(QJsonDocument::Compact);
}
void PersonalizationV1::onMetadataChanged(const QString &metadata)
{
QJsonDocument json_doc = QJsonDocument::fromJson(metadata.toLocal8Bit());
if (!json_doc.isNull()) {
QJsonObject json = json_doc.object();
QMapIterator<QString, WallpaperMetaData *> it(m_screens);
while (it.hasNext()) {
it.next();
QJsonObject context = json.value(it.key()).toObject();
if (context.isEmpty())
continue;
it.value()->currentIndex = context["CurrentIndex"].toInt();
it.value()->group = context["Group"].toString();
it.value()->imagePath = context["ImagePath"].toString();
it.value()->output = context["Output"].toString();
it.value()->options = context["Options"].toInt();
}
}
if (m_currentOutput.isEmpty())
return;
auto meta = m_screens[m_currentOutput];
auto model = m_modes[meta->group];
if (model) {
model->setCurrentIndex(meta->currentIndex);
}
Q_EMIT wallpaperChanged(meta->imagePath);
}
PersonalizationWindow::PersonalizationWindow(
struct ::treeland_personalization_window_context_v1 *object)
: QWaylandClientExtensionTemplate<PersonalizationWindow>(1)
, QtWayland::treeland_personalization_window_context_v1(object)
{
}
PersonalizationWallpaper::PersonalizationWallpaper(
struct ::treeland_personalization_wallpaper_context_v1 *object)
: QWaylandClientExtensionTemplate<PersonalizationWallpaper>(1)
, QtWayland::treeland_personalization_wallpaper_context_v1(object)
{
}
void PersonalizationWallpaper::treeland_personalization_wallpaper_context_v1_metadata(
const QString &metadata)
{
Q_EMIT metadataChanged(metadata);
}