1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-25 04:02:50 +01:00

Refactor enum #2 and merge Util into ScreenPlayUtil/Util

This commit is contained in:
Elias Steurer 2023-12-01 16:15:53 +01:00
parent 9e01dbac54
commit 9a583efbd9
42 changed files with 675 additions and 740 deletions

View File

@ -24,7 +24,6 @@ set(SOURCES
src/screenplaywidget.cpp
src/sdkconnection.cpp
src/settings.cpp
src/util.cpp
src/wizards.cpp)
set(HEADER
@ -45,7 +44,6 @@ set(HEADER
inc/public/ScreenPlay/screenplaywidget.h
inc/public/ScreenPlay/sdkconnection.h
inc/public/ScreenPlay/settings.h
inc/public/ScreenPlay/util.h
inc/public/ScreenPlay/wizards.h)
set(QML

View File

@ -25,8 +25,8 @@
#include "ScreenPlay/profilelistmodel.h"
#include "ScreenPlay/screenplaymanager.h"
#include "ScreenPlay/settings.h"
#include "ScreenPlay/util.h"
#include "ScreenPlay/wizards.h"
#include "ScreenPlayUtil/util.h"
#include <memory>

View File

@ -25,7 +25,7 @@
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/profilelistmodel.h"
#include "ScreenPlay/settings.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
#include "ScreenPlayUtil/projectfile.h"
#include <memory>

View File

@ -11,7 +11,7 @@
#include <QJsonObject>
#include <QVector>
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
namespace ScreenPlay {

View File

@ -14,7 +14,7 @@
#include <QWebSocketServer>
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
#include "ScreenPlayUtil/util.h"
#include <memory>

View File

@ -33,7 +33,7 @@
#include <QtGlobal>
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
#include <memory>
#include <optional>

View File

@ -1,132 +0,0 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#pragma once
#include <QClipboard>
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMetaType>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QObject>
#include <QProcess>
#include <QQmlEngine>
#include <QScopeGuard>
#include <QString>
#include <QTextStream>
#include <QVersionNumber>
#include <QtConcurrent/QtConcurrent>
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlayUtil/contenttypes.h"
#include "ScreenPlayUtil/util.h"
#include <fstream>
#include <iostream>
#include <optional>
namespace QArchive {
class DiskCompressor;
class DiskExtractor;
}
namespace ScreenPlay {
template <typename T>
T QStringToEnum(const QString& key, const T defaultValue)
{
auto metaEnum = QMetaEnum::fromType<T>();
bool ok = false;
T wantedEnum = static_cast<T>(metaEnum.keyToValue(key.toUtf8(), &ok));
if (ok) {
return wantedEnum;
} else {
qWarning() << "Unable to convert QStringToEnum. Key: " << key;
}
return defaultValue;
}
class Util : public QObject {
Q_OBJECT
Q_PROPERTY(QString debugMessages READ debugMessages NOTIFY debugMessagesChanged)
public:
Util(
const std::shared_ptr<GlobalVariables>& globalVariables);
~Util();
QString debugMessages() const { return m_debugMessages; }
signals:
void extractionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void extractionFinished();
void compressionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void compressionFinished();
void requestNavigation(QString nav);
void requestNavigationActive(bool isActive);
void requestToggleWallpaperConfiguration();
void setSidebarItem(QString folderName, ScreenPlay::ContentTypes::InstalledType type);
void allLicenseLoaded(QString licensesText);
void allDataProtectionLoaded(QString dataProtectionText);
void debugMessagesChanged(QString debugMessages);
public slots:
void copyToClipboard(const QString& text) const;
void openFolderInExplorer(const QString& url) const;
QString toLocal(const QString& url) const;
bool exportProject(QString contentPath, QString exportFileName);
bool openGodotEditor(QString contentPath) const;
bool importProject(QString archivePath, QString extractionPath);
void requestAllLicenses();
void requestDataProtection();
bool fileExists(const QString& filePath) const;
static bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate = true);
static bool writeSettings(const QJsonObject& obj, const QString& absolutePath);
static bool writeFile(const QString& text, const QString& absolutePath);
static bool writeFileFromQrc(const QString& qrcPath, const QString& absolutePath);
static bool copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnail, const QString& destination);
void setNavigation(QString nav)
{
emit requestNavigation(nav);
}
// When we create a wallpaper the main navigation gets disabled
void setNavigationActive(bool isActive)
{
emit requestNavigationActive(isActive);
}
void setToggleWallpaperConfiguration()
{
emit requestToggleWallpaperConfiguration();
}
void appendDebugMessages(QString debugMessages)
{
if (m_debugMessages.size() > 10000) {
m_debugMessages = "###### DEBUG CLEARED ######";
}
m_debugMessages += debugMessages;
emit debugMessagesChanged(m_debugMessages);
}
private:
QString m_debugMessages {};
QFuture<void> m_requestAllLicensesFuture;
std::unique_ptr<QArchive::DiskCompressor> m_compressor;
std::unique_ptr<QArchive::DiskExtractor> m_extractor;
const std::shared_ptr<GlobalVariables>& m_globalVariables;
};
}

View File

@ -25,7 +25,7 @@
#include "ScreenPlay/createimportvideo.h"
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
#include <memory>
#include <optional>
@ -125,5 +125,6 @@ private:
QColor("#FFD600"),
QColor("#4A148C")
};
Util m_util;
};
}

View File

@ -6,7 +6,6 @@ import QtQuick.Layouts
import QtQuick.Dialogs
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
Item {
@ -59,10 +58,6 @@ Item {
}
ComboBox {
// ListElement {
// text: "AV1 (NVidia 3000, AMD 6000 or newer). ULTRA SLOW ENCODING!"
// value: Create.AV1
// }
id: comboBoxCodec
Layout.preferredWidth: 400
@ -76,14 +71,13 @@ Item {
ListElement {
text: "VP8 (Better for older hardware)"
value: Create.VP9
value: Util.Video.VideoCodec.VP9
}
ListElement {
text: "VP9 (Better for newer hardware 2018+)"
value: Create.VP8
value: Util.Video.VideoCodec.VP8
}
// Import works but the QWebEngine cannot display AV1 :(
}
}
}

View File

@ -5,8 +5,6 @@ import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
Item {
@ -329,7 +327,7 @@ Item {
onClicked: {
if (conversionFinishedSuccessful) {
btnSave.enabled = false;
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Create.VP9, textFieldTags.getTags());
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Util.Video.VideoCodec.VP9, textFieldTags.getTags());
savePopup.open();
}
}

View File

@ -62,7 +62,7 @@ Item {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_installed.svg"
onClicked: {
setSidebarActive(false);
App.installedListFilter.sortBySearchType(SearchType.All);
App.installedListFilter.sortBySearchType(Util.ContentTypes.SearchType.All);
}
}
@ -71,7 +71,7 @@ Item {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg"
onClicked: {
setSidebarActive(false);
App.installedListFilter.sortBySearchType(SearchType.Scene);
App.installedListFilter.sortBySearchType(Util.ContentTypes.SearchType.Scene);
}
}
@ -80,7 +80,7 @@ Item {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg"
onClicked: {
setSidebarActive(false);
App.installedListFilter.sortBySearchType(SearchType.Wallpaper);
App.installedListFilter.sortBySearchType(Util.ContentTypes.SearchType.Wallpaper);
}
}
@ -89,7 +89,7 @@ Item {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg"
onClicked: {
setSidebarActive(false);
App.installedListFilter.sortBySearchType(SearchType.Widget);
App.installedListFilter.sortBySearchType(Util.ContentTypes.SearchType.Widget);
}
}
}

View File

@ -4,7 +4,6 @@ import QtQuick.Controls
import QtQuick.Controls.Material
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
Item {
@ -26,15 +25,15 @@ Item {
width: 320
height: 180
onTypeChanged: {
if (Util.JSUtil.isWidget(type)) {
if (App.util.isWidget(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg";
return;
}
if (Util.JSUtil.isScene(type)) {
if (App.util.isScene(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg";
return;
}
if (Util.JSUtil.isVideo(type)) {
if (App.util.isVideo(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg";
return;
}

View File

@ -6,15 +6,15 @@ import QtQuick.Controls.Material
import QtQuick.Controls.Material.impl
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil
import "../Monitors"
import ScreenPlayUtil as Util
Item {
id: root
property real navHeight
property var type: InstalledType.QMLWallpaper
property var type: ContentTypes.InstalledType.QMLWallpaper
property string contentFolderName
function indexOfValue(model, value) {
@ -50,7 +50,7 @@ Item {
} else {
imagePreview.source = previewImageFilePath;
}
if (Util.JSUtil.isWidget(root.type) || (monitorSelection.activeMonitors.length > 0)) {
if (App.util.isWidget(root.type) || (monitorSelection.activeMonitors.length > 0)) {
btnLaunchContent.enabled = true;
return;
}
@ -67,8 +67,8 @@ Item {
}
root.contentFolderName = folderName;
root.type = type;
if (Util.JSUtil.isWallpaper(root.type)) {
if (type === InstalledType.VideoWallpaper)
if (App.util.isWallpaper(root.type)) {
if (type === ContentTypes.InstalledType.VideoWallpaper)
root.state = "activeWallpaper";
else
root.state = "activeScene";
@ -82,7 +82,7 @@ Item {
target: App.util
}
Util.MouseHoverBlocker {
MouseHoverBlocker {
}
Rectangle {
@ -274,7 +274,7 @@ Item {
}
}
Util.Slider {
Slider {
id: sliderVolume
Layout.fillWidth: true
@ -314,19 +314,19 @@ Item {
valueRole: "value"
font.family: App.settings.font
model: [{
"value": FillMode.Stretch,
"value": Settings.FillMode.Stretch,
"text": qsTr("Stretch")
}, {
"value": FillMode.Fill,
"value": Settings.FillMode.Fill,
"text": qsTr("Fill")
}, {
"value": FillMode.Contain,
"value": Settings.FillMode.Contain,
"text": qsTr("Contain")
}, {
"value": FillMode.Cover,
"value": Settings.FillMode.Cover,
"text": qsTr("Cover")
}, {
"value": FillMode.Scale_Down,
"value": Settings.FillMode.Scale_Down,
"text": qsTr("Scale-Down")
}]
Component.onCompleted: {
@ -339,7 +339,7 @@ Item {
Button {
id: btnLaunchContent
objectName: "btnLaunchContent"
enabled: Util.JSUtil.isWidget(root.type) ? true : monitorSelection.isSelected
enabled: App.util.isWidget(root.type) ? true : monitorSelection.isSelected
Material.background: Material.accent
Material.foreground: "white"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
@ -349,7 +349,7 @@ Item {
const item = App.installedListModel.get(root.contentFolderName);
const absoluteStoragePath = item.m_absoluteStoragePath;
const previewImage = item.m_preview;
if (Util.JSUtil.isWallpaper(root.type)) {
if (App.util.isWallpaper(root.type)) {
let activeMonitors = monitorSelection.getActiveMonitors();
// TODO Alert user to choose a monitor
if (activeMonitors.length === 0)
@ -357,12 +357,12 @@ Item {
// We only have sliderVolume if it is a VideoWallpaper
let volume = 0;
if (type === InstalledType.VideoWallpaper)
if (type === ContentTypes.InstalledType.VideoWallpaper)
volume = Math.round(sliderVolume.slider.value * 100) / 100;
const screenFile = item.m_file;
let success = App.screenPlayManager.createWallpaper(root.type, cbVideoFillMode.currentValue, absoluteStoragePath, previewImage, screenFile, activeMonitors, volume, 1, {}, true);
}
if (Util.JSUtil.isWidget(root.type))
if (App.util.isWidget(root.type))
App.screenPlayManager.createWidget(type, Qt.point(0, 0), absoluteStoragePath, previewImage, {}, true);
root.state = "inactive";
monitorSelection.reset();

View File

@ -80,19 +80,19 @@ ColumnLayout {
valueRole: "value"
currentIndex: root.indexOfValue(settingsComboBox.model, App.settings.videoFillMode)
model: [{
"value": FillMode.Stretch,
"value": Util.Video.FillMode.Stretch,
"text": qsTr("Stretch")
}, {
"value": FillMode.Fill,
"value": Util.Video.FillMode.Fill,
"text": qsTr("Fill")
}, {
"value": FillMode.Contain,
"value": Util.Video.FillMode.Contain,
"text": qsTr("Contain")
}, {
"value": FillMode.Cover,
"value": Util.Video.FillMode.Cover,
"text": qsTr("Cover")
}, {
"value": FillMode.Scale_Down,
"value": Util.Video.FillMode.Scale_Down,
"text": qsTr("Scale_Down")
}]
onActivated: {

View File

@ -3,8 +3,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil
Item {
id: root

View File

@ -7,7 +7,7 @@ import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
import ScreenPlayUtil
Item {
id: root
@ -250,11 +250,11 @@ Item {
comboBox {
model: ListModel {
ListElement { value: Settings.FillMode.Stretch; text: qsTr("Stretch") }
ListElement { value: Settings.FillMode.Fill; text: qsTr("Fill") }
ListElement { value: Settings.FillMode.Contain; text: qsTr("Contain") }
ListElement { value: Settings.FillMode.Cover; text: qsTr("Cover") }
ListElement { value: Settings.FillMode.Scale_Down; text: qsTr("Scale-Down") }
ListElement { value: Video.FillMode.Stretch; text: qsTr("Stretch") }
ListElement { value: Video.FillMode.Fill; text: qsTr("Fill") }
ListElement { value: Video.FillMode.Contain; text: qsTr("Contain") }
ListElement { value: Video.FillMode.Cover; text: qsTr("Cover") }
ListElement { value: Video.FillMode.Scale_Down; text: qsTr("Scale-Down") }
}
onActivated: {
App.settings.setVideoFillMode(cbVideoFillMode.comboBox.currentValue)
@ -340,31 +340,31 @@ Item {
bottom: parent.bottom
}
Util.GrowIconLink {
GrowIconLink {
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/brand_github.svg"
url: "https://github.com/kelteseth"
color: "#333333"
}
Util.GrowIconLink {
GrowIconLink {
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/brand_gitlab.svg"
url: "https://gitlab.com/kelteseth"
color: "#FC6D26"
}
Util.GrowIconLink {
GrowIconLink {
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/brand_twitter.svg"
url: "https://twitter.com/Kelteseth"
color: "#1DA1F2"
}
Util.GrowIconLink {
GrowIconLink {
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/brand_twitch.svg"
url: "https://www.twitch.tv/kelteseth/"
color: "#6441A5"
}
Util.GrowIconLink {
GrowIconLink {
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/brand_reddit.svg"
url: "https://www.reddit.com/r/ScreenPlayApp/"
color: "#FF4500"

View File

@ -88,7 +88,7 @@ void App::init()
m_globalVariables = make_shared<GlobalVariables>();
m_monitorListModel = make_shared<MonitorListModel>();
m_util = make_unique<Util>(m_globalVariables);
m_util = make_unique<Util>();
m_profileListModel = make_shared<ProfileListModel>(m_globalVariables);
m_settings = make_shared<Settings>(m_globalVariables);
m_installedListModel = make_shared<InstalledListModel>(m_globalVariables, m_settings);
@ -107,7 +107,7 @@ void App::init()
const QString appPath = QGuiApplication::applicationDirPath();
sentry_options_set_handler_path(options, QString(appPath + "/crashpad_handler.exe").toStdString().c_str());
sentry_options_set_database_path(options, appPath.toStdString().c_str());
sentry_options_set_handler_path(options, QString(QGuiApplication::applicationDirPath() + "/crashpad_handler" + ScreenPlayUtil::executableBinEnding()).toStdString().c_str());
sentry_options_set_handler_path(options, QString(QGuiApplication::applicationDirPath() + "/crashpad_handler" + Util().executableBinEnding()).toStdString().c_str());
sentry_options_set_database_path(options, QGuiApplication::applicationDirPath().toStdString().c_str());
const int sentryInitStatus = sentry_init(options);
if (sentryInitStatus != 0) {

View File

@ -1,7 +1,6 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/create.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
namespace ScreenPlay {
@ -47,9 +46,10 @@ void Create::reset()
void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality)
{
reset();
videoPath = ScreenPlayUtil::toLocal(videoPath);
ScreenPlay::Util util;
videoPath = util.toLocal(videoPath);
const QDir installedDir = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString());
const QDir installedDir = util.toLocal(m_globalVariables->localStoragePath().toString());
// Create a temp dir so we can later alter it to the workshop id
const QDateTime date = QDateTime::currentDateTime();
@ -160,9 +160,10 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
void Create::importH264(QString videoPath)
{
reset();
videoPath = ScreenPlayUtil::toLocal(videoPath);
ScreenPlay::Util util;
videoPath = util.toLocal(videoPath);
const QDir installedDir = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString());
const QDir installedDir = util.toLocal(m_globalVariables->localStoragePath().toString());
// Create a temp dir so we can later alter it to the workshop id
const QDateTime date = QDateTime::currentDateTime();
@ -254,8 +255,9 @@ void Create::saveWallpaper(
const Create::VideoCodec codec,
const QVector<QString> tags)
{
filePath = ScreenPlayUtil::toLocal(filePath);
previewImagePath = ScreenPlayUtil::toLocal(previewImagePath);
ScreenPlay::Util util;
filePath = util.toLocal(filePath);
previewImagePath = util.toLocal(previewImagePath);
emit createWallpaperStateChanged(Import::State::CopyFiles);
@ -301,7 +303,7 @@ void Create::saveWallpaper(
obj.insert("preview", previewImageFile.exists() ? previewImageFile.fileName() : "preview.jpg");
obj.insert("previewThumbnail", "previewThumbnail.jpg");
obj.insert("type", "videoWallpaper");
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", util.fillArray(tags));
QFile audioFile { m_workingDir + "/audio.mp3" };
if (audioFile.exists() && audioFile.size() > 0) {
@ -309,7 +311,7 @@ void Create::saveWallpaper(
obj.insert("audioCodec", "mp3");
}
if (!Util::writeSettings(std::move(obj), m_workingDir + "/project.json")) {
if (!util.writeSettings(std::move(obj), m_workingDir + "/project.json")) {
emit createWallpaperStateChanged(Import::State::CreateProjectFileError);
return;
}

View File

@ -50,13 +50,14 @@ CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& ex
void CreateImportVideo::setupFFMPEG()
{
Util util;
#ifdef Q_OS_LINUX
// Use system ffmpeg
m_ffprobeExecutable = "ffprobe";
m_ffmpegExecutable = "ffmpeg";
#else
m_ffprobeExecutable = QGuiApplication::applicationDirPath() + "/ffprobe" + ScreenPlayUtil::executableBinEnding();
m_ffmpegExecutable = QGuiApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding();
m_ffprobeExecutable = QGuiApplication::applicationDirPath() + "/ffprobe" + util.executableBinEnding();
m_ffmpegExecutable = QGuiApplication::applicationDirPath() + "/ffmpeg" + util.executableBinEnding();
#endif
// We use system ffmpeg on linux
#ifndef Q_OS_LINUX
@ -109,7 +110,8 @@ bool CreateImportVideo::createWallpaperInfo()
args.append(m_videoPath);
emit processOutput("ffprobe " + ScreenPlayUtil::toString(args));
Util util;
emit processOutput("ffprobe " + util.toString(args));
emit createWallpaperStateChanged(Import::State::AnalyseVideo);
@ -118,7 +120,7 @@ bool CreateImportVideo::createWallpaperInfo()
emit createWallpaperStateChanged(Import::State::AnalyseVideoFinished);
auto obj = ScreenPlayUtil::parseQByteArrayToQJsonObject(QByteArray::fromStdString(ffmpegOut.toStdString()));
auto obj = util.parseQByteArrayToQJsonObject(QByteArray::fromStdString(ffmpegOut.toStdString()));
if (!obj) {
QString error = ffmpegOut;
@ -329,7 +331,7 @@ bool CreateImportVideo::createWallpaperVideoPreview()
// Disable audio
args.append("-an");
args.append(m_exportPath + "/preview.webm");
emit processOutput("ffmpeg " + ScreenPlayUtil::toString(args));
emit processOutput("ffmpeg " + Util().toString(args));
const QString ffmpegOut = waitForFinished(args);
const QFile previewVideo(m_exportPath + "/preview.webm");
@ -376,7 +378,7 @@ bool CreateImportVideo::createWallpaperGifPreview()
args.append("-filter_complex");
args.append("[0:v] fps=12,scale=w=480:h=-1,split [a][b];[a] palettegen=stats_mode=single [p];[b][p] paletteuse=new=1");
args.append(m_exportPath + "/preview.gif");
emit processOutput("ffmpeg " + ScreenPlayUtil::toString(args));
emit processOutput("ffmpeg " + Util().toString(args));
const QString ffmpegOut = waitForFinished(args);
@ -435,7 +437,7 @@ bool CreateImportVideo::createWallpaperImageThumbnailPreview()
}
args.append(m_exportPath + "/previewThumbnail.jpg");
emit processOutput("ffmpeg " + ScreenPlayUtil::toString(args));
emit processOutput("ffmpeg " + Util().toString(args));
const QString ffmpegOut = waitForFinished(args);
if (!ffmpegOut.isEmpty()) {
@ -480,7 +482,7 @@ bool CreateImportVideo::createWallpaperImagePreview()
}
args.append(m_exportPath + "/preview.jpg");
emit processOutput("ffmpeg " + ScreenPlayUtil::toString(args));
emit processOutput("ffmpeg " + Util().toString(args));
const QString ffmpegOut = waitForFinished(args);
if (!ffmpegOut.isEmpty()) {
const QFile previewImg(m_exportPath + "/preview.jpg");
@ -694,7 +696,7 @@ QString CreateImportVideo::waitForFinished(
{
m_process = std::make_unique<QProcess>();
QObject::connect(m_process.get(), &QProcess::errorOccurred, [=](QProcess::ProcessError error) {
QObject::connect(m_process.get(), &QProcess::errorOccurred, [=, this](QProcess::ProcessError error) {
qDebug() << "error enum val = " << error << m_process->errorString();
emit createWallpaperStateChanged(Import::State::AnalyseVideoError);
m_process->terminate();

View File

@ -61,7 +61,7 @@ void InstalledListModel::init()
*/
bool InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath)
{
const QString path = ScreenPlayUtil::toLocal(absoluteStoragePath);
const QString path = Util().toLocal(absoluteStoragePath);
int index = -1;
for (int i = 0; i < m_screenPlayFiles.size(); ++i) {
if (m_screenPlayFiles.at(i).projectJsonFilePath.path() == path) {

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/screenplaymanager.h"
#include "ScreenPlay/util.h"
#include "ScreenPlayUtil/util.h"
#include <QScopeGuard>
namespace ScreenPlay {
@ -129,7 +129,7 @@ bool ScreenPlayManager::createWallpaper(
});
const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile();
const QString appID = ScreenPlayUtil::generateRandomString();
const QString appID = Util().generateRandomString();
// Only support remove wallpaper that spans over 1 monitor
if (monitorIndex.length() == 1) {
@ -196,7 +196,7 @@ bool ScreenPlayManager::createWidget(
}
});
const QString appID = ScreenPlayUtil::generateRandomString();
const QString appID = Util().generateRandomString();
const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile();
if (path.isEmpty()) {
@ -536,7 +536,7 @@ bool ScreenPlayManager::saveProfiles()
profile.insert("version", "1.0.0");
profile.insert("profiles", activeProfileList);
if (Util::writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) {
if (Util().writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) {
emit profilesSaved();
return true;
}
@ -548,14 +548,15 @@ bool ScreenPlayManager::saveProfiles()
*/
bool ScreenPlayManager::loadProfiles()
{
const auto configObj = ScreenPlayUtil::openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json");
Util util;
const auto configObj = util.openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json");
if (!configObj) {
qWarning() << "Could not load active profiles at path: " << m_globalVariables->localSettingsPath().toString() + "/profiles.json";
return false;
}
std::optional<QVersionNumber> version = ScreenPlayUtil::getVersionNumberFromString(configObj->value("version").toString());
std::optional<QVersionNumber> version = util.getVersionNumberFromString(configObj->value("version").toString());
if (version && *version != m_globalVariables->version()) {
qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << m_globalVariables->version().toString();
@ -670,7 +671,6 @@ bool ScreenPlayManager::loadProfiles()
return true;
}
}
#include "moc_screenplaymanager.cpp"

View File

@ -43,7 +43,8 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(
, m_playbackRate { playbackRate }
, m_settings { settings }
{
std::optional<QJsonObject> projectOpt = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json");
Util util;
std::optional<QJsonObject> projectOpt = util.openJsonFileToObject(absolutePath + "/project.json");
if (projectOpt.has_value()) {
m_projectJson = projectOpt.value();
}
@ -53,7 +54,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(
projectSettingsListModelProperties.insert("playbackRate", m_playbackRate);
} else {
if (properties.isEmpty()) {
if (auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json")) {
if (auto obj = util.openJsonFileToObject(absolutePath + "/project.json")) {
if (obj->contains("properties"))
projectSettingsListModelProperties = obj->value("properties").toObject();
}

View File

@ -34,7 +34,7 @@ ScreenPlayWidget::ScreenPlayWidget(
QJsonObject projectSettingsListModelProperties;
if (properties.isEmpty()) {
if (auto obj = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json")) {
if (auto obj = Util().openJsonFileToObject(absolutePath + "/project.json")) {
if (obj->contains("properties"))
projectSettingsListModelProperties = obj->value("properties").toObject();
}

View File

@ -55,7 +55,8 @@ void ScreenPlay::SDKConnection::readyRead()
m_appID = appID.remove("appID=");
bool typeFound = false;
for (const QString& type : ScreenPlayUtil::getAvailableTypes()) {
Util util;
for (const QString& type : util.getAvailableTypes()) {
if (msg.contains(type, Qt::CaseInsensitive)) {
m_type = type;
typeFound = true;
@ -64,7 +65,7 @@ void ScreenPlay::SDKConnection::readyRead()
}
if (!typeFound) {
qCritical() << "Wallpaper type not found. Expected: " << ScreenPlayUtil::getAvailableTypes() << " got: " << msg;
qCritical() << "Wallpaper type not found. Expected: " << util.getAvailableTypes() << " got: " << msg;
}
qInfo() << "[2/4] SDKConnection parsed with type: " << m_type << " connected with AppID:" << m_appID;

View File

@ -148,13 +148,14 @@ void Settings::setupWidgetAndWindowPaths()
{
QDir workingDir(QGuiApplication::applicationDirPath());
const QString osType = QSysInfo::productType();
Util util;
QString godotVersion = QString(SCREENPLAY_GODOT_VERSION);
QString godotReleaseType = QString(SCREENPLAY_GODOT_RELEASE_TYPE);
if (osType == "windows") {
m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget" + ScreenPlayUtil::executableBinEnding()));
m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper" + ScreenPlayUtil::executableBinEnding()));
m_globalVariables->setGodotWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaperGodot" + ScreenPlayUtil::executableBinEnding()));
m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget" + util.executableBinEnding()));
m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper" + util.executableBinEnding()));
m_globalVariables->setGodotWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaperGodot" + util.executableBinEnding()));
const auto godotEditorName = "Godot_" + godotVersion + "_win64.exe";
m_globalVariables->setGodotEditorExecutablePath(QUrl(workingDir.path() + "/" + godotEditorName));
if (!QFileInfo::exists(m_globalVariables->godotWallpaperExecutablePath().toString())) {

View File

@ -1,364 +0,0 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/util.h"
#include "qarchive_enums.hpp"
#include "qarchivediskcompressor.hpp"
#include "qarchivediskextractor.hpp"
#include <QDesktopServices>
#include <QGuiApplication>
#if defined(Q_OS_WIN)
#include <sentry.h>
#endif
namespace ScreenPlay {
/*!
\class ScreenPlay::Util
\inmodule ScreenPlay
\brief Easy to use global object to use when certain functionality is not available in QML.
*/
/*!
\brief Constructor.
*/
Util::Util(
const std::shared_ptr<GlobalVariables>& globalVariables)
: QObject(nullptr)
, m_globalVariables { globalVariables }
{
m_extractor = std::make_unique<QArchive::DiskExtractor>();
m_compressor = std::make_unique<QArchive::DiskCompressor>();
QObject::connect(m_extractor.get(), &QArchive::DiskExtractor::progress, this, &Util::extractionProgressChanged);
QObject::connect(m_extractor.get(), &QArchive::DiskExtractor::finished, this, &Util::extractionFinished);
QObject::connect(m_compressor.get(), &QArchive::DiskCompressor::progress, this, &Util::compressionProgressChanged);
QObject::connect(m_compressor.get(), &QArchive::DiskCompressor::finished, this, &Util::compressionFinished);
}
/*!
\brief Needed only for QArchive unique_ptr
https://stackoverflow.com/questions/28386185/cant-use-stdunique-ptrt-with-t-being-a-forward-declaration
*/
Util::~Util() { }
/*!
\brief Copies the given string to the clipboard.
*/
void Util::copyToClipboard(const QString& text) const
{
auto* clipboard = QGuiApplication::clipboard();
clipboard->setText(text);
}
/*!
\brief Writes a given QJsonObject to a file. The path must be absolute. When truncate is set to
true the exsisting json file will be overriten.
*/
bool Util::writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate)
{
QFile configTmp;
configTmp.setFileName(absoluteFilePath);
QIODevice::OpenMode openMode;
if (truncate) {
openMode = QIODevice::ReadWrite | QIODevice::Truncate;
} else {
openMode = QIODevice::ReadWrite | QIODevice::Append;
}
if (!configTmp.open(openMode)) {
qWarning() << "Could not open out file!" << configTmp.errorString();
return false;
}
QTextStream out(&configTmp);
out.setEncoding(QStringConverter::Utf8);
out << QJsonDocument(object).toJson();
configTmp.close();
return true;
}
/*!
\brief Opens a native folder window on the given path. Windows and Mac only for now!
*/
void Util::openFolderInExplorer(const QString& url) const
{
const QString path = QUrl::fromUserInput(url).toLocalFile();
// QDesktopServices can hang on Windows
if (QSysInfo::productType() == "windows") {
QProcess explorer;
explorer.setProgram("explorer.exe");
// When we have space in the path like
// C:\Program Files (x86)\Steam\...
// we cannot set the path as an argument. But we can set the working it
// to the wanted path and open the current path via the dot.
explorer.setWorkingDirectory(QDir::toNativeSeparators(path));
explorer.setArguments({ "." });
explorer.startDetached();
return;
}
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
/*!
\brief Removes file///: or file:// from the url/string
*/
QString Util::toLocal(const QString& url) const
{
return ScreenPlayUtil::toLocal(url);
}
/*!
\brief Exports a given project into a .screenplay 7Zip file.
*/
bool Util::exportProject(QString contentPath, QString exportFileName)
{
m_compressor->clear();
contentPath = ScreenPlayUtil::toLocal(contentPath);
exportFileName = ScreenPlayUtil::toLocal(exportFileName);
QDir dir(contentPath);
bool success = true;
if (!dir.exists()) {
qWarning() << "Directory does not exist!" << dir;
return false;
}
QStringList files;
for (auto& item : dir.entryInfoList(QDir::Files)) {
files.append(item.absoluteFilePath());
}
QFile exportFile(exportFileName);
if (exportFile.exists()) {
if (!exportFile.remove()) {
qWarning() << "Unable to delte file marked to override!" << dir;
return false;
}
}
m_compressor->setFileName(exportFileName);
m_compressor->setArchiveFormat(QArchive::SevenZipFormat);
m_compressor->addFiles(files);
m_compressor->start();
return true;
}
bool Util::openGodotEditor(QString contentPath) const
{
const QList<QString> godotCmd = { "--editor", "--path", toLocal(contentPath) };
QProcess process;
process.setProgram(m_globalVariables->godotEditorExecutablePath().toString());
process.setArguments(godotCmd);
return process.startDetached();
}
/*!
\brief Imports a given project from a .screenplay zip file. The argument extractionPath
must be copied otherwise it will get reset in qml before extracting.
*/
bool Util::importProject(QString archivePath, QString extractionPath)
{
m_extractor->clear();
archivePath = ScreenPlayUtil::toLocal(archivePath);
extractionPath = ScreenPlayUtil::toLocal(extractionPath);
QFileInfo fileInfo(archivePath);
if (!fileInfo.fileName().endsWith(".screenplay")) {
qWarning() << "Unsupported file type: " << fileInfo.fileName() << ". We only support '.screenplay' files.";
return false;
}
const QString name = fileInfo.fileName().remove(".screenplay");
const auto timestamp = QDateTime::currentDateTime().toString("ddMMyyyyhhmmss-");
extractionPath = extractionPath + "/" + timestamp + name + "/";
QDir dir(extractionPath);
if (dir.exists()) {
qWarning() << "Directory does already exist!" << dir;
return false;
}
if (!dir.mkdir(extractionPath)) {
qWarning() << "Unable to create directory:" << dir;
return false;
}
m_extractor->setArchive(archivePath);
m_extractor->setOutputDirectory(extractionPath);
m_extractor->setCalculateProgress(true);
m_extractor->getInfo();
m_extractor->start();
return true;
}
/*!
\brief Loads all content of the legal folder in the qrc into a property string of this class.
allLicenseLoaded is emited when loading is finished.
*/
void Util::Util::requestAllLicenses()
{
if (m_requestAllLicensesFuture.isRunning())
return;
m_requestAllLicensesFuture = QtConcurrent::run([this]() {
QString tmp;
QFile file;
QTextStream out(&file);
file.setFileName(":/qml/ScreenPlayApp/legal/Font Awesome Free License.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/gpl-3.0.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/gpl-3.0.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/OFL.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/OpenSSL.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/Qt LGPLv3.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
emit this->allLicenseLoaded(tmp);
});
}
/*!
\brief Loads all dataprotection of the legal folder in the qrc into a property string of this class.
allDataProtectionLoaded is emited when loading is finished.
*/
void Util::Util::requestDataProtection()
{
QString tmp;
QFile file;
QTextStream out(&file);
file.setFileName(":/qml/ScreenPlayApp/legal/DataProtection.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
emit this->allDataProtectionLoaded(tmp);
}
bool Util::fileExists(const QString& filePath) const
{
const QFileInfo file(toLocal(filePath));
return file.isFile();
}
/*!
\brief Takes ownership of \a obj and \a name. Tries to save into a text file
with of name.
*/
bool Util::writeSettings(const QJsonObject& obj, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
QJsonDocument doc(obj);
out << doc.toJson();
file.close();
return true;
}
/*!
\brief Tries to save into a text file with absolute path.
*/
bool Util::writeFile(const QString& text, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
out << text;
file.close();
return true;
}
/*!
\brief Tries to save into a text file with absolute path.
*/
bool Util::writeFileFromQrc(const QString& qrcPath, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
QFile qrc(qrcPath);
qrc.open(QIODevice::ReadOnly);
QTextStream in(&qrc);
// Read line by line to avoid CLRF/LF issues
while (!in.atEnd()) {
out << in.readLine() << "\n";
}
qrc.close();
file.close();
return true;
}
/*!
\brief Takes reference to \a obj. If the copy of the thumbnail is successful,
it adds the corresponding settings entry to the json object reference.
*/
bool Util::copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnail, const QString& destination)
{
const QUrl previewThumbnailUrl { previewThumbnail };
const QFileInfo previewImageFile(previewThumbnailUrl.toString());
const QString destinationFilePath = destination + "/" + previewImageFile.fileName();
if (!previewThumbnail.isEmpty()) {
if (!QFile::copy(previewThumbnailUrl.toLocalFile(), destinationFilePath)) {
qDebug() << "Could not copy" << previewThumbnailUrl.toLocalFile() << " to " << destinationFilePath;
return false;
}
}
obj.insert("previewThumbnail", previewImageFile.fileName());
obj.insert("preview", previewImageFile.fileName());
return true;
}
}
#include "moc_util.cpp"

View File

@ -49,30 +49,30 @@ void Wizards::createQMLWidget(const QString& title,
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("license", licenseName);
obj.insert("title", title);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("createdBy", createdBy);
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::QMLWidget).toString());
obj.insert("file", "main.qml");
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/QMLWidgetMain.qml", workingPath + "/main.qml")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/QMLWidgetMain.qml", workingPath + "/main.qml")) {
qWarning() << "Could not write main.qml";
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -81,7 +81,7 @@ void Wizards::createQMLWidget(const QString& title,
createPreviewImage(title, workingPath);
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
@ -113,23 +113,23 @@ void Wizards::createHTMLWidget(const QString& title,
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("license", licenseName);
obj.insert("createdBy", createdBy);
obj.insert("title", title);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::HTMLWidget).toString());
obj.insert("file", "index.html");
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/HTMLWidgetMain.html", workingPath + "/index.html")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/HTMLWidgetMain.html", workingPath + "/index.html")) {
qWarning() << "Could not write HTMLWidgetMain.html";
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
@ -139,7 +139,7 @@ void Wizards::createHTMLWidget(const QString& title,
QFileInfo previewImageFile(previewThumbnailUrl.toLocalFile());
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -148,7 +148,7 @@ void Wizards::createHTMLWidget(const QString& title,
createPreviewImage(title, workingPath);
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
@ -181,30 +181,30 @@ void Wizards::createHTMLWallpaper(
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("license", licenseName);
obj.insert("createdBy", createdBy);
obj.insert("title", title);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::HTMLWallpaper).toString());
obj.insert("file", "index.html");
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/HTMLWallpaperMain.html", workingPath + "/index.html")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/HTMLWallpaperMain.html", workingPath + "/index.html")) {
qWarning() << "Could not write HTMLWallpaperMain.html";
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -213,7 +213,7 @@ void Wizards::createHTMLWallpaper(
createPreviewImage(title, workingPath);
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
@ -246,18 +246,18 @@ void Wizards::createQMLWallpaper(
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("license", licenseName);
obj.insert("title", title);
obj.insert("createdBy", createdBy);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::QMLWallpaper).toString());
obj.insert("file", "main.qml");
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -266,25 +266,25 @@ void Wizards::createQMLWallpaper(
createPreviewImage(title, workingPath);
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
const QString qmlproject = workingPath + "/" + title + ".qmlproject";
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/" + QString("QmlProject.qmlproject"), qmlproject)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/" + QString("QmlProject.qmlproject"), qmlproject)) {
qWarning() << "Could not write " << qmlproject;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/QMLWallpaperMain.qml", workingPath + "/main.qml")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/QMLWallpaperMain.qml", workingPath + "/main.qml")) {
qWarning() << "Could not write main.qml";
return;
}
@ -317,7 +317,7 @@ void Wizards::createGodotWallpaper(
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("license", licenseName);
@ -330,12 +330,12 @@ void Wizards::createGodotWallpaper(
QString godotVersionMinor = QString::number(SCREENPLAY_GODOT_VERSION_MINOR);
obj.insert("godotVersionMajor", godotVersionMajor);
obj.insert("godotVersionMinor", godotVersionMinor);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::GodotWallpaper).toString());
obj.insert("file", "wallpaper.tscn");
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -344,28 +344,28 @@ void Wizards::createGodotWallpaper(
createPreviewImage(title, workingPath);
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/project.godot", workingPath + "/project.godot")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/project.godot", workingPath + "/project.godot")) {
qWarning() << "Could not write project.godot";
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/spinner.gd", workingPath + "/spinner.gd")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/spinner.gd", workingPath + "/spinner.gd")) {
qWarning() << "Could not write spinner.gd";
return;
}
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/wallpaper.tscn", workingPath + "/wallpaper.tscn")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/wallpaper.tscn", workingPath + "/wallpaper.tscn")) {
qWarning() << "Could not write wallpaper.tscn";
return;
}
@ -373,7 +373,7 @@ void Wizards::createGodotWallpaper(
// This presets file is needed for the export. Because we do only export
// package files, it does not matter that we hardcode "Windows Desktop" as
// export preset.
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/export_presets.cfg", workingPath + "/export_presets.cfg")) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/export_presets.cfg", workingPath + "/export_presets.cfg")) {
qWarning() << "Could not write export_presets.cfg";
return;
}
@ -403,8 +403,8 @@ void Wizards::createGifWallpaper(
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString gifFileName = QFileInfo(ScreenPlayUtil::toLocal(file)).fileName();
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString gifFileName = QFileInfo(m_util.toLocal(file)).fileName();
QJsonObject obj;
obj.insert("license", licenseName);
@ -412,21 +412,21 @@ void Wizards::createGifWallpaper(
obj.insert("title", title);
obj.insert("file", gifFileName);
obj.insert("previewGIF", gifFileName);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::GifWallpaper).toString());
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
if (!m_util.writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
qWarning() << "Could not write " << licenseFile;
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
return;
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}
if (!QFile::copy(ScreenPlayUtil::toLocal(file), workingPath + "/" + gifFileName)) {
if (!QFile::copy(m_util.toLocal(file), workingPath + "/" + gifFileName)) {
qWarning() << "Could not copy gif " << file << " to: " << workingPath + "/" + gifFileName;
emit widgetCreationFinished(WizardResult::CopyFileError);
return;
@ -458,16 +458,16 @@ void Wizards::createWebsiteWallpaper(
return;
}
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
const QString workingPath = m_util.toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
QJsonObject obj;
obj.insert("title", title);
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
obj.insert("tags", m_util.fillArray(tags));
obj.insert("type", QVariant::fromValue(ContentTypes::InstalledType::WebsiteWallpaper).toString());
obj.insert("url", url.toString());
if (!previewThumbnail.isEmpty()) {
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
if (!m_util.copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
return;
}
@ -476,7 +476,7 @@ void Wizards::createWebsiteWallpaper(
createPreviewImage(title, workingPath);
}
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
if (!m_util.writeSettings(obj, workingPath + "/project.json")) {
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
return;
}

View File

@ -6,9 +6,12 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON)
find_package(fmt CONFIG REQUIRED)
# Needed on macos
find_package(Threads REQUIRED)
find_package(LibArchive REQUIRED)
find_package(
Qt6
COMPONENTS Core Quick
COMPONENTS Core Quick Gui
REQUIRED)
set(QML
@ -26,7 +29,6 @@ set(QML
qml/Headline.qml
qml/HeadlineSection.qml
qml/ImageSelector.qml
qml/JSUtil.js
qml/LicenseSelector.qml
qml/ModalBackgroundBlur.qml
qml/MouseHoverBlocker.qml
@ -45,7 +47,8 @@ set(SOURCES
src/logginghandler.cpp
src/projectfile.cpp
src/exitcodes.cpp
src/util.cpp)
src/util.cpp
src/archive.cpp)
set(HEADER
# cmake-format: sort
@ -57,6 +60,7 @@ set(HEADER
inc/public/ScreenPlayUtil/PropertyHelpers.h
inc/public/ScreenPlayUtil/ListPropertyHelper.h
inc/public/ScreenPlayUtil/HelpersCommon.h
inc/public/ScreenPlayUtil/archive.h
inc/public/ScreenPlayUtil/util.h)
if(APPLE)
@ -71,7 +75,8 @@ qt_add_library(
${PROJECT_NAME}
STATIC
${SOURCES}
${HEADER})
${HEADER}
)
qt_add_qml_module(
${PROJECT_NAME}
@ -104,7 +109,11 @@ target_include_directories(${PROJECT_NAME} PUBLIC inc/public/ScreenPlayUtil)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt6::Core Qt6::Quick
PUBLIC fmt::fmt-header-only)
PUBLIC
Qt6::Gui
fmt::fmt-header-only
LibArchive::LibArchive
QArchive)
if(WIN32)
# Used for query windows monitor data

View File

@ -0,0 +1,30 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include "qarchive_enums.hpp"
#include "qarchivediskcompressor.hpp"
#include "qarchivediskextractor.hpp"
namespace ScreenPlay {
class Archive : public QObject {
Q_OBJECT
QML_ELEMENT
public:
explicit Archive(QObject* parent = nullptr);
Q_INVOKABLE bool importProject(QString archivePath, QString extractionPath);
Q_INVOKABLE bool exportProject(QString contentPath, QString exportFileName);
signals:
void extractionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void extractionFinished();
void compressionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void compressionFinished();
private:
std::unique_ptr<QArchive::DiskCompressor> m_compressor;
std::unique_ptr<QArchive::DiskExtractor> m_extractor;
};
}

View File

@ -15,8 +15,6 @@ class ContentTypes : public QObject {
QML_ELEMENT
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
/*!
\namespace ScreenPlay::SearchType
\inmodule ScreenPlayUtil
\brief Global enum for search types. Used in the "Installed" tab.
*/
public:
@ -30,8 +28,6 @@ public:
};
Q_ENUM(SearchType)
/*!
\namespace ScreenPlay::InstalledType
\inmodule ScreenPlayUtil
\brief When changing the enum, one also needs to change:
GlobalVariables::getAvailableWallpaper
GlobalVariables::getAvailableWidgets
@ -61,8 +57,6 @@ class Video : public QObject {
public:
Video(QObject* parent = nullptr);
/*!
\namespace ScreenPlay::FillMode
\inmodule ScreenPlayUtil
\brief Global enum for fill mode. This is a c++ representation
of HTML fill modes. We use "_" instead of "-" for scale down,
because c++ forbids "-" in enum names.
@ -77,8 +71,6 @@ public:
Q_ENUM(FillMode)
/*!
\namespace ScreenPlay::InstalledType
\inmodule ScreenPlayUtil
\brief When changing the enum, one also needs to change:
GlobalVariables::getAvailableWallpaper
GlobalVariables::getAvailableWidgets

View File

@ -2,42 +2,125 @@
#pragma once
#include "ScreenPlayUtil/contenttypes.h"
#include <QClipboard>
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMetaEnum>
#include <QMetaType>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QObject>
#include <QProcess>
#include <QQmlEngine>
#include <QScopeGuard>
#include <QString>
#include <QTextStream>
#include <QVersionNumber>
#include <QtConcurrent/QtConcurrent>
#include <QtGlobal>
#include <optional>
namespace ScreenPlayUtil {
#include "ScreenPlayUtil/contenttypes.h"
QJsonArray fillArray(const QVector<QString>& items);
ScreenPlay::ContentTypes::SearchType getSearchTypeFromInstalledType(const ScreenPlay::ContentTypes::InstalledType type);
std::optional<ScreenPlay::ContentTypes::InstalledType> getInstalledTypeFromString(const QString& type);
std::optional<ScreenPlay::Video::VideoCodec> getVideoCodecFromString(const QString& type);
std::optional<QJsonObject> parseQByteArrayToQJsonObject(const QByteArray& byteArray);
std::optional<QJsonObject> openJsonFileToObject(const QString& path);
std::optional<QString> openJsonFileToString(const QString& path);
std::optional<QVersionNumber> getVersionNumberFromString(const QString& str);
bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate = true);
bool writeSettings(const QJsonObject& obj, const QString& absolutePath);
bool writeFile(const QString& text, const QString& absolutePath);
bool writeFileFromQrc(const QString& qrcPath, const QString& absolutePath);
bool copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnail, const QString& destination);
QString toString(const QStringList& list);
QString toLocal(const QString& url);
QString generateRandomString(quint32 length = 32);
QString executableAppEnding();
QString executableBinEnding();
QStringList getAvailableWallpaper();
QStringList getAvailableWidgets();
QStringList getAvailableTypes();
QStringList getAvailableFillModes();
bool isWallpaper(const ScreenPlay::ContentTypes::InstalledType type);
bool isWidget(const ScreenPlay::ContentTypes::InstalledType type);
std::optional<QVector<int>> parseStringToIntegerList(const QString string);
float roundDecimalPlaces(const float number);
namespace ScreenPlay {
template <typename T>
T QStringToEnum(const QString& key, const T defaultValue)
{
auto metaEnum = QMetaEnum::fromType<T>();
bool ok = false;
T wantedEnum = static_cast<T>(metaEnum.keyToValue(key.toUtf8(), &ok));
if (ok) {
return wantedEnum;
} else {
qWarning() << "Unable to convert QStringToEnum. Key: " << key;
}
return defaultValue;
}
class Util : public QObject {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
public:
QJsonArray fillArray(const QVector<QString>& items);
ScreenPlay::ContentTypes::SearchType getSearchTypeFromInstalledType(const ScreenPlay::ContentTypes::InstalledType type);
std::optional<ScreenPlay::ContentTypes::InstalledType> getInstalledTypeFromString(const QString& type);
std::optional<ScreenPlay::Video::VideoCodec> getVideoCodecFromString(const QString& type);
std::optional<QJsonObject> parseQByteArrayToQJsonObject(const QByteArray& byteArray);
std::optional<QJsonObject> openJsonFileToObject(const QString& path);
std::optional<QString> openJsonFileToString(const QString& path);
std::optional<QVersionNumber> getVersionNumberFromString(const QString& str);
bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate = true);
bool writeSettings(const QJsonObject& obj, const QString& absolutePath);
bool writeFile(const QString& text, const QString& absolutePath);
bool writeFileFromQrc(const QString& qrcPath, const QString& absolutePath);
bool copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnail, const QString& destination);
QString toString(const QStringList& list) const;
std::optional<QVector<int>> parseStringToIntegerList(const QString string) const;
float roundDecimalPlaces(const float number) const;
QString generateRandomString(quint32 length = 32);
QString executableAppEnding();
QString executableBinEnding();
QStringList getAvailableWallpaper() const;
QStringList getAvailableWidgets() const;
QStringList getAvailableTypes() const;
QStringList getAvailableFillModes() const;
// QML callable functions
Q_INVOKABLE QString toLocal(const QString& url) const;
Q_INVOKABLE bool isWallpaper(const ScreenPlay::ContentTypes::InstalledType type) const;
Q_INVOKABLE bool isWidget(const ScreenPlay::ContentTypes::InstalledType type) const;
Q_INVOKABLE bool isScene(const ScreenPlay::ContentTypes::InstalledType type) const;
Q_INVOKABLE bool isVideo(const ScreenPlay::ContentTypes::InstalledType type) const;
Q_INVOKABLE void copyToClipboard(const QString& text) const;
Q_INVOKABLE void openFolderInExplorer(const QString& url) const;
Q_INVOKABLE bool openGodotEditor(QString contentPath) const;
Q_INVOKABLE void requestAllLicenses();
Q_INVOKABLE void requestDataProtection();
Q_INVOKABLE bool fileExists(const QString& filePath) const;
Q_INVOKABLE void setNavigation(QString nav)
{
emit requestNavigation(nav);
}
// When we create a wallpaper the main navigation gets disabled
Q_INVOKABLE void setNavigationActive(bool isActive)
{
emit requestNavigationActive(isActive);
}
Q_INVOKABLE void setToggleWallpaperConfiguration()
{
emit requestToggleWallpaperConfiguration();
}
signals:
void extractionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void extractionFinished();
void compressionProgressChanged(QString file, int proc, int total, qint64 br, qint64 bt);
void compressionFinished();
void requestNavigation(QString nav);
void requestNavigationActive(bool isActive);
void requestToggleWallpaperConfiguration();
void setSidebarItem(QString folderName, ScreenPlay::ContentTypes::InstalledType type);
void allLicenseLoaded(QString licensesText);
void allDataProtectionLoaded(QString dataProtectionText);
private:
QFuture<void> m_requestAllLicensesFuture;
};
}

View File

@ -1,25 +1,25 @@
function isWallpaper(type) {
return type === InstalledType.VideoWallpaper
|| type === InstalledType.HTMLWallpaper
|| type === InstalledType.QMLWallpaper
|| type === InstalledType.GifWallpaper
|| type === InstalledType.WebsiteWallpaper
|| type === InstalledType.GodotWallpaper
return type === ContentTypes.InstalledType.VideoWallpaper
|| type === ContentTypes.InstalledType.HTMLWallpaper
|| type === ContentTypes.InstalledType.QMLWallpaper
|| type === ContentTypes.InstalledType.GifWallpaper
|| type === ContentTypes.InstalledType.WebsiteWallpaper
|| type === ContentTypes.InstalledType.GodotWallpaper
}
function isWidget(type) {
return type === InstalledType.HTMLWidget || type === InstalledType.QMLWidget
return type === ContentTypes.InstalledType.HTMLWidget || type === ContentTypes.InstalledType.QMLWidget
}
function isScene(type) {
return type === InstalledType.HTMLWallpaper
|| type === InstalledType.QMLWallpaper
|| type === InstalledType.WebsiteWallpaper
|| type === InstalledType.GodotWallpaper
return type === ContentTypes.InstalledType.HTMLWallpaper
|| type === ContentTypes.InstalledType.QMLWallpaper
|| type === ContentTypes.InstalledType.WebsiteWallpaper
|| type === ContentTypes.InstalledType.GodotWallpaper
}
function isVideo(type) {
return type === InstalledType.VideoWallpaper
|| type === InstalledType.GifWallpaper
return type === ContentTypes.InstalledType.VideoWallpaper
|| type === ContentTypes.InstalledType.GifWallpaper
}

View File

@ -0,0 +1,90 @@
#include "ScreenPlayUtil/archive.h"
#include "ScreenPlayUtil/util.h"
namespace ScreenPlay {
Archive::Archive(QObject* parent)
: QObject { parent }
{
m_extractor = std::make_unique<QArchive::DiskExtractor>();
m_compressor = std::make_unique<QArchive::DiskCompressor>();
QObject::connect(m_extractor.get(), &QArchive::DiskExtractor::progress, this, &Archive::extractionProgressChanged);
QObject::connect(m_extractor.get(), &QArchive::DiskExtractor::finished, this, &Archive::extractionFinished);
QObject::connect(m_compressor.get(), &QArchive::DiskCompressor::progress, this, &Archive::compressionProgressChanged);
QObject::connect(m_compressor.get(), &QArchive::DiskCompressor::finished, this, &Archive::compressionFinished);
}
/*!
\brief Imports a given project from a .screenplay zip file. The argument extractionPath
must be copied otherwise it will get reset in qml before extracting.
*/
bool Archive::importProject(QString archivePath, QString extractionPath)
{
m_extractor->clear();
Util util;
archivePath = util.toLocal(archivePath);
extractionPath = util.toLocal(extractionPath);
QFileInfo fileInfo(archivePath);
if (!fileInfo.fileName().endsWith(".screenplay")) {
qWarning() << "Unsupported file type: " << fileInfo.fileName() << ". We only support '.screenplay' files.";
return false;
}
const QString name = fileInfo.fileName().remove(".screenplay");
const auto timestamp = QDateTime::currentDateTime().toString("ddMMyyyyhhmmss-");
extractionPath = extractionPath + "/" + timestamp + name + "/";
QDir dir(extractionPath);
if (dir.exists()) {
qWarning() << "Directory does already exist!" << dir;
return false;
}
if (!dir.mkdir(extractionPath)) {
qWarning() << "Unable to create directory:" << dir;
return false;
}
m_extractor->setArchive(archivePath);
m_extractor->setOutputDirectory(extractionPath);
m_extractor->setCalculateProgress(true);
m_extractor->getInfo();
m_extractor->start();
return true;
}
/*!
\brief Exports a given project into a .screenplay 7Zip file.
*/
bool Archive::exportProject(QString contentPath, QString exportFileName)
{
m_compressor->clear();
Util util;
contentPath = util.toLocal(contentPath);
exportFileName = util.toLocal(exportFileName);
QDir dir(contentPath);
bool success = true;
if (!dir.exists()) {
qWarning() << "Directory does not exist!" << dir;
return false;
}
QStringList files;
for (auto& item : dir.entryInfoList(QDir::Files)) {
files.append(item.absoluteFilePath());
}
QFile exportFile(exportFileName);
if (exportFile.exists()) {
if (!exportFile.remove()) {
qWarning() << "Unable to delte file marked to override!" << dir;
return false;
}
}
m_compressor->setFileName(exportFileName);
m_compressor->setArchiveFormat(QArchive::SevenZipFormat);
m_compressor->addFiles(files);
m_compressor->start();
return true;
}
}

View File

@ -7,7 +7,8 @@ bool ProjectFile::init()
if (!isValid())
return false;
const auto jsonObjOpt = ScreenPlayUtil::openJsonFileToObject(projectJsonFilePath.absoluteFilePath());
Util util;
const auto jsonObjOpt = util.openJsonFileToObject(projectJsonFilePath.absoluteFilePath());
QDir folder = projectJsonFilePath.dir();
folderName = folder.dirName();
QFileInfo folderInfo(folder.path());
@ -29,7 +30,7 @@ bool ProjectFile::init()
if (!obj.contains("type"))
return false;
auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString());
auto typeParsed = util.getInstalledTypeFromString(obj.value("type").toString());
if (!typeParsed.has_value()) {
qWarning() << "Type could not parsed from string: " << obj.value("type").toString();
return false;
@ -99,10 +100,10 @@ bool ProjectFile::init()
}
}
searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(type);
searchType = util.getSearchTypeFromInstalledType(type);
if (obj.contains("codec")) {
if (auto videoCodecOpt = ScreenPlayUtil::getVideoCodecFromString(obj.value("codec").toString())) {
if (auto videoCodecOpt = util.getVideoCodecFromString(obj.value("codec").toString())) {
videoCodec = videoCodecOpt.value();
} else {
qWarning("Invalid videoCodec was specified inside the json object!");

View File

@ -1,5 +1,7 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlayUtil/util.h"
#include "qguiapplication.h"
#include <QDesktopServices>
#include <QFile>
#include <QJsonParseError>
#include <QRandomGenerator>
@ -10,18 +12,18 @@
\brief Module for ScreenPlayUtil.
*/
/*!
\namespace ScreenPlayUtil
\namespace ScreenPlay
\inmodule ScreenPlayUtil
\brief Namespace for ScreenPlayUtil.
*/
namespace ScreenPlayUtil {
namespace ScreenPlay {
/*!
\brief Opens a json file (absolute path) and tries to convert it to a QJsonObject.
Returns std::nullopt when not successful.
*/
std::optional<QJsonObject> openJsonFileToObject(const QString& path)
std::optional<QJsonObject> Util::openJsonFileToObject(const QString& path)
{
auto jsonString = openJsonFileToString(path);
@ -45,7 +47,7 @@ std::optional<QJsonObject> openJsonFileToObject(const QString& path)
\brief Writes a QJsonObject into a given file. It defaults to truncate the file
or you can set it to append to an existing file.
*/
bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate)
bool Util::writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& object, bool truncate)
{
QFile configTmp;
configTmp.setFileName(absoluteFilePath);
@ -69,11 +71,78 @@ bool writeJsonObjectToFile(const QString& absoluteFilePath, const QJsonObject& o
return true;
}
/*!
\brief Takes ownership of \a obj and \a name. Tries to save into a text file
with of name.
*/
bool Util::writeSettings(const QJsonObject& obj, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
QJsonDocument doc(obj);
out << doc.toJson();
file.close();
return true;
}
/*!
\brief Tries to save into a text file with absolute path.
*/
bool Util::writeFile(const QString& text, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
out << text;
file.close();
return true;
}
/*!
\brief Tries to save into a text file with absolute path.
*/
bool Util::writeFileFromQrc(const QString& qrcPath, const QString& absolutePath)
{
QFile file { absolutePath };
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not open" << absolutePath;
return false;
}
QTextStream out(&file);
out.setEncoding(QStringConverter::Utf8);
QFile qrc(qrcPath);
qrc.open(QIODevice::ReadOnly);
QTextStream in(&qrc);
// Read line by line to avoid CLRF/LF issues
while (!in.atEnd()) {
out << in.readLine() << "\n";
}
qrc.close();
file.close();
return true;
}
/*!
\brief Opens a json file (absolute path) and tries to convert it to a QString.
Returns std::nullopt when not successful.
*/
std::optional<QString> openJsonFileToString(const QString& path)
std::optional<QString> Util::openJsonFileToString(const QString& path)
{
QFile file;
file.setFileName(path);
@ -96,7 +165,7 @@ std::optional<QString> openJsonFileToString(const QString& path)
\li 0-9
\endlist
*/
QString generateRandomString(quint32 length)
QString Util::generateRandomString(quint32 length)
{
const QString possibleCharacters {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
@ -115,7 +184,7 @@ QString generateRandomString(quint32 length)
/*!
\brief Return .exe on windows otherwise empty string.
*/
QString executableBinEnding()
QString Util::executableBinEnding()
{
#ifdef Q_OS_WIN
return ".exe";
@ -126,7 +195,7 @@ QString executableBinEnding()
/*!
\brief Return .exe on windows, .app on osx otherwise empty string.
*/
QString executableAppEnding()
QString Util::executableAppEnding()
{
#ifdef Q_OS_WIN
return ".exe";
@ -142,7 +211,7 @@ QString executableAppEnding()
1.0.0 - Major.Minor.Patch. A fixed position is used for parsing (at 0,2,4).
Return std::nullopt when not successful.
*/
std::optional<QVersionNumber> getVersionNumberFromString(const QString& str)
std::optional<QVersionNumber> Util::getVersionNumberFromString(const QString& str)
{
// Must be: Major.Minor.Patch
bool okMajor { false };
@ -163,7 +232,7 @@ std::optional<QVersionNumber> getVersionNumberFromString(const QString& str)
/*!
\brief Parses a QByteArray to a QJsonObject. If returns and std::nullopt on failure.
*/
std::optional<QJsonObject> parseQByteArrayToQJsonObject(const QByteArray& byteArray)
std::optional<QJsonObject> Util::parseQByteArrayToQJsonObject(const QByteArray& byteArray)
{
QJsonObject obj;
QJsonParseError err {};
@ -180,7 +249,7 @@ std::optional<QJsonObject> parseQByteArrayToQJsonObject(const QByteArray& byteAr
/*!
\brief Helper function to append a QStringList into a QString with a space between the items.
*/
QString toString(const QStringList& list)
QString Util::toString(const QStringList& list) const
{
QString out;
for (const auto& string : list) {
@ -192,7 +261,7 @@ QString toString(const QStringList& list)
/*!
\brief Util function that converts a QVector of Strings into a QJsonArray.
*/
QJsonArray fillArray(const QVector<QString>& items)
QJsonArray Util::fillArray(const QVector<QString>& items)
{
QJsonArray array;
for (const QString& item : items) {
@ -204,7 +273,7 @@ QJsonArray fillArray(const QVector<QString>& items)
/*!
\brief Maps the Search type to an installed type. Used for filtering the installed content.
*/
ScreenPlay::ContentTypes::SearchType getSearchTypeFromInstalledType(const ScreenPlay::ContentTypes::InstalledType type)
ScreenPlay::ContentTypes::SearchType Util::getSearchTypeFromInstalledType(const ScreenPlay::ContentTypes::InstalledType type)
{
using namespace ScreenPlay;
switch (type) {
@ -228,7 +297,7 @@ ScreenPlay::ContentTypes::SearchType getSearchTypeFromInstalledType(const Screen
/*!
\brief Maps the installed type from a QString to an enum. Used for parsing the project.json.
*/
std::optional<ScreenPlay::ContentTypes::InstalledType> getInstalledTypeFromString(const QString& type)
std::optional<ScreenPlay::ContentTypes::InstalledType> Util::getInstalledTypeFromString(const QString& type)
{
using namespace ScreenPlay;
if (type.endsWith("Wallpaper", Qt::CaseInsensitive)) {
@ -267,7 +336,7 @@ std::optional<ScreenPlay::ContentTypes::InstalledType> getInstalledTypeFromStrin
/*!
\brief Maps the video codec type from a QString to an enum. Used for parsing the project.json.
*/
std::optional<ScreenPlay::Video::VideoCodec> getVideoCodecFromString(const QString& type)
std::optional<ScreenPlay::Video::VideoCodec> Util::getVideoCodecFromString(const QString& type)
{
if (type.isEmpty())
return std::nullopt;
@ -293,7 +362,7 @@ std::optional<ScreenPlay::Video::VideoCodec> getVideoCodecFromString(const QStri
/*!
\brief Converts the given \a url string to a local file path.
*/
QString toLocal(const QString& url)
QString Util::toLocal(const QString& url) const
{
return QUrl(url).toLocalFile();
}
@ -301,7 +370,7 @@ QString toLocal(const QString& url)
/*!
\brief Returns a list of available wallpaper types like videoWallpaper.
*/
QStringList getAvailableWallpaper()
QStringList Util::getAvailableWallpaper() const
{
return {
"qmlWallpaper",
@ -316,7 +385,7 @@ QStringList getAvailableWallpaper()
/*!
\brief Returns a list of available widget types like qmlWidget.
*/
QStringList getAvailableWidgets()
QStringList Util::getAvailableWidgets() const
{
return {
"qmlWidget",
@ -327,7 +396,7 @@ QStringList getAvailableWidgets()
/*!
\brief Returns a combined list of available widgets and wallpaper types.
*/
QStringList getAvailableTypes()
QStringList Util::getAvailableTypes() const
{
return { getAvailableWallpaper() + getAvailableWidgets() };
}
@ -335,7 +404,7 @@ QStringList getAvailableTypes()
/*!
\brief Returns true of the given type is a wallpaper.
*/
bool isWallpaper(const ScreenPlay::ContentTypes::InstalledType type)
bool Util::isWallpaper(const ScreenPlay::ContentTypes::InstalledType type) const
{
using namespace ScreenPlay;
@ -350,18 +419,40 @@ bool isWallpaper(const ScreenPlay::ContentTypes::InstalledType type)
/*!
\brief Returns true of the given type is a widget.
*/
bool isWidget(const ScreenPlay::ContentTypes::InstalledType type)
bool Util::isWidget(const ScreenPlay::ContentTypes::InstalledType type) const
{
using namespace ScreenPlay;
return (type == ContentTypes::InstalledType::QMLWidget || type == ContentTypes::InstalledType::HTMLWidget);
}
/*!
\brief Returns true of the given type is a isScene.
*/
bool Util::isScene(const ScreenPlay::ContentTypes::InstalledType type) const
{
using namespace ScreenPlay;
return (type == ContentTypes::InstalledType::HTMLWallpaper
|| type == ContentTypes::InstalledType::QMLWallpaper
|| type == ContentTypes::InstalledType::WebsiteWallpaper
|| type == ContentTypes::InstalledType::GodotWallpaper);
}
/*!
\brief Returns true of the given type is a isVideo.
*/
bool Util::isVideo(const ScreenPlay::ContentTypes::InstalledType type) const
{
using namespace ScreenPlay;
return (type == ContentTypes::InstalledType::VideoWallpaper
|| type == ContentTypes::InstalledType::GifWallpaper);
}
/*!
\brief HTML video fillModes to be used in the QWebEngine video player.
See https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
*/
QStringList getAvailableFillModes()
QStringList Util::getAvailableFillModes() const
{
return { "stretch", "fill", "contain", "cover", "scale-down" };
}
@ -370,7 +461,7 @@ QStringList getAvailableFillModes()
\brief parseIntList parses a list of string separated with a comma
"1,2,3". IMPORTANT: No trailing comma!
*/
std::optional<QVector<int>> parseStringToIntegerList(const QString string)
std::optional<QVector<int>> Util::parseStringToIntegerList(const QString string) const
{
if (string.isEmpty())
return {};
@ -390,10 +481,145 @@ std::optional<QVector<int>> parseStringToIntegerList(const QString string)
return list;
}
float roundDecimalPlaces(const float number)
float Util::roundDecimalPlaces(const float number) const
{
float big = number * 100.0;
return std::ceil(big * 0.01);
}
/*!
\brief Copies the given string to the clipboard.
*/
void Util::copyToClipboard(const QString& text) const
{
auto* clipboard = QGuiApplication::clipboard();
clipboard->setText(text);
}
/*!
\brief Opens a native folder window on the given path. Windows and Mac only for now!
*/
void Util::openFolderInExplorer(const QString& url) const
{
const QString path = QUrl::fromUserInput(url).toLocalFile();
// QDesktopServices can hang on Windows
if (QSysInfo::productType() == "windows") {
QProcess explorer;
explorer.setProgram("explorer.exe");
// When we have space in the path like
// C:\Program Files (x86)\Steam\...
// we cannot set the path as an argument. But we can set the working it
// to the wanted path and open the current path via the dot.
explorer.setWorkingDirectory(QDir::toNativeSeparators(path));
explorer.setArguments({ "." });
explorer.startDetached();
return;
}
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
bool Util::openGodotEditor(QString contentPath) const
{
const QList<QString> godotCmd = { "--editor", "--path", toLocal(contentPath) };
QProcess process;
// process.setProgram(m_globalVariables->godotEditorExecutablePath().toString());
process.setArguments(godotCmd);
return process.startDetached();
}
/*!
\brief Loads all content of the legal folder in the qrc into a property string of this class.
allLicenseLoaded is emited when loading is finished.
*/
void Util::requestAllLicenses()
{
if (m_requestAllLicensesFuture.isRunning())
return;
m_requestAllLicensesFuture = QtConcurrent::run([this]() {
QString tmp;
QFile file;
QTextStream out(&file);
file.setFileName(":/qml/ScreenPlayApp/legal/Font Awesome Free License.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/gpl-3.0.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/gpl-3.0.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/OFL.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/OpenSSL.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
file.setFileName(":/qml/ScreenPlayApp/legal/Qt LGPLv3.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
emit this->allLicenseLoaded(tmp);
});
}
/*!
\brief Loads all dataprotection of the legal folder in the qrc into a property string of this class.
allDataProtectionLoaded is emited when loading is finished.
*/
void Util::requestDataProtection()
{
QString tmp;
QFile file;
QTextStream out(&file);
file.setFileName(":/qml/ScreenPlayApp/legal/DataProtection.txt");
file.open(QIODevice::ReadOnly | QIODevice::Text);
tmp += out.readAll();
file.close();
emit this->allDataProtectionLoaded(tmp);
}
bool Util::fileExists(const QString& filePath) const
{
const QFileInfo file(toLocal(filePath));
return file.isFile();
}
/*!
\brief Takes reference to \a obj. If the copy of the thumbnail is successful,
it adds the corresponding settings entry to the json object reference.
*/
bool Util::copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnail, const QString& destination)
{
const QUrl previewThumbnailUrl { previewThumbnail };
const QFileInfo previewImageFile(previewThumbnailUrl.toString());
const QString destinationFilePath = destination + "/" + previewImageFile.fileName();
if (!previewThumbnail.isEmpty()) {
if (!QFile::copy(previewThumbnailUrl.toLocalFile(), destinationFilePath)) {
qDebug() << "Could not copy" << previewThumbnailUrl.toLocalFile() << " to " << destinationFilePath;
return false;
}
}
obj.insert("previewThumbnail", previewImageFile.fileName());
obj.insert("preview", previewImageFile.fileName());
return true;
}
}

View File

@ -85,8 +85,8 @@ int main(int argc, char* argv[])
if (argumentList.length() != 9) {
return static_cast<int>(ScreenPlay::WallpaperExit::Code::Invalid_ArgumentSize);
}
const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1));
ScreenPlay::Util util;
const auto activeScreensList = util.parseStringToIntegerList(argumentList.at(1));
if (!activeScreensList.has_value()) {
qCritical("Could not activeScreensList");
@ -94,7 +94,7 @@ int main(int argc, char* argv[])
}
auto installedType = ScreenPlay::ContentTypes::InstalledType::Unknown;
if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(argumentList.at(6))) {
if (auto typeOpt = util.getInstalledTypeFromString(argumentList.at(6))) {
installedType = typeOpt.value();
} else {
qCritical() << "Cannot parse Wallpaper type from value" << argumentList.at(6);

View File

@ -2,6 +2,8 @@ import QtQml
import QtQuick
import QtQuick.Controls
import ScreenPlayWallpaper
import ScreenPlayUtil
Rectangle {
id: root
@ -18,7 +20,7 @@ Rectangle {
// macOS only supports h264 via the native Qt MM
if (Qt.platform.os === "osx") {
if ((Wallpaper.videoCodec === VideoCodec.VP8 || Wallpaper.videoCodec === VideoCodec.VP9)) {
if ((Wallpaper.videoCodec === Video.VideoCodec.VP8 || Wallpaper.videoCodec === Util.Video.VideoCodec.VP9)) {
loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaWebView.qml";
} else {
loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml";

View File

@ -150,7 +150,7 @@ void BaseWindow::replaceWallpaper(
setVolume(volume);
setFillMode(fillMode);
if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(type)) {
if (auto typeOpt = ScreenPlay::Util().getInstalledTypeFromString(type)) {
setType(typeOpt.value());
}

View File

@ -231,10 +231,10 @@ public slots:
fillMode = fillMode.toLower();
if (!ScreenPlayUtil::getAvailableFillModes().contains(fillMode)) {
if (!ScreenPlay::Util().getAvailableFillModes().contains(fillMode)) {
qWarning() << "Unable to set fillmode, the provided value did not match the available values"
<< "Provided: " << fillMode
<< "Available: " << ScreenPlayUtil::getAvailableFillModes();
<< "Available: " << ScreenPlay::Util().getAvailableFillModes();
return;
}

View File

@ -31,7 +31,7 @@ void ScreenPlayWeather::updateLatitudeLongtitude(const QString& city)
if (data.size() <= 0)
return;
const auto msgOpt = ScreenPlayUtil::parseQByteArrayToQJsonObject(data);
const auto msgOpt = ScreenPlay::Util().parseQByteArrayToQJsonObject(data);
if (!msgOpt.has_value())
return;
@ -80,13 +80,13 @@ void ScreenPlayWeather::update()
request.setUrl(url);
qInfo() << url;
auto* reply = m_networkAccessManager.get(request);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
const QByteArray data = reply->readAll();
if (data.size() <= 0)
return;
const auto msgOpt = ScreenPlayUtil::parseQByteArrayToQJsonObject(data);
ScreenPlay::Util util;
const auto msgOpt = util.parseQByteArrayToQJsonObject(data);
if (!msgOpt.has_value())
return;
@ -113,10 +113,10 @@ void ScreenPlayWeather::update()
day->set_sunrise(QDateTime::fromString(sunrise.at(i).toString(), m_dataTimeFormat).toString("mm:ss"));
day->set_sunset(QDateTime::fromString(sunset.at(i).toString(), m_dataTimeFormat).toString("mm:ss"));
day->set_weatherCode(weathercode.at(i).toInt());
day->set_temperature_2m_min(ScreenPlayUtil::roundDecimalPlaces(temperature_2m_min.at(i).toDouble()));
day->set_temperature_2m_max(ScreenPlayUtil::roundDecimalPlaces(temperature_2m_max.at(i).toDouble()));
day->set_temperature_2m_min(util.roundDecimalPlaces(temperature_2m_min.at(i).toDouble()));
day->set_temperature_2m_max(util.roundDecimalPlaces(temperature_2m_max.at(i).toDouble()));
day->set_precipitationHours(precipitation_hours.at(i).toInt());
day->set_precipitationSum(ScreenPlayUtil::roundDecimalPlaces(precipitation_sum.at(i).toDouble()));
day->set_precipitationSum(util.roundDecimalPlaces(precipitation_sum.at(i).toDouble()));
m_days.append(&m_days, std::move(day));
}
const auto hourly = msgOpt->value("hourly").toObject();

View File

@ -48,12 +48,13 @@ WidgetWindow::WidgetWindow(
setWindowBlur();
#endif
ScreenPlay::Util util;
if (projectPath == "test") {
setProjectSourceFileAbsolute({ "qrc:/qml/ScreenPlayWidget/qml/Test.qml" });
setType(ScreenPlay::ContentTypes::InstalledType::QMLWidget);
} else {
setProjectPath(projectPath);
auto projectOpt = ScreenPlayUtil::openJsonFileToObject(m_projectPath + "/project.json");
auto projectOpt = util.openJsonFileToObject(m_projectPath + "/project.json");
if (!projectOpt.has_value()) {
qWarning() << "Unable to parse project file!";
return;
@ -63,7 +64,7 @@ WidgetWindow::WidgetWindow(
setProjectSourceFile(m_project.value("file").toString());
setProjectSourceFileAbsolute(QUrl::fromLocalFile(m_projectPath + "/" + projectSourceFile()));
if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(m_project.value("type").toString())) {
if (auto typeOpt = util.getInstalledTypeFromString(m_project.value("type").toString())) {
setType(typeOpt.value());
} else {
qWarning() << "Cannot parse Wallpaper type from value" << m_project.value("type");

View File

@ -55,9 +55,9 @@ void SteamWorkshopItem::uploadItemToWorkshop(CreateItemResult_t* pCallback, bool
return;
}
const QString absoluteContentPath = ScreenPlayUtil::toLocal(m_absolutePath.toString());
auto jsonObjectOpt = ScreenPlayUtil::openJsonFileToObject(absoluteContentPath + "/project.json");
ScreenPlay::Util util;
const QString absoluteContentPath = util.toLocal(m_absolutePath.toString());
auto jsonObjectOpt = util.openJsonFileToObject(absoluteContentPath + "/project.json");
if (!jsonObjectOpt.has_value()) {
qWarning() << "Unable to load project file";
@ -212,9 +212,10 @@ void SteamWorkshopItem::submitItemUpdateStatus(SubmitItemUpdateResult_t* pCallba
void SteamWorkshopItem::saveWorkshopID()
{
ScreenPlay::Util util;
const QString path = QUrl::fromUserInput(m_absolutePath.toString() + "/project.json").toLocalFile();
qInfo() << m_absolutePath << m_publishedFileId << path;
auto jsonProject = ScreenPlayUtil::openJsonFileToObject(path);
auto jsonProject = util.openJsonFileToObject(path);
if (!jsonProject.has_value()) {
qWarning() << "Could not parse project file!";
@ -225,7 +226,7 @@ void SteamWorkshopItem::saveWorkshopID()
jsonObject.insert("workshopid", m_publishedFileId.toString());
qInfo() << "Writing workshopID: " << m_publishedFileId.toString() << "into: " << path;
if (!ScreenPlayUtil::writeJsonObjectToFile(path, jsonObject)) {
if (!util.writeJsonObjectToFile(path, jsonObject)) {
qWarning() << "Could not write project file!";
}
}