304 lines
8.5 KiB
C++
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);
|
|
}
|