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

Merge branch 'master' into qt6-support

# Conflicts:
#	CMakeLists.txt
#	ScreenPlay/app.h
#	ScreenPlay/main.cpp
#	ScreenPlay/main.qml
#	ScreenPlay/qml/Navigation/Navigation.qml
#	ScreenPlay/src/settings.h
#	ScreenPlay/translations/ScreenPlay_zh_cn.qm
#	ScreenPlayWallpaper/CMakeLists.txt
#	ScreenPlayWallpaper/SPWResources.qrc
#	ScreenPlayWallpaper/qml/Wallpaper.qml
This commit is contained in:
Elias Steurer 2021-09-10 11:09:38 +02:00
commit 4504f06eb1
198 changed files with 39583 additions and 7941 deletions

3
.gitattributes vendored
View File

@ -1,3 +0,0 @@
*.dll filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored
View File

@ -91,3 +91,4 @@ _deps
.cmake/** .cmake/**
/Common/ffmpeg/* /Common/ffmpeg/*
/Docs/html/screenplay.index /Docs/html/screenplay.index
/ContentBuilder/**

View File

@ -13,8 +13,8 @@ check:
script: script:
- cd Tools - cd Tools
- pip install cmakelang - pip install cmakelang
- python format_cmake.py - python clang_format.py
- python format_cpp.py - python cmake_format.py
build:windows_debug: build:windows_debug:
stage: build stage: build
@ -84,23 +84,24 @@ build:linux_debug:
stage: build stage: build
allow_failure: true allow_failure: true
image: image:
name: darkmattercoder/qt-build:5.15.2 name: ubuntu:20.04
entrypoint: [""]
tags: tags:
- gitlab-org-docker - gitlab-org-docker
needs: needs:
- check - check
script: script:
- sudo apt-get update -y - apt update -y
- sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common -y # Otherwise libglib2 needs interaction
- sudo snap install cqtdeployer - export DEBIAN_FRONTEND=noninteractive
- wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null - apt install mesa-common-dev curl zip unzip tar git pkg-config apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common wget python3-pip build-essential libgl1-mesa-dev lld ninja-build cmake -y
- sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic-rc main' -y - pip3 install aqtinstall
- sudo apt-get update -y - mkdir Qt
- sudo apt install build-essential libgl1-mesa-dev lld ninja-build cmake -y - aqt install --outputdir Qt/ 5.15.2 linux desktop
- cd Tools - cd Tools
- python setup.py - wget -q https://github.com/QuasarApp/CQtDeployer/releases/download/1.5.2/CQtDeployer_1.5.2_OfflineInstaller_Linux64.run
- python build.py -t debug - python3 setup.py
- python3 build.py -t debug
artifacts: artifacts:
expire_in: "4 weeks" expire_in: "4 weeks"
paths: paths:
@ -110,24 +111,23 @@ build:linux_release:
stage: build stage: build
allow_failure: true allow_failure: true
image: image:
name: darkmattercoder/qt-build:5.15.1 name: ubuntu:20.04
entrypoint: [""]
tags: tags:
- gitlab-org-docker - gitlab-org-docker
needs: needs:
- check - check
script: script:
- sudo apt-get update -y - apt update -y
- sudo apt-get install apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common snapd -y # Otherwise libglib2 needs interaction
- sudo /etc/init.d/snapd start - export DEBIAN_FRONTEND=noninteractive
- sudo snap install cqtdeployer - apt install mesa-common-dev curl zip unzip tar git pkg-config apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common wget python3-pip build-essential libgl1-mesa-dev lld ninja-build cmake -y
- wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null - pip3 install aqtinstall
- sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic-rc main' -y - mkdir Qt
- sudo apt-get update -y - aqt install --outputdir Qt/ 5.15.2 linux desktop
- sudo apt install build-essential libgl1-mesa-dev lld ninja-build cmake -y
- cd Tools - cd Tools
- python setup.py - wget -q https://github.com/QuasarApp/CQtDeployer/releases/download/1.5.2/CQtDeployer_1.5.2_OfflineInstaller_Linux64.run
- python build.py -t release - python3 setup.py
- python3 build.py -t release
artifacts: artifacts:
expire_in: "4 weeks" expire_in: "4 weeks"
paths: paths:

Binary file not shown.

BIN
.gitlab/media/preview.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 MiB

9
CMake/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
project(CMake)
set(FILES # cmake-format: sortable
QtUpdateTranslations.cmake)
add_custom_target(
${PROJECT_NAME}
SOURCES ${FILES}
COMMENT "Dummy target to list these files in the IDE")

View File

@ -0,0 +1,16 @@
find_program(LUPDATE_EXECUTABLE lupdate)
find_program(LRELEASE_EXECUTABLE lrelease)
# Updates all ts files and generates .qm
# Absolute paths are needed!
# qt_update_translations("${CMAKE_CURRENT_SOURCE_DIR}/qml" "${L10N_LIST}")
# The second argument (list) __must__ be passed as string!
function(qt_update_translations SOURCE_PATH TS_FILES)
foreach(_ts_file ${TS_FILES})
message(STATUS "Update Translation: ${_ts_file}")
execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET)
execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file} OUTPUT_QUIET)
endforeach()
endfunction()

View File

@ -6,7 +6,15 @@ project(ScreenPlay LANGUAGES CXX)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
option(SCREENPLAY_FOSS "" true)
option(SCREENPLAY_STEAM_DEPLOY OFF "Steam build settings. Disables steam_app.txt copy step, that is only needed for development.")
option(SCREENPLAY_STEAM ON "For FOSS distribution so we do not bundle proprietary code.")
option(TESTS_ENABLED OFF)
# Add our *.cmake diretory to the CMAKE_MODULE_PATH, so that our includes are found
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
file(MAKE_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
@ -18,31 +26,20 @@ elseif(APPLE)
set(VCPKG_ARCH "x64-osx") set(VCPKG_ARCH "x64-osx")
endif() endif()
# Assume built-in pthreads on MacOS https://stackoverflow.com/questions/54587052/cmake-on-mac-could-not-find-threads-missing-threads-found if(${TESTS_ENABLED})
if(APPLE) enable_testing()
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
set(THREADS_PREFER_PTHREAD_FLAG ON)
endif()
if(${SCREENPLAY_FOSS})
set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlay-vcpkg")
else()
set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../ScreenPlay-vcpkg")
endif() endif()
set(VCPKG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlay-vcpkg")
set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}") set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}")
find_package(Git REQUIRED) find_package(Git REQUIRED)
if(WIN32) if(WIN32)
set(date_command "CMD") set(date_command "CMD")
set(date_arg "/c date /t") set(date_arg "/c date /t")
elseif(APPLE) elseif(APPLE)
set(date_command "date") set(date_command "date")
set(date_arg " +%y.%m.%d") set(date_arg "")
elseif(UNIX) elseif(UNIX)
set(date_command "date") set(date_command "date")
set(date_arg "") set(date_arg "")
@ -52,15 +49,16 @@ execute_process(
COMMAND ${date_command} ${date_arg} COMMAND ${date_command} ${date_arg}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE BUILD_DATE OUTPUT_VARIABLE BUILD_DATE
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process( execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --always COMMAND "${GIT_EXECUTABLE}" describe --always
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_VARIABLE GIT_COMMIT_HASH
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
add_compile_definitions(COMPILE_INFO="${BUILD_DATE} + ${GIT_COMMIT_HASH}") add_compile_definitions(COMPILE_INFO="${BUILD_DATE} + ${GIT_COMMIT_HASH}")
add_compile_definitions(SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
# Fixes QWebEngine linker errors on Ubuntu 20.04 # Fixes QWebEngine linker errors on Ubuntu 20.04
@ -74,13 +72,24 @@ add_subdirectory(ScreenPlayShader)
add_subdirectory(ScreenPlayWallpaper) add_subdirectory(ScreenPlayWallpaper)
add_subdirectory(ScreenPlayWidget) add_subdirectory(ScreenPlayWidget)
add_subdirectory(ScreenPlayUtil) add_subdirectory(ScreenPlayUtil)
add_subdirectory(CMake)
if(${SCREENPLAY_STEAM})
add_subdirectory(ScreenPlayWorkshop)
endif()
if(WIN32) if(WIN32)
add_subdirectory(ScreenPlaySysInfo) add_subdirectory(ScreenPlaySysInfo)
endif() endif()
message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") message(STATUS "[DEFINE] SOURCE_DIR = ${SOURCE_DIR}")
message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") message(STATUS "[DEFINE] BUILD_DATE = ${BUILD_DATE}")
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}")
message(STATUS "[PROJECT] QT_VERSION_MAJOR = ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} ") message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "[PROJECT] Qt6_FOUND = ${Qt6_FOUND}") message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}")
message(STATUS "[PROJECT] VCPKG_ARCH = ${VCPKG_ARCH}")
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}")
message(STATUS "[OPTION] SCREENPLAY_STEAM_DEPLOY = ${SCREENPLAY_STEAM_DEPLOY}")
message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}")
message(STATUS "[OPTION] TESTS_ENABLED = ${TESTS_ENABLED}")

29
Docs/macOSSigning.md Normal file
View File

@ -0,0 +1,29 @@
# ScreenPlay macOS signing full guide
## Create a developer account and certs
1. Pay the 99$ Apple tax
2. Create a app password for distribution outside of the app store
- Go to https://appleid.apple.com/account/manage
- Call it ScreenPlay and save the password!
3. Next we need a developer certificate:
- Go to https://developer.apple.com/account/resources/certificates/list
- Click the blue plus sign
- Select `Developer ID Application`
- _This certificate is used to code sign your app for distribution outside of the Mac App Store._
## Sign the app locally with codesign
We need to sign every single file in the .app file. For this we use the name from the installed cert. This can be copied from the `Keychain Access.app`.
`codesign --deep -f -s "Developer ID Application: Elias Steurer (AAABCXYZAA)" --options "runtime" "ScreenPlay.app/"`
## Upload to apple for notization
We use [xcnotary](https://github.com/akeru-inc/xcnotary) tools for fast automatic upload. Install it via brew:
`brew install akeru-inc/tap/xcnotary`
Then run it with the
- `*.app` name
- `-d` the developer account email and
- `-k` command is here the keychain name that contains your password from the app password step above!
`xcnotary notarize ScreenPlay.app -d yourDeveloperAccountEmail@example.com -k ScreenPlay`

View File

@ -16,9 +16,6 @@ Dev. Docs [![pipeline status](https://gitlab.com/kelteseth/ScreenPlayDeveloper
<br><br> <br><br>
User Chat (Discord) User Chat (Discord)
<a href="https://discord.com/invite/JBMmZbgc?utm_source=Discord%20Widget&utm_medium=Connect">![Discord](https://img.shields.io/discord/516635043435773970?style=for-the-badge)</a> <a href="https://discord.com/invite/JBMmZbgc?utm_source=Discord%20Widget&utm_medium=Connect">![Discord](https://img.shields.io/discord/516635043435773970?style=for-the-badge)</a>
Developer Chat [![Gitter](https://badges.gitter.im/ScreenPlayApp/community.svg)](https://gitter.im/ScreenPlayApp/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
<br> <br>
ScreenPlay is an open source cross platform app for displaying Video Wallpaper, Widgets and AppDrawer. It is written in modern C++20/Qt5/QML. Binaries with workshop support are available for Windows and soon Linux & MacOSX via <a href="https://store.steampowered.com/app/672870/ScreenPlay/">Steam</a>. Join our community: <a href="https://screen-play.app/">Homepage</a> - <a href="https://forum.screen-play.app/">Forum</a> ScreenPlay is an open source cross platform app for displaying Video Wallpaper, Widgets and AppDrawer. It is written in modern C++20/Qt5/QML. Binaries with workshop support are available for Windows and soon Linux & MacOSX via <a href="https://store.steampowered.com/app/672870/ScreenPlay/">Steam</a>. Join our community: <a href="https://screen-play.app/">Homepage</a> - <a href="https://forum.screen-play.app/">Forum</a>
@ -29,14 +26,16 @@ Windows only, Linux and MacOS next.
<br> <br>
<br> <br>
<a href="https://www.youtube.com/watch?v=q-J2fTWDxw8"> <!-- This works only on gitlab -->
![](https://gitlab.com/kelteseth/ScreenPlay/-/raw/master/.gitlab/media/preview.webp)
<!-- This works only on github -->
![](/.gitlab/media/preview.webp)
![Preview](.gitlab/media/preview.gif) <a href="https://www.youtube.com/watch?v=q-J2fTWDxw8"><p>Watch the Steam Early Access Trailer (YouTube)</p></a>
</a>
<p>Click gif to see the Steam Early Access Trailer (YouTube)</p>
</div> </div>
# Important Issues # Important Issues
* [Implement KDE Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111) * [Implement KDE Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111)
* [Implement MacOS Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130) * [Implement MacOS Support](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130)
@ -97,7 +96,7 @@ Here are some ways you can contribute:
| Feature | Windows | Linux | MacOS | | Feature | Windows | Linux | MacOS |
|------------------------ |--------- |------- |------- | |------------------------ |--------- |------- |------- |
| __ScreenPlay Main App__ | ✔ | ✔ | ✔ | | __ScreenPlay Main App__ | ✔ | ✔ | ✔ |
| __Steam Binaries__ | ✔ | ❌ | | | __Steam Binaries__ | ✔ | ❌ | |
| __Wallpaper__ | ✔ | ❓ Help Needed for Gnome/KDE/etc! | ✔ | | __Wallpaper__ | ✔ | ❓ Help Needed for Gnome/KDE/etc! | ✔ |
| __Widgets__ | ✔ | ✔ | ✔ | | __Widgets__ | ✔ | ✔ | ✔ |
| __Multilanguage (EN,DE,RU,FR,ES,KO,VI,CH_ZN,PT_BR🆕)__ | ✔ | ✔ | ✔ | | __Multilanguage (EN,DE,RU,FR,ES,KO,VI,CH_ZN,PT_BR🆕)__ | ✔ | ✔ | ✔ |

View File

@ -11,10 +11,8 @@ ScreenPlay [![pipeline status](https://gitlab.com/kelteseth/ScreenPlay/badges/ma
<a href="https://twitter.com/kelteseth">![Twitter Follow](https://img.shields.io/twitter/follow/kelteseth?style=for-the-badge)</a> <a href="https://twitter.com/kelteseth">![Twitter Follow](https://img.shields.io/twitter/follow/kelteseth?style=for-the-badge)</a>
<a href="https://www.reddit.com/r/ScreenPlayApp/">![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/screenplayapp?style=for-the-badge)</a> <a href="https://www.reddit.com/r/ScreenPlayApp/">![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/screenplayapp?style=for-the-badge)</a>
<br><br> <br><br>
用户交流 (Discord英语) 用户聊天群 (Discord英语)
<a href="https://discord.com/invite/JBMmZbgc?utm_source=Discord%20Widget&utm_medium=Connect">![Discord](https://img.shields.io/discord/516635043435773970?style=for-the-badge)</a> <a href="https://discord.com/invite/JBMmZbgc?utm_source=Discord%20Widget&utm_medium=Connect">![Discord](https://img.shields.io/discord/516635043435773970?style=for-the-badge)</a>
开发者交流(英语) [![Gitter](https://badges.gitter.im/ScreenPlayApp/community.svg)](https://gitter.im/ScreenPlayApp/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
<br> <br>
@ -22,21 +20,21 @@ ScreenPlay 是一款开源、跨平台,显示视频壁纸,部件,应用抽
带有创意工坊支持的二进制(在 Windows ,以及不久的 Linux 及 MacOSX 可用)可以通过<a href="https://store.steampowered.com/app/672870/ScreenPlay/">Steam</a>获取。加入我们(英语):<a href="https://screen-play.app/">首页</a> - <a href="https://forum.screen-play.app/">论坛</a> 带有创意工坊支持的二进制(在 Windows ,以及不久的 Linux 及 MacOSX 可用)可以通过<a href="https://store.steampowered.com/app/672870/ScreenPlay/">Steam</a>获取。加入我们(英语):<a href="https://screen-play.app/">首页</a> - <a href="https://forum.screen-play.app/">论坛</a>
<br> <br>
<h3><a href="https://store.steampowered.com/app/672870/ScreenPlay/">✨通过Steam下载ScreenPlay</a> - <a href="https://steamcommunity.com/app/672870/workshop/">Steam 创意工坊,获取壁纸与部件✨</a></h3> <h3><a href="https://store.steampowered.com/app/672870/ScreenPlay/">✨通过Steam下载ScreenPlay</a> <br><br> <a href="https://www.patreon.com/ScreenPlayApp">🚀于 Patreon 支持 ScreenPlay 🚀</a></h3>
仅支持WindowsLinux 和 MacOS 在做了 支持Windows 与 MacOS。Linux支持敬请期待
<br> <br>
<br> <br>
<!-- This works only on gitlab -->
![](https://gitlab.com/kelteseth/ScreenPlay/-/raw/master/.gitlab/media/preview.webp)
<!-- This works only on github -->
![](/.gitlab/media/preview.webp)
<a href="https://www.youtube.com/watch?v=q-J2fTWDxw8"> <a href="https://www.youtube.com/watch?v=q-J2fTWDxw8">
<p>查看提前访问预告片 (YouTube)</p>
![预览](.gitlab/media/preview.gif)
</a>
<p>点击gif查看尽早访问预告片 (YouTube)</p>
</div> </div>
# 重要议题 # 重要问题
* [对Windows显示器缩放的支持目前有问题。所有显示器必须被设为100%](https://gitlab.com/kelteseth/ScreenPlay/-/issues/125)
* [KDE 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111) * [KDE 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/111)
* [MacOS 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130) * [MacOS 支持](https://gitlab.com/kelteseth/ScreenPlay/-/issues/130)
@ -58,16 +56,16 @@ ScreenPlay 是一款开源、跨平台,显示视频壁纸,部件,应用抽
* [部件引导](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/widgets/) - 通用引导,如何创建部件。 * [部件引导](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/widgets/) - 通用引导,如何创建部件。
ScreenPlay使用易于学习的 QML 语言。无需任何编程知识! ScreenPlay使用易于学习的 QML 语言。无需任何编程知识!
* [Storage Widget](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_Storage/). Display your drives and usage. * [存储部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_Storage/) 显示您的设备及使用情况
* [CPU 占用部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_CPU/) 显示您当前的CPU使用情况 * [CPU 占用部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_CPU/) 显示您当前的CPU使用情况
* [RSS订阅部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_RSS/) 以RSS部件显示新闻 * [RSS订阅部件](https://kelteseth.gitlab.io/ScreenPlayDocs/widgets/example_RSS/) 用RSS部件显示新闻
# 一般贡献 # 一般贡献
每个人都可以贡献代码,设计,文档以及翻译。更多信息见[贡献引导](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute)。也请查阅 [Collaboration Guidelines](Docs/CodeOfConduct.md). 每个人都可以贡献代码,设计,文档以及翻译。更多信息见[贡献引导](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute)。也请查阅 [Collaboration Guidelines](Docs/CodeOfConduct.md).
这里是一些贡献的方式: 这里是一些贡献的方式:
* 通过使用预发布版本/ master分支或者Steam每夜构建。 * 通过使用预发布版本/ master分支或者Steam每夜构建。
* 通过 [添加/修复翻译](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/translations/) * 通过 [添加/修复翻译](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/translations/)
* by [设计 UI/UX](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute/#design) * by [设计 UI/UX](https://kelteseth.gitlab.io/ScreenPlayDocs/contribute/contribute/#design)
@ -88,17 +86,17 @@ ScreenPlay使用易于学习的 QML 语言。无需任何编程知识!
* [ScreenPlay project overview](Docs/ProjectOverview.md) * [ScreenPlay project overview](Docs/ProjectOverview.md)
* [Developer C++ Classes Documentation](https://kelteseth.gitlab.io/ScreenPlayDeveloperDocs/) * [Developer C++ Classes Documentation](https://kelteseth.gitlab.io/ScreenPlayDeveloperDocs/)
# Platform support # 平台支持
* ❌ Not working/Not implemented * ❌ 不工作 / 尚未实现
* ❓ Only partially implemented/Not tested, help needed * ❓ 部分实现 / 尚未测试,需要帮助
<div align="center"> <div align="center">
| 功能 | Windows | Linux | MacOS | | 功能 | Windows | Linux | MacOS |
|------------------------ |--------- |------- |------- | |------------------------ |--------- |------- |------- |
| __ScreenPlay 主程序__ | ✔ | ✔ | ✔ | | __ScreenPlay 主程序__ | ✔ | ✔ | ✔ |
| __Steam 二进制__ | ✔ | ❌ | | | __Steam 二进制__ | ✔ | ❌ | |
| __壁纸__ | ✔ | ❓ 需要帮助 Gnome/KDE 等! | ✔ | | __壁纸__ | ✔ | ❓ 需要帮助 Gnome/KDE 等! | ✔ |
| __部件__ | ✔ | ✔ | ✔ | | __部件__ | ✔ | ✔ | ✔ |
| __多语言 (EN,DE,RU,FR,ES,KO,VI,ZH_CN,PT_BR🆕)__ | ✔ | ✔ | ✔ | | __多语言 (EN,DE,RU,FR,ES,KO,VI,ZH_CN,PT_BR🆕)__ | ✔ | ✔ | ✔ |
@ -106,9 +104,9 @@ ScreenPlay使用易于学习的 QML 语言。无需任何编程知识!
</div> </div>
因为每个操作系统有它自己的桌面环境,我们需要分别适配 ScreenPlayWindow 到各个平台。 因为每个操作系统有它自己的桌面环境,我们需要分别适配 ScreenPlayWindow 到各个平台。
目前功能最完好的是Windows 10。Windows 7下也可用但有[错误的coordinates](https://gitlab.com/kelteseth/ScreenPlay/issues/34). MacOS has some basic wallpaper functionality but no maintainer. For Linux we sadly have no support for any desktop environments at the moment, except basic KDE support. 目前功能最完好的是Windows 10。Windows 7下也可用但有[错误的coordinates](https://gitlab.com/kelteseth/ScreenPlay/issues/34)。MacOS 有了一定的基本壁纸功能但是没有人维护。对于linux很抱歉我们尚未支持任何桌面环境除了 KDE 的基本支持。
__If you want to help and add new desktop environments look at ScreenPlayWallpaper/src folder__ __如果您想要帮助我们,添加新的桌面环境,请于 ScreenPlayWallpaper/src 文件夹查看__
* [BaseWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/basewindow.h) baseclass for: * [BaseWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/basewindow.h) baseclass for:
* [LinuxWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/linuxwindow.h) * [LinuxWindow](https://gitlab.com/kelteseth/ScreenPlay/blob/dev/ScreenPlayWallpaper/src/linuxwindow.h)
@ -119,7 +117,7 @@ __If you want to help and add new desktop environments look at ScreenPlayWallpap
| 平台 | Windows 10 | Gnome | KDE | MacOS | | 平台 | Windows 10 | Gnome | KDE | MacOS |
|------------------------ |------- |--------- |------- | ------- | |------------------------ |------- |--------- |------- | ------- |
| __壁纸__ | ✔ |❌ Help Needed! | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/tree/master/ScreenPlayWallpaper/kde/ScreenPlay) | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/blob/master/ScreenPlayWallpaper/src/MacBridge.mm) | | __壁纸__ | ✔ |❌ 需要帮助! | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/tree/master/ScreenPlayWallpaper/kde/ScreenPlay) | ❓ [基本实现](https://gitlab.com/kelteseth/ScreenPlay/-/blob/master/ScreenPlayWallpaper/src/MacBridge.mm) |
</div> </div>

View File

@ -14,7 +14,6 @@ find_package(CURL CONFIG REQUIRED)
find_package(sentry CONFIG REQUIRED) find_package(sentry CONFIG REQUIRED)
set(src set(src
main.cpp
app.cpp app.cpp
src/globalvariables.cpp src/globalvariables.cpp
src/createimportvideo.cpp src/createimportvideo.cpp
@ -36,6 +35,7 @@ set(headers
app.h app.h
src/globalvariables.h src/globalvariables.h
src/createimportvideo.h src/createimportvideo.h
src/createimportstates.h
src/installedlistmodel.h src/installedlistmodel.h
src/monitorlistmodel.h src/monitorlistmodel.h
src/screenplaywallpaper.h src/screenplaywallpaper.h
@ -51,97 +51,75 @@ set(headers
src/create.h src/create.h
src/wizards.h) src/wizards.h)
set(l10n list(
translations/ScreenPlay_de.ts APPEND
translations/ScreenPlay_zh_cn.ts L10N_LIST
translations/ScreenPlay_pt_br.ts # cmake-format: sortable
translations/ScreenPlay_en.ts ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_de.ts
translations/ScreenPlay_es.ts ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_zh_cn.ts
translations/ScreenPlay_fr.ts ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_pt_br.ts
translations/ScreenPlay_ko.ts ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_en.ts
translations/ScreenPlay_ru.ts ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_es.ts
translations/ScreenPlay_vi.ts) ${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_fr.ts
${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_ko.ts
${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_ru.ts
${CMAKE_CURRENT_SOURCE_DIR}/translations/ScreenPlay_vi.ts)
set_source_files_properties(${l10n} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/translations") include(QtUpdateTranslations)
qt_update_translations("${CMAKE_CURRENT_SOURCE_DIR}/qml" "${L10N_LIST}")
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) # Needed on macos
find_package( find_package(Threads REQUIRED)
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
WebEngineCore
WebEngineQuick
WebChannel
Positioning
LinguistTools)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") find_package(
qt_add_resources(qml qml.qrc assets.qrc) Qt6
else() COMPONENTS Core
qtquick_compiler_add_resources(qml qml.qrc assets.qrc) Quick
endif() Gui
Widgets
WebSockets
Svg
LinguistTools
WebEngineQuick
WebEngineCore
Test)
add_executable(${PROJECT_NAME} ${src} ${headers} ${resources} ${qml} ${fonts}) if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
qt_add_resources(resources ScreenPlayAssets.qrc ScreenPlayQML.qrc)
target_link_libraries(
${PROJECT_NAME}
PRIVATE ScreenPlaySDK
ScreenPlayUtil
benchmark::benchmark
benchmark::benchmark_main
doctest::doctest
sentry::sentry
Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt6::WebEngineCore
Qt6::WebEngineQuick)
qt_add_translation(qmFiles ${l10n})
else() else()
find_package( qtquick_compiler_add_resources(resources ScreenPlayAssets.qrc ScreenPlayQML.qrc)
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
LinguistTools
WebEngine)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
qt_add_resources(qml qml.qrc assets.qrc)
else()
qtquick_compiler_add_resources(qml qml.qrc assets.qrc)
endif()
add_executable(${PROJECT_NAME} ${src} ${headers} ${resources} ${qml} ${fonts})
target_link_libraries(
${PROJECT_NAME}
PRIVATE ScreenPlaySDK
ScreenPlayUtil
benchmark::benchmark
benchmark::benchmark_main
doctest::doctest
sentry::sentry
Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt5::WebEngine)
qt5_add_translation(qmFiles ${l10n})
endif() endif()
add_library(ScreenPlayLib ${src} ${headers} ${resources} ${resources} ${fonts})
target_include_directories(ScreenPlayLib PUBLIC ./ src/)
target_link_libraries(
ScreenPlayLib
PUBLIC ScreenPlaySDK
ScreenPlayUtil
benchmark::benchmark
benchmark::benchmark_main
doctest::doctest
sentry::sentry
Threads::Threads
Qt6::Quick
Qt6::Gui
Qt6::Widgets
Qt6::Core
Qt6::WebSockets
Qt6::Svg
Qt6::WebEngineQuick
Qt6::WebEngineCore)
add_executable(tst_ScreenPlay tests/tst_main.cpp)
target_link_libraries(tst_ScreenPlay PRIVATE ScreenPlayLib Qt6::Test)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlayLib)
qt_add_translation(qmFiles ${l10n})
qt_add_big_resources(fonts fonts.qrc) qt_add_big_resources(fonts fonts.qrc)
target_compile_definitions(${PROJECT_NAME} PRIVATE "GIT_VERSION=${GIT_VERSION}") target_compile_definitions(${PROJECT_NAME} PRIVATE "GIT_VERSION=${GIT_VERSION}")
@ -193,6 +171,19 @@ if(APPLE)
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../Common/ffmpeg/ffprobe COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../Common/ffmpeg/ffprobe
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/) ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/)
# tst_ScreenPlay needs ffmpeg in the base path
if(${TESTS_ENABLED})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../Common/ffmpeg/ffmpeg ${CMAKE_BINARY_DIR}/bin/)
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../Common/ffmpeg/ffprobe ${CMAKE_BINARY_DIR}/bin/)
endif()
add_custom_command( add_custom_command(
TARGET ${PROJECT_NAME} TARGET ${PROJECT_NAME}
POST_BUILD POST_BUILD

View File

@ -13,11 +13,13 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>${PRODUCT_NAME}</string> <string>ScreenPlay</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>0.14</string>
<key>CFBundleShortVersionString</key>
<string>0.14</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>ScreenPlay</string> <string>ScreenPlay</string>
</dict> </dict>

View File

@ -130,5 +130,6 @@
<file>assets/icons/brand_reddit.svg</file> <file>assets/icons/brand_reddit.svg</file>
<file>assets/icons/steam_default_avatar.png</file> <file>assets/icons/steam_default_avatar.png</file>
<file>assets/macos/app.screenplay.plist</file> <file>assets/macos/app.screenplay.plist</file>
<file>assets/icons/item_banner_new.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -58,7 +58,7 @@ App::App()
QGuiApplication::setOrganizationName("ScreenPlay"); QGuiApplication::setOrganizationName("ScreenPlay");
QGuiApplication::setOrganizationDomain("screen-play.app"); QGuiApplication::setOrganizationDomain("screen-play.app");
QGuiApplication::setApplicationName("ScreenPlay"); QGuiApplication::setApplicationName("ScreenPlay");
QGuiApplication::setApplicationVersion("0.13.3"); QGuiApplication::setApplicationVersion("0.14.0");
QGuiApplication::setQuitOnLastWindowClosed(false); QGuiApplication::setQuitOnLastWindowClosed(false);
QFontDatabase::addApplicationFont(":/assets/fonts/LibreBaskerville-Italic.ttf"); QFontDatabase::addApplicationFont(":/assets/fonts/LibreBaskerville-Italic.ttf");
@ -173,6 +173,8 @@ void App::init()
} }
m_create = make_unique<Create>(m_globalVariables); m_create = make_unique<Create>(m_globalVariables);
QObject::connect(m_create.get(), &Create::finished, m_installedListModel.get(), &InstalledListModel::reset);
m_wizards = make_unique<Wizards>(m_globalVariables); m_wizards = make_unique<Wizards>(m_globalVariables);
// When the installed storage path changed // When the installed storage path changed
@ -195,6 +197,11 @@ void App::init()
} }
qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "ScreenPlay", this); qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "ScreenPlay", this);
#ifdef Q_OS_MACOS
// Needed for macos .app files
m_mainWindowEngine->addPluginPath(QGuiApplication::instance()->applicationDirPath());
#endif
m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/main.qml"))); m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/main.qml")));
// Must be called last to display a error message on startup by the qml engine // Must be called last to display a error message on startup by the qml engine

View File

@ -47,12 +47,7 @@
#include <QUrl> #include <QUrl>
#include <QtGlobal> #include <QtGlobal>
#include <QtQml> #include <QtQml>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QtWebEngine>
#else
#include <QtWebEngineCore> #include <QtWebEngineCore>
#endif
#include <QtSvg> #include <QtSvg>
#include "src/create.h" #include "src/create.h"

View File

@ -1 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 22 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path id="display" d="M0,0l0,13.701l21.922,0l0,-13.701l-21.922,0Zm20.552,12.331l-19.182,0l0,-10.961l19.182,0l0,10.961Zm-6.166,2.74l-6.85,0l-0.685,2.741l-1.371,1.37l10.961,0l-1.37,-1.37l-0.685,-2.741Z" style="fill:#626262;fill-rule:nonzero;"/></svg> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 28 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="Artboard1" transform="matrix(1.27726,0,0,1.25117,0,0)">
<rect x="0" y="0" width="21.922" height="19.182" style="fill:none;"/>
<g id="display" transform="matrix(0.914274,0,0,1,0,0)">
<path d="M0,0L0,15.099L23.977,15.099L23.977,0L0,0ZM22.607,13.729L1.37,13.729L1.37,1.37L22.607,1.37L22.607,13.729ZM14.103,15.005L9.875,15.005L9.453,17.812L8.607,19.182L15.371,19.182L14.525,17.812L14.103,15.005Z" style="fill:rgb(98,98,98);fill-rule:nonzero;"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 952 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 320 180" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.319516,0.319516,-0.498372,0.498372,302.434,-166.795)">
<path d="M350.406,189.405L226.597,189.405L189.603,213.123L387.4,213.123L350.406,189.405Z" style="fill:rgb(255,152,0);"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

After

Width:  |  Height:  |  Size: 18 MiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@ -51,10 +51,9 @@
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_INIT_RESOURCE(ScreenPlayQML);
QtWebEngine::initialize(); Q_INIT_RESOURCE(ScreenPlayAssets);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication qtGuiApp(argc, argv); QApplication qtGuiApp(argc, argv);

View File

@ -34,11 +34,17 @@ ApplicationWindow {
function switchPage(name) { function switchPage(name) {
if (nav.currentNavigationName === name) { if (nav.currentNavigationName === name) {
if (name === "Installed") if (name === "Installed")
ScreenPlay.installedListModel.reset(); ScreenPlay.installedListModel.reset()
}
if (name === "Installed") {
stackView.replace("qrc:/qml/" + name + "/" + name + ".qml", {
"sidebar": sidebar
})
return return
} }
stackView.replace("qrc:/qml/" + name + "/" + name + ".qml"); stackView.replace("qrc:/qml/" + name + "/" + name + ".qml")
sidebar.state = "inactive"; sidebar.state = "inactive"
} }
color: Material.theme === Material.Dark ? Qt.darker(Material.background) : Material.background color: Material.theme === Material.Dark ? Qt.darker(Material.background) : Material.background
@ -105,7 +111,7 @@ ApplicationWindow {
StackView { StackView {
id: stackView id: stackView
objectName: "stackView"
property int duration: 300 property int duration: 300
anchors { anchors {
@ -172,6 +178,7 @@ ApplicationWindow {
Installed.Sidebar { Installed.Sidebar {
id: sidebar id: sidebar
objectName: "installedSidebar"
navHeight: nav.height navHeight: nav.height

View File

@ -141,8 +141,8 @@ Item {
title: qsTr("Please choose a file") title: qsTr("Please choose a file")
onAccepted: { onAccepted: {
root.file = fileDialog.file; root.file = fileDialog.fileUrl;
txtName.text = fileDialog.file.toString(); txtName.text = fileDialog.fileUrl.toString();
} }
} }

View File

@ -1,7 +1,7 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12 import QtQuick.Controls.Material 2.12
import Qt.labs.platform 1.1 import QtQuick.Dialogs 1.2
import ScreenPlay 1.0 import ScreenPlay 1.0
/*! /*!
@ -193,11 +193,10 @@ Item {
id: fileDialog id: fileDialog
title: "Please choose a file" title: "Please choose a file"
fileMode: FileDialog.OpenFile
nameFilters: ["Images (*.png *.jpg)"] nameFilters: ["Images (*.png *.jpg)"]
onAccepted: { onAccepted: {
imageSource = fileDialog.file; imageSource = fileDialog.fileUrl;
txtName.text = fileDialog.file.toString().replace(/^.*[\\\/]/, ''); txtName.text = fileDialog.fileUrl.toString().replace(/^.*[\\\/]/, '');
} }
} }

View File

@ -11,6 +11,7 @@ import ScreenPlay.QMLUtilities 1.0
Rectangle { Rectangle {
id: root id: root
objectName: "createSidebar"
property bool expanded: false property bool expanded: false
property alias listView: listView property alias listView: listView
@ -24,6 +25,8 @@ Rectangle {
color: Material.background color: Material.background
ListView { ListView {
/* /*
ListElement { ListElement {
headline: qsTr("QML Particle Wallpaper") headline: qsTr("QML Particle Wallpaper")
@ -85,8 +88,8 @@ Rectangle {
category: "Example Widget" category: "Example Widget"
} }
*/ */
id: listView id: listView
objectName: "wizardsListView"
anchors.fill: parent anchors.fill: parent
anchors.margins: 20 anchors.margins: 20
@ -97,15 +100,15 @@ Rectangle {
id: loaderConnections id: loaderConnections
function onWizardStarted() { function onWizardStarted() {
root.expanded = false; root.expanded = false
} }
function onWizardExited() { function onWizardExited() {
root.expanded = true; root.expanded = true
stackView.clear(StackView.PushTransition); stackView.clear(StackView.PushTransition)
stackView.push("qrc:/qml/Create/StartInfo.qml"); stackView.push("qrc:/qml/Create/StartInfo.qml")
listView.currentIndex = 0; listView.currentIndex = 0
ScreenPlay.util.setNavigationActive(true); ScreenPlay.util.setNavigationActive(true)
} }
ignoreUnknownSignals: true ignoreUnknownSignals: true
@ -116,56 +119,64 @@ Rectangle {
headline: qsTr("Tools Overview") headline: qsTr("Tools Overview")
source: "qrc:/qml/Create/StartInfo.qml" source: "qrc:/qml/Create/StartInfo.qml"
category: "Home" category: "Home"
objectName: ""
} }
ListElement { ListElement {
headline: "Video import and convert (all types)" headline: qsTr("Video import and convert (all types)")
source: "qrc:/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml" source: "qrc:/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml"
category: "Video Wallpaper" category: "Video Wallpaper"
objectName: "videoImportConvert"
} }
ListElement { ListElement {
headline: qsTr("Video Import (.webm)") headline: qsTr("Video Import (.webm)")
source: "qrc:/qml/Create/Wizards/ImportWebm/ImportWebm.qml" source: "qrc:/qml/Create/Wizards/ImportWebm/ImportWebm.qml"
category: "Video Wallpaper" category: "Video Wallpaper"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("GIF Wallpaper") headline: qsTr("GIF Wallpaper")
source: "qrc:/qml/Create/Wizards/GifWallpaper.qml" source: "qrc:/qml/Create/Wizards/GifWallpaper.qml"
category: "Video Wallpaper" category: "Video Wallpaper"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("QML Wallpaper") headline: qsTr("QML Wallpaper")
source: "qrc:/qml/Create/Wizards/QMLWallpaper.qml" source: "qrc:/qml/Create/Wizards/QMLWallpaper.qml"
category: "Code Wallpaper" category: "Code Wallpaper"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("HTML5 Wallpaper") headline: qsTr("HTML5 Wallpaper")
source: "qrc:/qml/Create/Wizards/HTMLWallpaper.qml" source: "qrc:/qml/Create/Wizards/HTMLWallpaper.qml"
category: "Code Wallpaper" category: "Code Wallpaper"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("Website Wallpaper") headline: qsTr("Website Wallpaper")
source: "qrc:/qml/Create/Wizards/WebsiteWallpaper.qml" source: "qrc:/qml/Create/Wizards/WebsiteWallpaper.qml"
category: "Code Wallpaper" category: "Code Wallpaper"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("QML Widget") headline: qsTr("QML Widget")
source: "qrc:/qml/Create/Wizards/QMLWidget.qml" source: "qrc:/qml/Create/Wizards/QMLWidget.qml"
category: "Code Widgets" category: "Code Widgets"
objectName: ""
} }
ListElement { ListElement {
headline: qsTr("HTML Widget") headline: qsTr("HTML Widget")
source: "qrc:/qml/Create/Wizards/HTMLWidget.qml" source: "qrc:/qml/Create/Wizards/HTMLWidget.qml"
category: "Code Widgets" category: "Code Widgets"
objectName: ""
} }
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
@ -186,25 +197,22 @@ Rectangle {
left: parent.left left: parent.left
bottomMargin: 10 bottomMargin: 10
} }
} }
} }
delegate: Button { delegate: Button {
id: listItem id: listItem
objectName: model.objectName
width: listView.width - 40 width: listView.width - 40
height: 45 height: 45
highlighted: ListView.isCurrentItem highlighted: ListView.isCurrentItem
text: headline text: headline
onClicked: { onClicked: {
listView.currentIndex = index; listView.currentIndex = index
const item = stackView.push(source); const item = stackView.push(source)
loaderConnections.target = item; loaderConnections.target = item
} }
} }
} }
layer.effect: ElevationEffect { layer.effect: ElevationEffect {
@ -220,7 +228,6 @@ Rectangle {
anchors.leftMargin: 0 anchors.leftMargin: 0
opacity: 1 opacity: 1
} }
}, },
State { State {
name: "inactive" name: "inactive"
@ -230,7 +237,6 @@ Rectangle {
opacity: 0 opacity: 0
anchors.leftMargin: -root.width anchors.leftMargin: -root.width
} }
} }
] ]
transitions: [ transitions: [
@ -249,9 +255,7 @@ Rectangle {
duration: 300 duration: 300
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
} }
] ]
} }

View File

@ -21,12 +21,14 @@ Item {
clip: true clip: true
CreateWallpaperInit { CreateWallpaperInit {
onNext: { onNext: startConvert(filePath,codec);
function startConvert(filePath,codec){
root.wizardStarted(); root.wizardStarted();
swipeView.currentIndex = 1; swipeView.currentIndex = 1;
createWallpaperVideoImportConvert.codec = codec; createWallpaperVideoImportConvert.codec = codec;
createWallpaperVideoImportConvert.filePath = filePath; createWallpaperVideoImportConvert.filePath = filePath;
ScreenPlay.create.createWallpaperStart(filePath, codec, quality); ScreenPlay.create.createWallpaperStart(filePath, codec, quality);
} }
} }

View File

@ -10,6 +10,7 @@ import "../../../Common" as Common
Item { Item {
id: root id: root
objectName: "createWallpaperInit"
property int quality: sliderQuality.slider.value property int quality: sliderQuality.slider.value
@ -127,6 +128,7 @@ Item {
} }
Button { Button {
objectName: "createWallpaperInitFileSelectButton"
text: qsTr("Select file") text: qsTr("Select file")
highlighted: true highlighted: true
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font

View File

@ -5,6 +5,7 @@ import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import ScreenPlay 1.0 import ScreenPlay 1.0
import ScreenPlay.Create 1.0 import ScreenPlay.Create 1.0
import ScreenPlay.Enums.ImportVideoState 1.0
import "../../../Common" as Common import "../../../Common" as Common
Item { Item {
@ -15,86 +16,88 @@ Item {
property var codec: Create.VP8 property var codec: Create.VP8
property string filePath property string filePath
signal abort() signal abort
signal save() signal save
function cleanup() { function cleanup() {
ScreenPlay.create.abortAndCleanup(); ScreenPlay.create.cancel()
} }
function basename(str) { function basename(str) {
let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1)); let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1))
let filename = filenameWithExtentions.split('.').slice(0, -1).join('.'); let filename = filenameWithExtentions.split('.').slice(0, -1).join('.')
return filename; return filename
} }
function checkCanSave() { function checkCanSave() {
if (canSave && conversionFinishedSuccessful) if (canSave && conversionFinishedSuccessful)
btnSave.enabled = true; btnSave.enabled = true
else else
btnSave.enabled = false; btnSave.enabled = false
} }
onCanSaveChanged: root.checkCanSave() onCanSaveChanged: root.checkCanSave()
onFilePathChanged: { onFilePathChanged: {
textFieldName.text = basename(filePath); textFieldName.text = basename(filePath)
} }
Connections { Connections {
function onCreateWallpaperStateChanged(state) { function onCreateWallpaperStateChanged(state) {
switch (state) { switch (state) {
case CreateImportVideo.ConvertingPreviewImage: case ImportVideoState.ConvertingPreviewImage:
txtConvert.text = qsTr("Generating preview image..."); txtConvert.text = qsTr("Generating preview image...")
break; break
case CreateImportVideo.ConvertingPreviewThumbnailImage: case ImportVideoState.ConvertingPreviewThumbnailImage:
txtConvert.text = qsTr("Generating preview thumbnail image..."); txtConvert.text = qsTr("Generating preview thumbnail image...")
break; break
case CreateImportVideo.ConvertingPreviewImageFinished: case ImportVideoState.ConvertingPreviewImageFinished:
imgPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.jpg"; imgPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.jpg"
imgPreview.visible = true; imgPreview.visible = true
break; break
case CreateImportVideo.ConvertingPreviewVideo: case ImportVideoState.ConvertingPreviewVideo:
txtConvert.text = qsTr("Generating 5 second preview video..."); txtConvert.text = qsTr("Generating 5 second preview video...")
break; break
case CreateImportVideo.ConvertingPreviewGif: case ImportVideoState.ConvertingPreviewGif:
txtConvert.text = qsTr("Generating preview gif..."); txtConvert.text = qsTr("Generating preview gif...")
break; break
case CreateImportVideo.ConvertingPreviewGifFinished: case ImportVideoState.ConvertingPreviewGifFinished:
gifPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.gif"; gifPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.gif"
imgPreview.visible = false; imgPreview.visible = false
gifPreview.visible = true; gifPreview.visible = true
gifPreview.playing = true; gifPreview.playing = true
break; break
case CreateImportVideo.ConvertingAudio: case ImportVideoState.ConvertingAudio:
txtConvert.text = qsTr("Converting Audio..."); txtConvert.text = qsTr("Converting Audio...")
break; break
case CreateImportVideo.ConvertingVideo: case ImportVideoState.ConvertingVideo:
txtConvert.text = qsTr("Converting Video... This can take some time!"); txtConvert.text = qsTr(
break; "Converting Video... This can take some time!")
case CreateImportVideo.ConvertingVideoError: break
txtConvert.text = qsTr("Converting Video ERROR!"); case ImportVideoState.ConvertingVideoError:
break; txtConvert.text = qsTr("Converting Video ERROR!")
case CreateImportVideo.AnalyseVideoError: break
txtConvert.text = qsTr("Analyse Video ERROR!"); case ImportVideoState.AnalyseVideoError:
break; txtConvert.text = qsTr("Analyse Video ERROR!")
case CreateImportVideo.Finished: break
txtConvert.text = ""; case ImportVideoState.Finished:
conversionFinishedSuccessful = true; txtConvert.text = ""
busyIndicator.running = false; conversionFinishedSuccessful = true
root.checkCanSave(); busyIndicator.running = false
break; btnExit.enabled = false;
root.checkCanSave()
break
} }
} }
function onProgressChanged(progress) { function onProgressChanged(progress) {
var percentage = Math.floor(progress * 100); var percentage = Math.floor(progress * 100)
if (percentage > 100 || progress > 0.95) if (percentage > 100 || progress > 0.95)
percentage = 100; percentage = 100
if (percentage === NaN) if (percentage === NaN)
print(progress, percentage); print(progress, percentage)
txtConvertNumber.text = percentage + "%"; txtConvertNumber.text = percentage + "%"
} }
target: ScreenPlay.create target: ScreenPlay.create
@ -116,7 +119,6 @@ Item {
margins: 40 margins: 40
bottomMargin: 0 bottomMargin: 0
} }
} }
Item { Item {
@ -186,9 +188,7 @@ Item {
position: 1 position: 1
color: "#00000000" color: "#00000000"
} }
} }
} }
BusyIndicator { BusyIndicator {
@ -211,7 +211,6 @@ Item {
bottom: parent.bottom bottom: parent.bottom
bottomMargin: 40 bottomMargin: 40
} }
} }
Text { Text {
@ -227,9 +226,7 @@ Item {
bottom: parent.bottom bottom: parent.bottom
bottomMargin: 20 bottomMargin: 20
} }
} }
} }
Common.ImageSelector { Common.ImageSelector {
@ -243,9 +240,7 @@ Item {
left: parent.left left: parent.left
bottom: parent.bottom bottom: parent.bottom
} }
} }
} }
Item { Item {
@ -283,9 +278,9 @@ Item {
Layout.fillWidth: true Layout.fillWidth: true
onTextChanged: { onTextChanged: {
if (textFieldName.text.length >= 3) if (textFieldName.text.length >= 3)
canSave = true; canSave = true
else else
canSave = false; canSave = false
} }
} }
@ -311,7 +306,6 @@ Item {
width: parent.width width: parent.width
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
Row { Row {
@ -336,14 +330,14 @@ Item {
Material.foreground: "white" Material.foreground: "white"
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font
onClicked: { onClicked: {
root.abort(); root.abort()
ScreenPlay.create.abortAndCleanup(); ScreenPlay.create.cancel()
} }
} }
Button { Button {
id: btnSave id: btnSave
objectName: "btnSave"
text: qsTr("Save") text: qsTr("Save")
enabled: false enabled: false
Material.background: Material.accent Material.background: Material.accent
@ -351,16 +345,18 @@ Item {
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font
onClicked: { onClicked: {
if (conversionFinishedSuccessful) { if (conversionFinishedSuccessful) {
btnSave.enabled = false; btnSave.enabled = false
ScreenPlay.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, codec, textFieldTags.getTags()); ScreenPlay.create.saveWallpaper(
savePopup.open(); textFieldName.text,
ScreenPlay.installedListModel.reset(); textFieldDescription.text, root.filePath,
previewSelector.imageSource,
textFieldYoutubeURL.text, codec,
textFieldTags.getTags())
savePopup.open()
} }
} }
} }
} }
} }
Popup { Popup {
@ -392,12 +388,10 @@ Item {
interval: 1000 + Math.random() * 1000 interval: 1000 + Math.random() * 1000
onTriggered: { onTriggered: {
savePopup.close(); savePopup.close()
ScreenPlay.util.setNavigationActive(true); ScreenPlay.util.setNavigationActive(true)
ScreenPlay.util.setNavigation("Installed"); ScreenPlay.util.setNavigation("Installed")
} }
} }
} }
} }

View File

@ -26,7 +26,7 @@ Item {
swipeView.currentIndex = 1; swipeView.currentIndex = 1;
createWallpaperVideoImportConvert.filePath = filePath; createWallpaperVideoImportConvert.filePath = filePath;
ScreenPlay.util.setNavigationActive(false); ScreenPlay.util.setNavigationActive(false);
ScreenPlay.create.createWallpaperStart(filePath, Create.VP9); ScreenPlay.create.createWallpaperStart(filePath);
} }
} }

View File

@ -5,6 +5,7 @@ import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import ScreenPlay 1.0 import ScreenPlay 1.0
import ScreenPlay.Create 1.0 import ScreenPlay.Create 1.0
import ScreenPlay.Enums.ImportVideoState 1.0
import "../../../Common" as Common import "../../../Common" as Common
Item { Item {
@ -38,47 +39,48 @@ Item {
Connections { Connections {
function onCreateWallpaperStateChanged(state) { function onCreateWallpaperStateChanged(state) {
switch (state) { switch (state) {
case CreateImportVideo.AnalyseVideo: case ImportVideoState.AnalyseVideo:
txtConvert.text = qsTr("AnalyseVideo..."); txtConvert.text = qsTr("AnalyseVideo...");
break; break;
case CreateImportVideo.ConvertingPreviewImage: case ImportVideoState.ConvertingPreviewImage:
txtConvert.text = qsTr("Generating preview image..."); txtConvert.text = qsTr("Generating preview image...");
break; break;
case CreateImportVideo.ConvertingPreviewThumbnailImage: case ImportVideoState.ConvertingPreviewThumbnailImage:
txtConvert.text = qsTr("Generating preview thumbnail image..."); txtConvert.text = qsTr("Generating preview thumbnail image...");
break; break;
case CreateImportVideo.ConvertingPreviewImageFinished: case ImportVideoState.ConvertingPreviewImageFinished:
imgPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.jpg"; imgPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.jpg";
imgPreview.visible = true; imgPreview.visible = true;
break; break;
case CreateImportVideo.ConvertingPreviewVideo: case ImportVideoState.ConvertingPreviewVideo:
txtConvert.text = qsTr("Generating 5 second preview video..."); txtConvert.text = qsTr("Generating 5 second preview video...");
break; break;
case CreateImportVideo.ConvertingPreviewGif: case ImportVideoState.ConvertingPreviewGif:
txtConvert.text = qsTr("Generating preview gif..."); txtConvert.text = qsTr("Generating preview gif...");
break; break;
case CreateImportVideo.ConvertingPreviewGifFinished: case ImportVideoState.ConvertingPreviewGifFinished:
gifPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.gif"; gifPreview.source = "file:///" + ScreenPlay.create.workingDir + "/preview.gif";
imgPreview.visible = false; imgPreview.visible = false;
gifPreview.visible = true; gifPreview.visible = true;
gifPreview.playing = true; gifPreview.playing = true;
break; break;
case CreateImportVideo.ConvertingAudio: case ImportVideoState.ConvertingAudio:
txtConvert.text = qsTr("Converting Audio..."); txtConvert.text = qsTr("Converting Audio...");
break; break;
case CreateImportVideo.ConvertingVideo: case ImportVideoState.ConvertingVideo:
txtConvert.text = qsTr("Converting Video... This can take some time!"); txtConvert.text = qsTr("Converting Video... This can take some time!");
break; break;
case CreateImportVideo.ConvertingVideoError: case ImportVideoState.ConvertingVideoError:
txtConvert.text = qsTr("Converting Video ERROR!"); txtConvert.text = qsTr("Converting Video ERROR!");
break; break;
case CreateImportVideo.AnalyseVideoError: case ImportVideoState.AnalyseVideoError:
txtConvert.text = qsTr("Analyse Video ERROR!"); txtConvert.text = qsTr("Analyse Video ERROR!");
break; break;
case CreateImportVideo.Finished: case ImportVideoState.Finished:
txtConvert.text = ""; txtConvert.text = "";
conversionFinishedSuccessful = true; conversionFinishedSuccessful = true;
busyIndicator.running = false; busyIndicator.running = false;
btnExit.enabled = false;
root.checkCanSave(); root.checkCanSave();
break; break;
} }
@ -330,13 +332,13 @@ Item {
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font
onClicked: { onClicked: {
root.exit(); root.exit();
ScreenPlay.create.abortAndCleanup(); ScreenPlay.create.cancel();
} }
} }
Button { Button {
id: btnSave id: btnSave
objectName: "btnSave"
text: qsTr("Save") text: qsTr("Save")
enabled: false enabled: false
Material.background: Material.accent Material.background: Material.accent
@ -347,7 +349,6 @@ Item {
btnSave.enabled = false; btnSave.enabled = false;
ScreenPlay.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Create.VP9, textFieldTags.getTags()); ScreenPlay.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Create.VP9, textFieldTags.getTags());
savePopup.open(); savePopup.open();
ScreenPlay.installedListModel.reset();
} }
} }
} }

View File

@ -65,7 +65,7 @@ FocusScope {
Button { Button {
id: btnSave id: btnSave
objectName: "btnSave"
text: qsTr("Save") text: qsTr("Save")
enabled: root.ready enabled: root.ready
Material.background: Material.accent Material.background: Material.accent

View File

@ -13,6 +13,7 @@ Item {
property bool refresh: false property bool refresh: false
property bool enabled: true property bool enabled: true
property Sidebar sidebar
signal setNavigationItem(var pos) signal setNavigationItem(var pos)
signal setSidebarActive(var active) signal setSidebarActive(var active)
@ -85,6 +86,7 @@ Item {
GridView { GridView {
id: gridView id: gridView
objectName: "gridView"
property bool isDragging: false property bool isDragging: false
property bool isScrolling: gridView.verticalVelocity != 0 property bool isScrolling: gridView.verticalVelocity != 0
@ -101,6 +103,36 @@ Item {
onDragStarted: isDragging = true onDragStarted: isDragging = true
onDragEnded: isDragging = false onDragEnded: isDragging = false
model: ScreenPlay.installedListFilter model: ScreenPlay.installedListFilter
removeDisplaced: Transition {
SequentialAnimation {
PauseAnimation {
duration: 150
}
NumberAnimation {
properties: "x,y"
duration: 250
easing.type: Easing.InOutQuart
}
}
}
remove: Transition {
SequentialAnimation {
NumberAnimation {
property: "opacity"
to: 0
duration: 200
easing.type: Easing.InOutQuart
}
NumberAnimation {
properties: "y"
to: 100
duration: 200
easing.type: Easing.InOutQuart
}
}
}
onContentYChanged: { onContentYChanged: {
if (contentY <= -180) if (contentY <= -180)
gridView.headerItem.isVisible = true; gridView.headerItem.isVisible = true;
@ -202,10 +234,11 @@ Item {
delegate: ScreenPlayItem { delegate: ScreenPlayItem {
id: delegate id: delegate
objectName: "installedItem" + index
focus: true focus: true
customTitle: m_title customTitle: m_title
type: m_type type: m_type
isNew: m_isNew
screenId: m_folderId screenId: m_folderId
absoluteStoragePath: m_absoluteStoragePath absoluteStoragePath: m_absoluteStoragePath
publishedFileID: m_publishedFileID publishedFileID: m_publishedFileID
@ -215,7 +248,6 @@ Item {
// Set the menu to the current item informations // Set the menu to the current item informations
contextMenu.publishedFileID = delegate.publishedFileID; contextMenu.publishedFileID = delegate.publishedFileID;
contextMenu.absoluteStoragePath = delegate.absoluteStoragePath; contextMenu.absoluteStoragePath = delegate.absoluteStoragePath;
deleteDialog.currentItemIndex = itemIndex;
const pos = delegate.mapToItem(root, position.x, position.y); const pos = delegate.mapToItem(root, position.x, position.y);
// Disable duplicate opening. The can happen if we // Disable duplicate opening. The can happen if we
// call popup when we are in the closing animtion. // call popup when we are in the closing animtion.
@ -234,51 +266,54 @@ Item {
Menu { Menu {
id: contextMenu id: contextMenu
objectName: "installedItemContextMenu"
property var publishedFileID: 0 property var publishedFileID: 0
property url absoluteStoragePath property url absoluteStoragePath
MenuItem { MenuItem {
text: qsTr("Open containing folder") text: qsTr("Open containing folder")
objectName: "openFolder"
icon.source: "qrc:/assets/icons/icon_folder_open.svg" icon.source: "qrc:/assets/icons/icon_folder_open.svg"
onClicked: { onClicked: {
ScreenPlay.util.openFolderInExplorer(contextMenu.absoluteStoragePath); ScreenPlay.util.openFolderInExplorer(
contextMenu.absoluteStoragePath)
} }
} }
MenuItem { MenuItem {
text: qsTr("Deinstall Item") text: enabled ? qsTr("Remove Item") : qsTr("Remove via Workshop")
objectName: enabled ? "removeItem" : "removeWorkshopItem"
icon.source: "qrc:/assets/icons/icon_delete.svg" icon.source: "qrc:/assets/icons/icon_delete.svg"
enabled: contextMenu.publishedFileID === 0 enabled: contextMenu.publishedFileID === 0
onClicked: { onClicked: {
deleteDialog.open(); deleteDialog.open()
} }
} }
MenuItem { MenuItem {
id: miWorkshop text: qsTr("Open Workshop Page")
text: qsTr("Open workshop Page")
enabled: contextMenu.publishedFileID !== 0 enabled: contextMenu.publishedFileID !== 0
icon.source: "qrc:/assets/icons/icon_steam.svg" icon.source: "qrc:/assets/icons/icon_steam.svg"
onClicked: { onClicked: {
Qt.openUrlExternally("steam://url/CommunityFilePage/" + publishedFileID); Qt.openUrlExternally(
"steam://url/CommunityFilePage/" + contextMenu.publishedFileID)
} }
} }
} }
Dialog { Dialog {
id: deleteDialog id: deleteDialog
property int currentItemIndex: 0
title: qsTr("Are you sure you want to delete this item?") title: qsTr("Are you sure you want to delete this item?")
standardButtons: Dialog.Ok | Dialog.Cancel standardButtons: Dialog.Ok | Dialog.Cancel
modal: true modal: true
dim: true dim: true
anchors.centerIn: Overlay.overlay anchors.centerIn: Overlay.overlay
onAccepted: ScreenPlay.installedListModel.deinstallItemAt(currentItemIndex) onAccepted: {
root.sidebar.clear()
ScreenPlay.installedListModel.deinstallItemAt(
contextMenu.absoluteStoragePath)
}
} }
Navigation { Navigation {
@ -289,7 +324,5 @@ Item {
right: parent.right right: parent.right
left: parent.left left: parent.left
} }
} }
} }

View File

@ -17,6 +17,7 @@ Item {
property var publishedFileID: 0 property var publishedFileID: 0
property int itemIndex property int itemIndex
property bool isScrolling: false property bool isScrolling: false
property bool isNew: false
signal openContextMenu(point position) signal openContextMenu(point position)
@ -24,16 +25,16 @@ Item {
height: 180 height: 180
onTypeChanged: { onTypeChanged: {
if (JSUtil.isWidget(type)) { if (JSUtil.isWidget(type)) {
icnType.source = "qrc:/assets/icons/icon_widgets.svg"; icnType.source = "qrc:/assets/icons/icon_widgets.svg"
return ; return
} }
if (JSUtil.isScene(type)) { if (JSUtil.isScene(type)) {
icnType.source = "qrc:/assets/icons/icon_code.svg"; icnType.source = "qrc:/assets/icons/icon_code.svg"
return ; return
} }
if (JSUtil.isVideo(type)) { if (JSUtil.isVideo(type)) {
icnType.source = "qrc:/assets/icons/icon_movie.svg"; icnType.source = "qrc:/assets/icons/icon_movie.svg"
return ; return
} }
} }
@ -41,11 +42,11 @@ Item {
running: true running: true
onTriggered: showAnim.start() onTriggered: showAnim.start()
interval: { interval: {
var itemIndexMax = itemIndex; var itemIndexMax = itemIndex
if (itemIndex > 30) if (itemIndex > 30)
itemIndexMax = 3; itemIndexMax = 3
5 * itemIndexMax * Math.random(); 5 * itemIndexMax * Math.random()
} }
} }
@ -78,7 +79,6 @@ Item {
duration: 200 duration: 200
easing.type: Easing.OutCirc easing.type: Easing.OutCirc
} }
} }
OpacityAnimator { OpacityAnimator {
@ -88,7 +88,6 @@ Item {
duration: 800 duration: 800
easing.type: Easing.OutCirc easing.type: Easing.OutCirc
} }
} }
RectangularGlow { RectangularGlow {
@ -107,7 +106,6 @@ Item {
top: parent.top top: parent.top
topMargin: 3 topMargin: 3
} }
} }
Item { Item {
@ -174,22 +172,37 @@ Item {
left: parent.left left: parent.left
margins: 10 margins: 10
} }
} }
Rectangle { Rectangle {
color: "#AAffffff"
height: 30
visible: false
anchors { width: 120
right: parent.right height: 20
left: parent.left anchors{
bottom: parent.bottom top:parent.top
right:parent.right
rightMargin: -60
topMargin: -20
} }
color: Material.color(Material.Orange)
transform: Rotation {
angle: 45
}
visible: root.isNew
Text {
font.family: ScreenPlay.settings.font
font.pointSize: 9
renderType: Text.QtRendering
color: "white"
text: qsTr("NEW")
smooth: true
antialiasing: true
visible: root.isNew
anchors.centerIn: parent
}
} }
} }
OpacityMask { OpacityMask {
@ -203,25 +216,23 @@ Item {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: { onEntered: {
root.state = "hover"; root.state = "hover"
screenPlayItemImage.state = "hover"; screenPlayItemImage.state = "hover"
screenPlayItemImage.enter(); screenPlayItemImage.enter()
} }
onExited: { onExited: {
root.state = ""; root.state = ""
screenPlayItemImage.state = "loaded"; screenPlayItemImage.state = "loaded"
screenPlayItemImage.exit(); screenPlayItemImage.exit()
} }
onClicked: (mouse)=> { onClicked: (mouse)=> {
if (mouse.button === Qt.LeftButton) if (mouse.button === Qt.LeftButton)
ScreenPlay.util.setSidebarItem(root.screenId, root.type); ScreenPlay.util.setSidebarItem(root.screenId, root.type)
else if (mouse.button === Qt.RightButton) else if (mouse.button === Qt.RightButton)
root.openContextMenu(Qt.point(mouseX, mouseY)); root.openContextMenu(Qt.point(mouseX, mouseY))
} }
} }
} }
} }
transitions: [ transitions: [
@ -256,7 +267,6 @@ Item {
from: 0.6 from: 0.6
to: 1 to: 1
} }
}, },
Transition { Transition {
from: "hover" from: "hover"
@ -289,7 +299,6 @@ Item {
from: 1 from: 1
to: 0.5 to: 0.5
} }
} }
] ]
} }

View File

@ -28,6 +28,14 @@ Item {
return -1; return -1;
} }
// This is used for removing wallpaper. We need to clear
// the preview image/gif so we can release the file for deletion.
function clear(){
image.source = ""
txtHeadline.text = ""
root.state = "inactive"
}
width: 400 width: 400
state: "inactive" state: "inactive"
onContentFolderNameChanged: { onContentFolderNameChanged: {
@ -47,8 +55,10 @@ Item {
btnSetWallpaper.enabled = false; btnSetWallpaper.enabled = false;
} }
Connections { Connections {
function onSetSidebarItem(folderName, type) { function onSetSidebarItem(folderName, type) {
// Toggle sidebar if clicked on the same content twice // Toggle sidebar if clicked on the same content twice
if (root.contentFolderName === folderName && root.state !== "inactive") { if (root.contentFolderName === folderName && root.state !== "inactive") {
root.state = "inactive"; root.state = "inactive";
@ -151,10 +161,12 @@ Item {
AnimatedImage { AnimatedImage {
id: image id: image
// Do NOT enable async image loading!
// Otherwhise it will still hold the file
// when calling InstalledListModel::deinstallItemAt
asynchronous: false
playing: true playing: true
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
asynchronous: true
anchors.fill: parent anchors.fill: parent
onStatusChanged: { onStatusChanged: {
if (image.status === Image.Error) if (image.status === Image.Error)
@ -262,6 +274,7 @@ Item {
MonitorSelection { MonitorSelection {
id: monitorSelection id: monitorSelection
objectName: "monitorSelection"
height: 180 height: 180
Layout.fillWidth: true Layout.fillWidth: true
@ -346,6 +359,7 @@ Item {
Button { Button {
id: btnSetWallpaper id: btnSetWallpaper
objectName: "btnSetWallpaper"
Material.background: Material.accent Material.background: Material.accent
Material.foreground: "white" Material.foreground: "white"

View File

@ -80,6 +80,7 @@ Rectangle {
name: "Create" name: "Create"
iconSource: "qrc:/assets/icons/icon_plus.svg" iconSource: "qrc:/assets/icons/icon_plus.svg"
onPageClicked: (name)=> {root.onPageChanged(name)} onPageClicked: (name)=> {root.onPageChanged(name)}
objectName: "createTab"
} }
NavigationItem { NavigationItem {
@ -89,6 +90,7 @@ Rectangle {
name: "Workshop" name: "Workshop"
iconSource: "qrc:/assets/icons/icon_steam.svg" iconSource: "qrc:/assets/icons/icon_steam.svg"
onPageClicked: (name)=> {root.onPageChanged(name)} onPageClicked: (name)=> {root.onPageChanged(name)}
objectName: "workshopTab"
} }
NavigationItem { NavigationItem {
@ -99,6 +101,7 @@ Rectangle {
amount: ScreenPlay.installedListModel.count amount: ScreenPlay.installedListModel.count
iconSource: "qrc:/assets/icons/icon_installed.svg" iconSource: "qrc:/assets/icons/icon_installed.svg"
onPageClicked: (name)=> {root.onPageChanged(name)} onPageClicked: (name)=> {root.onPageChanged(name)}
objectName: "installedTab"
} }
NavigationItem { NavigationItem {
@ -108,6 +111,7 @@ Rectangle {
name: "Community" name: "Community"
iconSource: "qrc:/assets/icons/icon_community.svg" iconSource: "qrc:/assets/icons/icon_community.svg"
onPageClicked: (name)=> {root.onPageChanged(name)} onPageClicked: (name)=> {root.onPageChanged(name)}
objectName: "communityTab"
} }
NavigationItem { NavigationItem {
@ -117,6 +121,7 @@ Rectangle {
name: "Settings" name: "Settings"
iconSource: "qrc:/assets/icons/icon_settings.svg" iconSource: "qrc:/assets/icons/icon_settings.svg"
onPageClicked: (name)=> {root.onPageChanged(name)} onPageClicked: (name)=> {root.onPageChanged(name)}
objectName: "settingsTab"
} }
} }

View File

@ -6,96 +6,122 @@ import ScreenPlay 1.0
import "../Common" import "../Common"
Item { Item {
id: navigationWallpaperConfiguration id: root
width: 450 width: 390
states: [] property bool active: ScreenPlay.screenPlayManager.activeWallpaperCounter > 0
transitions: []
anchors { anchors {
top: parent.top top: parent.top
right: parent.right right: parent.right
rightMargin: 20
bottom: parent.bottom bottom: parent.bottom
} }
RippleEffect {
id: rippleEffect
target: navigationWallpaperConfiguration
}
Connections { Connections {
function onActiveWallpaperCounterChanged() { function onActiveWallpaperCounterChanged() {
rippleEffect.trigger(); rippleEffect.trigger()
} }
target: ScreenPlay.screenPlayManager target: ScreenPlay.screenPlayManager
} }
Image { Pane {
id: image anchors.centerIn: parent
contentWidth: activeMonitorName.contentWidth + image.width + 80
contentHeight: parent.height - 10
background: Item {
Rectangle {
id: bg
clip: true
anchors {
fill: parent
margins: 16
}
color: "transparent"
border.color: root.active ? Material.accentColor : Material.iconDisabledColor
border.width: 1
radius: 3
}
width: 24 RippleEffect {
height: 24 id: rippleEffect
source: "qrc:/assets/icons/icon_monitor.svg"
anchors { target: bg
rightMargin: 30 }
right: parent.right }
verticalCenter: parent.verticalCenter
Behavior on contentWidth {
PropertyAnimation {
duration: 250
easing.type: Easing.InOutQuart
}
} }
Text { Text {
id: txtAmountActiveWallpapers id: activeMonitorName
text: ScreenPlay.screenPlayManager.activeWallpaperCounter + ScreenPlay.screenPlayManager.activeWidgetsCounter horizontalAlignment: Text.AlignRight
horizontalAlignment: Text.AlignHCenter color: root.active ? Material.primaryTextColor : Material.iconDisabledColor
verticalAlignment: Text.AlignVCenter font.pointSize: 12
color: Material.accent
font.pointSize: 10
font.bold: true
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font
text: root.active ? qsTr("Configurate active Wallpaper or Widgets") : qsTr(
"No active Wallpaper or Widgets")
anchors { anchors {
horizontalCenter: parent.horizontalCenter right: image.right
top: parent.top rightMargin: 50
topMargin: 1 verticalCenter: parent.verticalCenter
}
}
Image {
id: image
width: 28
height: 24
source: "qrc:/assets/icons/icon_monitor.svg"
layer {
effect: ColorOverlay {
color: root.active ? Material.color(
Material.Orange) : Material.iconDisabledColor
}
} }
anchors {
rightMargin: 30
right: parent.right
verticalCenter: parent.verticalCenter
}
Text {
id: txtAmountActiveWallpapers
text: ScreenPlay.screenPlayManager.activeWallpaperCounter
+ ScreenPlay.screenPlayManager.activeWidgetsCounter
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: root.active ? Material.color(
Material.Orange) : Material.iconDisabledColor
font.pointSize: 10
font.bold: true
font.family: ScreenPlay.settings.font
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 7
}
}
} }
} MouseArea {
id: ma
Text { anchors.fill: parent
id: activeMonitorName cursorShape: Qt.PointingHandCursor
onClicked: {
horizontalAlignment: Text.AlignRight ScreenPlay.util.setToggleWallpaperConfiguration()
color: Material.foreground }
font.pointSize: 12
font.family: ScreenPlay.settings.font
text: {
if (ScreenPlay.screenPlayManager.activeWallpaperCounter > 0)
return qsTr("Configurate active Wallpaper or Widgets");
else
return qsTr("No active Wallpaper or Widgets");
}
anchors {
right: image.right
rightMargin: 30
verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: ma
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
ScreenPlay.util.setToggleWallpaperConfiguration();
} }
} }
} }

View File

@ -15,6 +15,9 @@ Popup {
anchors.centerIn: Overlay.overlay anchors.centerIn: Overlay.overlay
dim: true dim: true
property ScreenPlayWorkshop workshop
property SteamWorkshop steam
Text { Text {
id: txtOffline id: txtOffline
@ -22,7 +25,7 @@ Popup {
font.family: ScreenPlay.settings.font font.family: ScreenPlay.settings.font
font.pointSize: 21 font.pointSize: 21
color: Material.foreground color: Material.foreground
text: qsTr("You need to run Steam for this :)") text: qsTr("You need to run Steam for this. steamErrorRestart: %1 - steamErrorAPIInit: %2").arg(steam.steamErrorRestart).arg(steam.steamErrorAPIInit)
} }
Button { Button {

View File

@ -10,12 +10,14 @@ Item {
id: root id: root
ScreenPlayWorkshop { ScreenPlayWorkshop {
id: workshop id: ws
Component.onCompleted: { Component.onCompleted: {
if (online) { const success = ws.init();
if(success){
stackView.push("qrc:/qml/Workshop/SteamWorkshop.qml", { stackView.push("qrc:/qml/Workshop/SteamWorkshop.qml", {
"workshop": workshop, "workshop": ws,
"steam": workshop.steamWorkshop "steam": ws.steamWorkshop
}) })
} else { } else {
popupOffline.open() popupOffline.open()
@ -25,6 +27,8 @@ Item {
PopupOffline { PopupOffline {
id: popupOffline id: popupOffline
workshop: ws
steam: ws.steamWorkshop
} }
StackView { StackView {
@ -37,8 +41,8 @@ Item {
ignoreUnknownSignals: true ignoreUnknownSignals: true
function onOpenSteamProfile(){ function onOpenSteamProfile(){
stackView.push("qrc:/qml/Workshop/SteamProfile.qml", { stackView.push("qrc:/qml/Workshop/SteamProfile.qml", {
"workshop": workshop, "workshop": ws,
"steam": workshop.steamWorkshop "steam": ws.steamWorkshop
}) })
} }
function onRequestWorkshopMainPage(){ function onRequestWorkshopMainPage(){

View File

@ -10,23 +10,16 @@ namespace ScreenPlay {
As for this writing (April 2019) it is solely used to import webm wallpaper As for this writing (April 2019) it is solely used to import webm wallpaper
and create the gif/web 5 second previews. and create the gif/web 5 second previews.
*/ */
/*! /*!
Constructor. Constructor.
*/ */
Create::Create(const std::shared_ptr<GlobalVariables>& globalVariables, QObject* parent) Create::Create(const std::shared_ptr<GlobalVariables>& globalVariables)
: QObject(parent) : QObject(nullptr)
, m_globalVariables(globalVariables) , m_globalVariables(globalVariables)
{ {
qRegisterMetaType<CreateImportVideo::ImportVideoState>("CreateImportVideo::ImportVideoState"); init();
qRegisterMetaType<Create::VideoCodec>("Create::VideoCodec");
qmlRegisterUncreatableType<CreateImportVideo>("ScreenPlay.Create", 1, 0, "CreateImportVideo", "Error only for enums");
qmlRegisterUncreatableType<Create>("ScreenPlay.Create", 1, 0, "VideoCodec", "Error only for enums");
qmlRegisterType<Create>("ScreenPlay.Create", 1, 0, "Create");
} }
/*! /*!
@ -35,11 +28,29 @@ Create::Create(const std::shared_ptr<GlobalVariables>& globalVariables, QObject*
Create::Create() Create::Create()
: QObject(nullptr) : QObject(nullptr)
{ {
qRegisterMetaType<CreateImportVideo::ImportVideoState>("CreateImportVideo::ImportVideoState"); init();
}
void Create::init()
{
qRegisterMetaType<Create::VideoCodec>("Create::VideoCodec"); qRegisterMetaType<Create::VideoCodec>("Create::VideoCodec");
qmlRegisterUncreatableType<ScreenPlay::CreateImportVideo>("ScreenPlay.Create", 1, 0, "CreateImportVideo", "Error only for enums");
qmlRegisterUncreatableType<Create>("ScreenPlay.Create", 1, 0, "VideoCodec", "Error only for enums"); qmlRegisterUncreatableType<Create>("ScreenPlay.Create", 1, 0, "VideoCodec", "Error only for enums");
qmlRegisterType<Create>("ScreenPlay.Create", 1, 0, "Create"); qmlRegisterType<Create>("ScreenPlay.Create", 1, 0, "Create");
qRegisterMetaType<ImportVideoState::ImportVideoState>("ImportVideoState::ImportVideoState");
qmlRegisterUncreatableMetaObject(ScreenPlay::ImportVideoState::staticMetaObject,
"ScreenPlay.Enums.ImportVideoState",
1, 0,
"ImportVideoState",
"Error: only enums");
}
void Create::reset()
{
clearFfmpegOutput();
m_interrupt = false;
setProgress(0.);
setWorkingDir({});
} }
/*! /*!
@ -47,20 +58,22 @@ Create::Create()
*/ */
void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality) void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality)
{ {
clearFfmpegOutput(); reset();
videoPath = ScreenPlayUtil::toLocal(videoPath); videoPath = ScreenPlayUtil::toLocal(videoPath);
const QDir dir(m_globalVariables->localStoragePath().toLocalFile()); const QDir installedDir = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString());
// Create a temp dir so we can later alter it to the workshop id // Create a temp dir so we can later alter it to the workshop id
const auto folderName = QString("_tmp_" + QTime::currentTime().toString()).replace(":", ""); const QDateTime date = QDateTime::currentDateTime();
const auto folderName = date.toString("ddMMyyyyhhmmss");
setWorkingDir(installedDir.path() + "/" + folderName);
if (!dir.mkdir(folderName)) { if (!installedDir.mkdir(folderName)) {
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CreateTmpFolderError); qInfo() << "Unable to create folder with name: " << folderName << " at: " << installedDir;
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CreateTmpFolderError);
emit abortCreateWallpaper(); emit abortCreateWallpaper();
return; return;
} }
setWorkingDir(dir.path() + "/" + folderName);
QString target_codec; QString target_codec;
switch (codec) { switch (codec) {
@ -75,34 +88,103 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
break; break;
} }
m_createImportVideoThread = new QThread(this); m_createImportFuture = QtConcurrent::run(QThreadPool::globalInstance(), [videoPath, target_codec, quality, this]() {
m_createImportVideo = new CreateImportVideo(videoPath, workingDir(), target_codec, quality); CreateImportVideo import(videoPath, workingDir(), target_codec, quality, m_interrupt);
connect(m_createImportVideo, &CreateImportVideo::processOutput, this, [this](QString text) { QObject::connect(&import, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged, Qt::ConnectionType::QueuedConnection);
appendFfmpegOutput(text + "\n"); QObject::connect(&import, &CreateImportVideo::abortAndCleanup, this, &Create::abortAndCleanup, Qt::ConnectionType::QueuedConnection);
QObject::connect(
&import, &CreateImportVideo::processOutput, this, [this](const QString text) {
appendFfmpegOutput(text + "\n");
},
Qt::ConnectionType::QueuedConnection);
if (!import.createWallpaperInfo() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
qInfo() << "createWallpaperImageThumbnailPreview()";
if (!import.createWallpaperImageThumbnailPreview() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
qInfo() << "createWallpaperImagePreview()";
if (!import.createWallpaperImagePreview() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
// Skip preview convert for webm
if (!import.m_isWebm) {
qInfo() << "createWallpaperVideoPreview()";
if (!import.createWallpaperVideoPreview() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
}
qInfo() << "createWallpaperGifPreview()";
if (!import.createWallpaperGifPreview() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
// If the video has no audio we can skip the extraction
if (!import.m_skipAudio) {
qInfo() << "extractWallpaperAudio()";
if (!import.extractWallpaperAudio() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
}
// Skip convert for webm
if (import.m_isWebm) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Finished);
return;
}
qInfo() << "createWallpaperVideo()";
if (!import.createWallpaperVideo() || m_interrupt) {
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Failed);
emit import.abortAndCleanup();
return;
}
emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::Finished);
}); });
connect(m_createImportVideo, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged); QObject::connect(&m_createImportFutureWatcher, &QFutureWatcherBase::finished, this, [this]() {
connect(m_createImportVideo, &CreateImportVideo::progressChanged, this, &Create::setProgress); if (m_interrupt)
connect(m_createImportVideoThread, &QThread::started, m_createImportVideo, &CreateImportVideo::process); abortAndCleanup();
connect(m_createImportVideo, &CreateImportVideo::abortAndCleanup, this, &Create::abortAndCleanup); });
connect(m_createImportVideo, &CreateImportVideo::finished, m_createImportVideoThread, &QThread::quit); m_createImportFutureWatcher.setFuture(m_createImportFuture);
connect(m_createImportVideo, &CreateImportVideo::finished, m_createImportVideo, &QObject::deleteLater);
connect(m_createImportVideoThread, &QThread::finished, m_createImportVideoThread, &QObject::deleteLater);
m_createImportVideo->moveToThread(m_createImportVideoThread);
m_createImportVideoThread->start();
} }
/*! /*!
\brief When converting of the wallpaper steps where successful. \brief When converting of the wallpaper steps where successful.
*/ */
void Create::saveWallpaper(QString title, QString description, QString filePath, QString previewImagePath, QString youtube, Create::VideoCodec codec, QVector<QString> tags) void Create::saveWallpaper(
const QString title,
const QString description,
QString filePath,
QString previewImagePath,
const QString youtube,
const Create::VideoCodec codec,
const QVector<QString> tags)
{ {
filePath = ScreenPlayUtil::toLocal(filePath); filePath = ScreenPlayUtil::toLocal(filePath);
previewImagePath = ScreenPlayUtil::toLocal(previewImagePath); previewImagePath = ScreenPlayUtil::toLocal(previewImagePath);
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CopyFiles); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CopyFiles);
// Case when the selected users preview image has the same name as // Case when the selected users preview image has the same name as
// our default "preview.jpg" name. QFile::copy does no override exsisting files // our default "preview.jpg" name. QFile::copy does no override exsisting files
@ -111,7 +193,7 @@ void Create::saveWallpaper(QString title, QString description, QString filePath,
if (userSelectedPreviewImage.fileName() == "preview.jpg") { if (userSelectedPreviewImage.fileName() == "preview.jpg") {
if (!userSelectedPreviewImage.remove()) { if (!userSelectedPreviewImage.remove()) {
qDebug() << "Could remove" << previewImagePath; qDebug() << "Could remove" << previewImagePath;
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CopyFilesError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CopyFilesError);
} }
} }
@ -119,7 +201,7 @@ void Create::saveWallpaper(QString title, QString description, QString filePath,
if (previewImageFile.exists()) { if (previewImageFile.exists()) {
if (!QFile::copy(previewImagePath, m_workingDir + "/" + previewImageFile.fileName())) { if (!QFile::copy(previewImagePath, m_workingDir + "/" + previewImageFile.fileName())) {
qDebug() << "Could not copy" << previewImagePath << " to " << m_workingDir + "/" + previewImageFile.fileName(); qDebug() << "Could not copy" << previewImagePath << " to " << m_workingDir + "/" + previewImageFile.fileName();
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CopyFilesError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CopyFilesError);
return; return;
} }
} }
@ -128,19 +210,19 @@ void Create::saveWallpaper(QString title, QString description, QString filePath,
if (filePath.endsWith(".webm")) { if (filePath.endsWith(".webm")) {
if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) { if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) {
qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName(); qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName();
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CopyFilesError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CopyFilesError);
return; return;
} }
} }
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CopyFilesFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CopyFilesFinished);
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CreateProjectFile); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CreateProjectFile);
QJsonObject obj; QJsonObject obj;
obj.insert("description", description); obj.insert("description", description);
obj.insert("title", title); obj.insert("title", title);
obj.insert("youtube", youtube); obj.insert("youtube", youtube);
obj.insert("videoCodec", codec == Create::VideoCodec::VP8 ? "vp8" : "vp9"); obj.insert("videoCodec", codec == Create::VideoCodec::VP8 ? "vp8" : "vp9");
obj.insert("file", filePathFile.fileName()); obj.insert("file", filePathFile.completeBaseName() + ".webm");
obj.insert("previewGIF", "preview.gif"); obj.insert("previewGIF", "preview.gif");
obj.insert("previewWEBM", "preview.webm"); obj.insert("previewWEBM", "preview.webm");
obj.insert("preview", previewImageFile.exists() ? previewImageFile.fileName() : "preview.jpg"); obj.insert("preview", previewImageFile.exists() ? previewImageFile.fileName() : "preview.jpg");
@ -155,11 +237,21 @@ void Create::saveWallpaper(QString title, QString description, QString filePath,
} }
if (!Util::writeSettings(std::move(obj), m_workingDir + "/project.json")) { if (!Util::writeSettings(std::move(obj), m_workingDir + "/project.json")) {
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CreateProjectFileError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CreateProjectFileError);
return; return;
} }
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::CreateProjectFileFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::CreateProjectFileFinished);
emit finished();
}
/*!
\brief This method is called from qml.
*/
void Create::cancel()
{
qInfo() << "cancel()";
m_interrupt = true;
} }
/*! /*!
@ -167,36 +259,15 @@ void Create::saveWallpaper(QString title, QString description, QString filePath,
*/ */
void Create::abortAndCleanup() void Create::abortAndCleanup()
{ {
qWarning() << "Abort and Cleanup!"; QDir exportPath(m_workingDir);
if (exportPath.exists()) {
if (m_createImportVideo == nullptr || m_createImportVideoThread == nullptr) { if (!exportPath.removeRecursively()) {
qDebug() << m_createImportVideo << m_createImportVideoThread; emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AbortCleanupError);
return; qWarning() << "Could not delete temp exportPath: " << exportPath;
}
// disconnect(m_createImportVideo);
// disconnect(m_createImportVideoThread);
// Save to export path before aborting to be able to cleanup the tmp folder
QString tmpExportPath = m_createImportVideo->m_exportPath;
connect(m_createImportVideoThread, &QThread::finished, this, [=]() {
QDir exportPath(tmpExportPath);
qWarning() << "Abort and Cleanup!" << exportPath;
if (exportPath.exists()) {
if (!exportPath.removeRecursively()) {
emit createWallpaperStateChanged(CreateImportVideo::ImportVideoState::AbortCleanupError);
qWarning() << "Could not delete temp exportPath: " << exportPath;
} else {
qDebug() << "cleanup " << tmpExportPath;
}
} else {
qDebug() << "Could not cleanup and delete: " << exportPath;
} }
m_createImportVideo = nullptr; } else {
m_createImportVideoThread = nullptr; qWarning() << "Could not cleanup video import. Export path does not exist: " << exportPath;
}); }
m_createImportVideoThread->requestInterruption();
} }
} }

View File

@ -71,9 +71,7 @@ class Create : public QObject {
Q_PROPERTY(QString ffmpegOutput READ ffmpegOutput WRITE appendFfmpegOutput NOTIFY ffmpegOutputChanged) Q_PROPERTY(QString ffmpegOutput READ ffmpegOutput WRITE appendFfmpegOutput NOTIFY ffmpegOutputChanged)
public: public:
explicit Create( explicit Create(const std::shared_ptr<GlobalVariables>& globalVariables);
const std::shared_ptr<GlobalVariables>& globalVariables,
QObject* parent = nullptr);
Create(); Create();
@ -85,32 +83,31 @@ public:
Q_ENUM(VideoCodec) Q_ENUM(VideoCodec)
float progress() const { return m_progress; } float progress() const { return m_progress; }
QString workingDir() const { return m_workingDir; } QString workingDir() const { return m_workingDir; }
QString ffmpegOutput() const { return m_ffmpegOutput; } QString ffmpegOutput() const { return m_ffmpegOutput; }
signals: signals:
void createWallpaperStateChanged(CreateImportVideo::ImportVideoState state); void createWallpaperStateChanged(ImportVideoState::ImportVideoState state);
void progressChanged(float progress); void progressChanged(float progress);
void abortCreateWallpaper(); void abortCreateWallpaper();
void workingDirChanged(QString workingDir); void workingDirChanged(QString workingDir);
void ffmpegOutputChanged(QString ffmpegOutput); void ffmpegOutputChanged(QString ffmpegOutput);
void widgetCreatedSuccessful(QString path); void widgetCreatedSuccessful(QString path);
void htmlWallpaperCreatedSuccessful(QString path); void htmlWallpaperCreatedSuccessful(QString path);
void finished();
public slots: public slots:
void cancel();
void createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality = 50); void createWallpaperStart(QString videoPath, Create::VideoCodec codec = Create::VideoCodec::VP9, const int quality = 50);
void saveWallpaper( void saveWallpaper(const QString title,
QString title, const QString description,
QString description,
QString filePath, QString filePath,
QString previewImagePath, QString previewImagePath,
QString youtube, const QString youtube,
ScreenPlay::Create::VideoCodec codec, const ScreenPlay::Create::VideoCodec codec,
QVector<QString> tags); const QVector<QString> tags);
void abortAndCleanup(); void abortAndCleanup();
@ -145,13 +142,18 @@ public slots:
} }
private: private:
CreateImportVideo* m_createImportVideo { nullptr }; void init();
QThread* m_createImportVideoThread { nullptr }; void reset();
private:
const std::shared_ptr<GlobalVariables> m_globalVariables; const std::shared_ptr<GlobalVariables> m_globalVariables;
float m_progress { 0.0F }; float m_progress { 0.0F };
QString m_workingDir; QString m_workingDir;
QString m_ffmpegOutput; QString m_ffmpegOutput;
std::atomic<bool> m_interrupt;
QFuture<void> m_createImportFuture;
QFutureWatcher<void> m_createImportFutureWatcher;
}; };
} }

View File

@ -0,0 +1,52 @@
#pragma once
#include <QObject>
namespace ScreenPlay {
/*!
\namespace ScreenPlay::ImportVideoState
\inmodule ScreenPlay
\brief Global enum for ImportVideoState.
*/
namespace ImportVideoState {
Q_NAMESPACE
enum class ImportVideoState {
Idle,
Started,
AnalyseVideo,
AnalyseVideoFinished,
AnalyseVideoError,
AnalyseVideoHasNoVideoStreamError,
ConvertingPreviewVideo,
ConvertingPreviewVideoFinished,
ConvertingPreviewVideoError,
ConvertingPreviewGif,
ConvertingPreviewGifFinished, //10
ConvertingPreviewGifError,
ConvertingPreviewImage,
ConvertingPreviewImageFinished,
ConvertingPreviewImageError,
ConvertingPreviewImageThumbnail,
ConvertingPreviewImageThumbnailFinished,
ConvertingPreviewImageThumbnailError,
ConvertingAudio,
ConvertingAudioFinished,
ConvertingAudioError, //20
ConvertingVideo,
ConvertingVideoFinished,
ConvertingVideoError,
CopyFiles,
CopyFilesFinished,
CopyFilesError,
CreateProjectFile,
CreateProjectFileFinished,
CreateProjectFileError,
AbortCleanupError, //30
CreateTmpFolderError,
Finished,
Failed,
};
Q_ENUM_NS(ImportVideoState)
}
}

View File

@ -17,21 +17,23 @@ namespace ScreenPlay {
/*! /*!
\brief This constructor is only needed for calling qRegisterMetaType on CreateImportVideo to register the enums. \brief This constructor is only needed for calling qRegisterMetaType on CreateImportVideo to register the enums.
\code \code
qRegisterMetaType<CreateImportVideo::ImportVideoState>("CreateImportVideo::ImportVideoState"); qRegisterMetaType<ImportVideoState::ImportVideoState>("ImportVideoState::ImportVideoState");
\endcode \endcode
*/ */
CreateImportVideo::CreateImportVideo(QObject* parent)
: QObject(parent)
{
}
/*! /*!
\brief Creates a CreateImportVideo object to be used in a different thread. A \a videoPath and a \a exportPath are \brief Creates a CreateImportVideo object to be used in a different thread. A \a videoPath and a \a exportPath are
needed for convertion. needed for convertion.
*/ */
CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& exportPath, const QString& codec, const int quality, QObject* parent) CreateImportVideo::CreateImportVideo(
: QObject(parent) const QString& videoPath,
const QString& exportPath,
const QString& codec,
const int quality,
std::atomic<bool>& interrupt)
: QObject(nullptr)
, m_quality(quality) , m_quality(quality)
, m_interrupt(interrupt)
{ {
m_videoPath = videoPath; m_videoPath = videoPath;
m_exportPath = exportPath; m_exportPath = exportPath;
@ -48,90 +50,6 @@ CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& ex
} }
} }
/*!
\brief Processes the multiple steps of creating a wallpaper.
\list 1
\li createWallpaperInfo()
\li createWallpaperImagePreview()
\li createWallpaperVideoPreview()
\li createWallpaperGifPreview()
\li createWallpaperVideo() - skiped if already a webm
\li extractWallpaperAudio() - skiped if no audio
\li emit createWallpaperStateChanged(ImportVideoState::Finished);
\endlist
*/
void CreateImportVideo::process()
{
qInfo() << "createWallpaperInfo()" << m_videoPath << m_exportPath << m_codec << m_ffmpegExecutable << m_ffprobeExecutable;
if (!createWallpaperInfo() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
qInfo() << "createWallpaperImageThumbnailPreview()";
if (!createWallpaperImageThumbnailPreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
qInfo() << "createWallpaperImagePreview()";
if (!createWallpaperImagePreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
qInfo() << "createWallpaperVideoPreview()";
if (!createWallpaperVideoPreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
qInfo() << "createWallpaperGifPreview()";
if (!createWallpaperGifPreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
// If the video has no audio we can skip the extraction
if (!m_skipAudio) {
qInfo() << "extractWallpaperAudio()";
if (!extractWallpaperAudio() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
}
if (m_isWebm) {
emit createWallpaperStateChanged(ImportVideoState::Finished);
return;
}
qInfo() << "createWallpaperVideo()";
if (!createWallpaperVideo() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
emit createWallpaperStateChanged(ImportVideoState::Finished);
}
void CreateImportVideo::processGif()
{
qInfo() << "createWallpaperImageThumbnailPreview()";
if (!createWallpaperImageThumbnailPreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
qInfo() << "createWallpaperImagePreview()";
if (!createWallpaperImagePreview() || QThread::currentThread()->isInterruptionRequested()) {
emit abortAndCleanup();
return;
}
emit createWallpaperStateChanged(ImportVideoState::Finished);
}
/*! /*!
\brief Starts ffprobe and tries to parse the resulting json. If the video \brief Starts ffprobe and tries to parse the resulting json. If the video
is a container that not contains the video length like webm or mkv is a container that not contains the video length like webm or mkv
@ -173,12 +91,12 @@ bool CreateImportVideo::createWallpaperInfo()
emit processOutput("ffprobe " + ScreenPlayUtil::toString(args)); emit processOutput("ffprobe " + ScreenPlayUtil::toString(args));
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideo); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideo);
const QString ffmpegOut = waitForFinished(args, QProcess::SeparateChannels, Executable::FFPROBE); const QString ffmpegOut = waitForFinished(args, QProcess::SeparateChannels, Executable::FFPROBE);
qInfo() << ffmpegOut; qInfo() << ffmpegOut;
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoFinished);
auto obj = ScreenPlayUtil::parseQByteArrayToQJsonObject(QByteArray::fromStdString(ffmpegOut.toStdString())); auto obj = ScreenPlayUtil::parseQByteArrayToQJsonObject(QByteArray::fromStdString(ffmpegOut.toStdString()));
@ -188,14 +106,14 @@ bool CreateImportVideo::createWallpaperInfo()
emit processOutput(ffmpegOut); emit processOutput(ffmpegOut);
emit processOutput("Error parsing FFPROBE json output"); emit processOutput("Error parsing FFPROBE json output");
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
return false; return false;
} }
if (obj->empty()) { if (obj->empty()) {
qWarning() << "Error! File could not be parsed."; qWarning() << "Error! File could not be parsed.";
emit processOutput("Error! File could not be parsed."); emit processOutput("Error! File could not be parsed.");
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
return false; return false;
} }
@ -214,7 +132,7 @@ bool CreateImportVideo::createWallpaperInfo()
bool CreateImportVideo::analyzeWebmReadFrames(const QJsonObject& obj) bool CreateImportVideo::analyzeWebmReadFrames(const QJsonObject& obj)
{ {
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideo); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideo);
// Number of frames is a string for some reason... // Number of frames is a string for some reason...
if (!obj.value("streams").isArray()) { if (!obj.value("streams").isArray()) {
@ -283,7 +201,7 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
if (!hasVideoStream) { if (!hasVideoStream) {
qDebug() << "Error! File has no video Stream!"; qDebug() << "Error! File has no video Stream!";
emit processOutput("Error! File has no video Stream!"); emit processOutput("Error! File has no video Stream!");
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoHasNoVideoStreamError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoHasNoVideoStreamError);
return false; return false;
} }
@ -299,7 +217,7 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
emit processOutput("Error parsing number of frames. Is this really a valid video File?"); emit processOutput("Error parsing number of frames. Is this really a valid video File?");
QJsonDocument tmpVideoStreamDoc(videoStream); QJsonDocument tmpVideoStreamDoc(videoStream);
emit processOutput(tmpVideoStreamDoc.toJson()); emit processOutput(tmpVideoStreamDoc.toJson());
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
return false; return false;
} }
@ -312,7 +230,7 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
if (!okParseDuration) { if (!okParseDuration) {
qDebug() << "Error parsing video length. Is this really a valid video File?"; qDebug() << "Error parsing video length. Is this really a valid video File?";
emit processOutput("Error parsing video length. Is this really a valid video File?"); emit processOutput("Error parsing video length. Is this really a valid video File?");
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
return false; return false;
} }
@ -373,7 +291,7 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
bool CreateImportVideo::createWallpaperVideoPreview() bool CreateImportVideo::createWallpaperVideoPreview()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewVideo); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewVideo);
QStringList args; QStringList args;
args.append("-y"); args.append("-y");
@ -397,13 +315,13 @@ bool CreateImportVideo::createWallpaperVideoPreview()
const QString ffmpegOut = waitForFinished(args); const QString ffmpegOut = waitForFinished(args);
const QFile previewVideo(m_exportPath + "/preview.webm"); const QFile previewVideo(m_exportPath + "/preview.webm");
if (!previewVideo.exists() || !(previewVideo.size() > 0)) { if (!previewVideo.exists() || !(previewVideo.size() > 0)) {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewVideoError);
return false; return false;
} }
emit processOutput(ffmpegOut); emit processOutput(ffmpegOut);
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewVideoFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewVideoFinished);
return true; return true;
} }
@ -425,13 +343,17 @@ bool CreateImportVideo::createWallpaperVideoPreview()
bool CreateImportVideo::createWallpaperGifPreview() bool CreateImportVideo::createWallpaperGifPreview()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewGif); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewGif);
QStringList args; QStringList args;
args.append("-y"); args.append("-y");
args.append("-stats"); args.append("-stats");
args.append("-i"); args.append("-i");
args.append(m_exportPath + "/preview.webm"); if (m_isWebm) {
args.append(m_videoPath);
} else {
args.append(m_exportPath + "/preview.webm");
}
args.append("-filter_complex"); 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("[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"); args.append(m_exportPath + "/preview.gif");
@ -442,13 +364,13 @@ bool CreateImportVideo::createWallpaperGifPreview()
if (!ffmpegOut.isEmpty()) { if (!ffmpegOut.isEmpty()) {
const QFile previewGif(m_exportPath + "/preview.gif"); const QFile previewGif(m_exportPath + "/preview.gif");
if (!previewGif.exists() || !(previewGif.size() > 0)) { if (!previewGif.exists() || !(previewGif.size() > 0)) {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewGifError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewGifError);
return false; return false;
} }
} }
emit processOutput(ffmpegOut); emit processOutput(ffmpegOut);
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewGifFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewGifFinished);
return true; return true;
} }
@ -464,7 +386,7 @@ bool CreateImportVideo::createWallpaperGifPreview()
bool CreateImportVideo::createWallpaperImageThumbnailPreview() bool CreateImportVideo::createWallpaperImageThumbnailPreview()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImageThumbnail); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImageThumbnail);
QStringList args; QStringList args;
args.clear(); args.clear();
@ -500,13 +422,13 @@ bool CreateImportVideo::createWallpaperImageThumbnailPreview()
if (!ffmpegOut.isEmpty()) { if (!ffmpegOut.isEmpty()) {
const QFile previewImg(m_exportPath + "/previewThumbnail.jpg"); const QFile previewImg(m_exportPath + "/previewThumbnail.jpg");
if (!previewImg.exists() || !(previewImg.size() > 0)) { if (!previewImg.exists() || !(previewImg.size() > 0)) {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImageThumbnailError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImageThumbnailError);
return false; return false;
} }
} }
emit processOutput(ffmpegOut); emit processOutput(ffmpegOut);
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImageThumbnailFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImageThumbnailFinished);
return true; return true;
} }
@ -517,7 +439,7 @@ bool CreateImportVideo::createWallpaperImageThumbnailPreview()
bool CreateImportVideo::createWallpaperImagePreview() bool CreateImportVideo::createWallpaperImagePreview()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImage); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImage);
QStringList args; QStringList args;
args.clear(); args.clear();
@ -544,13 +466,13 @@ bool CreateImportVideo::createWallpaperImagePreview()
if (!ffmpegOut.isEmpty()) { if (!ffmpegOut.isEmpty()) {
const QFile previewImg(m_exportPath + "/preview.jpg"); const QFile previewImg(m_exportPath + "/preview.jpg");
if (!previewImg.exists() || !(previewImg.size() > 0)) { if (!previewImg.exists() || !(previewImg.size() > 0)) {
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImageError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImageError);
return false; return false;
} }
} }
emit processOutput(ffmpegOut); emit processOutput(ffmpegOut);
emit createWallpaperStateChanged(ImportVideoState::ConvertingPreviewImageFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingPreviewImageFinished);
return true; return true;
} }
@ -576,13 +498,13 @@ bool CreateImportVideo::createWallpaperImagePreview()
*/ */
bool CreateImportVideo::createWallpaperVideo() bool CreateImportVideo::createWallpaperVideo()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingVideo); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingVideo);
connect(m_process.get(), &QProcess::readyReadStandardOutput, this, [&]() { connect(m_process.get(), &QProcess::readyReadStandardOutput, this, [&]() {
QString tmpOut = m_process->readAllStandardOutput(); QString tmpOut = m_process->readAllStandardOutput();
qInfo() << tmpOut; qInfo() << tmpOut;
if (tmpOut.contains("Conversion failed!")) { if (tmpOut.contains("Conversion failed!")) {
emit createWallpaperStateChanged(ImportVideoState::ConvertingVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingVideoError);
} }
const auto tmpList = tmpOut.split(QRegularExpression("\\s+"), Qt::SplitBehaviorFlags::SkipEmptyParts); const auto tmpList = tmpOut.split(QRegularExpression("\\s+"), Qt::SplitBehaviorFlags::SkipEmptyParts);
@ -614,7 +536,7 @@ bool CreateImportVideo::createWallpaperVideo()
if (m_codec == "av1") if (m_codec == "av1")
args.append("libaom-av1"); args.append("libaom-av1");
args.append("-b:v"); args.append("-b:v");
args.append("3000k"); args.append("13000k");
args.append("-threads"); args.append("-threads");
args.append(QString::number(QThread::idealThreadCount())); args.append(QString::number(QThread::idealThreadCount()));
qInfo() << "threads" << QThread::idealThreadCount() << "m_quality" << m_quality; qInfo() << "threads" << QThread::idealThreadCount() << "m_quality" << m_quality;
@ -657,7 +579,7 @@ bool CreateImportVideo::createWallpaperVideo()
if (m_codec == "av1") if (m_codec == "av1")
args.append("libaom-av1"); args.append("libaom-av1");
args.append("-b:v"); args.append("-b:v");
args.append("3000k"); args.append("13000k");
args.append("-threads"); args.append("-threads");
args.append(QString::number(QThread::idealThreadCount())); args.append(QString::number(QThread::idealThreadCount()));
args.append("-speed"); args.append("-speed");
@ -675,7 +597,7 @@ bool CreateImportVideo::createWallpaperVideo()
args.append("-pass"); args.append("-pass");
args.append("2"); args.append("2");
const QFileInfo file(m_videoPath); const QFileInfo file(m_videoPath);
const QString convertedFileAbsolutePath { m_exportPath + "/" + file.baseName() + ".webm" }; const QString convertedFileAbsolutePath { m_exportPath + "/" + file.completeBaseName() + ".webm" };
args.append(convertedFileAbsolutePath); args.append(convertedFileAbsolutePath);
const QString ffmpegOutput = waitForFinished(args); const QString ffmpegOutput = waitForFinished(args);
@ -683,11 +605,11 @@ bool CreateImportVideo::createWallpaperVideo()
QFile video(convertedFileAbsolutePath); QFile video(convertedFileAbsolutePath);
if (!video.exists() || !(video.size() > 0)) { if (!video.exists() || !(video.size() > 0)) {
qDebug() << convertedFileAbsolutePath << ffmpegOutput << video.exists() << video.size(); qDebug() << convertedFileAbsolutePath << ffmpegOutput << video.exists() << video.size();
emit createWallpaperStateChanged(ImportVideoState::ConvertingVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingVideoError);
return false; return false;
} }
emit createWallpaperStateChanged(ImportVideoState::ConvertingVideoFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingVideoFinished);
return true; return true;
} }
@ -710,7 +632,7 @@ bool CreateImportVideo::createWallpaperVideo()
bool CreateImportVideo::extractWallpaperAudio() bool CreateImportVideo::extractWallpaperAudio()
{ {
emit createWallpaperStateChanged(ImportVideoState::ConvertingAudio); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingAudio);
QStringList args; QStringList args;
args.append("-y"); args.append("-y");
@ -731,13 +653,13 @@ bool CreateImportVideo::extractWallpaperAudio()
if (!previewImg.exists() || !(previewImg.size() > 0)) { if (!previewImg.exists() || !(previewImg.size() > 0)) {
qDebug() << args; qDebug() << args;
qDebug() << tmpErrImg; qDebug() << tmpErrImg;
emit createWallpaperStateChanged(ImportVideoState::ConvertingAudioError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingAudioError);
return false; return false;
} }
} }
emit processOutput(tmpErrImg); emit processOutput(tmpErrImg);
emit createWallpaperStateChanged(ImportVideoState::ConvertingAudioFinished); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::ConvertingAudioFinished);
return true; return true;
} }
@ -755,12 +677,20 @@ QString CreateImportVideo::waitForFinished(
m_process = std::make_unique<QProcess>(); m_process = std::make_unique<QProcess>();
QObject::connect(m_process.get(), &QProcess::errorOccurred, [=](QProcess::ProcessError error) { QObject::connect(m_process.get(), &QProcess::errorOccurred, [=](QProcess::ProcessError error) {
qDebug() << "error enum val = " << error << m_process->errorString(); qDebug() << "error enum val = " << error << m_process->errorString();
emit createWallpaperStateChanged(ImportVideoState::AnalyseVideoError); emit createWallpaperStateChanged(ImportVideoState::ImportVideoState::AnalyseVideoError);
m_process->terminate(); m_process->terminate();
if (!m_process->waitForFinished(1000)) { if (!m_process->waitForFinished(1000)) {
m_process->kill(); m_process->kill();
} }
}); });
QObject::connect(m_process.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus) {
qInfo() << "Process finished with exit code: " << exitCode;
if (exitCode != 0)
qWarning() << "Process finished with exit code: " << exitCode << " exitStatus:" << exitStatus;
});
if (executable == Executable::FFMPEG) { if (executable == Executable::FFMPEG) {
m_process->setProgram(m_ffmpegExecutable); m_process->setProgram(m_ffmpegExecutable);
} else { } else {
@ -786,7 +716,7 @@ QString CreateImportVideo::waitForFinished(
while (!m_process->waitForFinished(10)) //Wake up every 10ms and check if we must exit while (!m_process->waitForFinished(10)) //Wake up every 10ms and check if we must exit
{ {
if (QThread::currentThread()->isInterruptionRequested()) { if (m_interrupt) {
qInfo() << "Interrupt thread"; qInfo() << "Interrupt thread";
m_process->terminate(); m_process->terminate();
if (!m_process->waitForFinished(1000)) { if (!m_process->waitForFinished(1000)) {
@ -802,7 +732,10 @@ QString CreateImportVideo::waitForFinished(
} else { } else {
processOutput = m_process->readAll(); processOutput = m_process->readAll();
} }
qInfo() << "ProcessOutput:" << processOutput;
if (!processOutput.isEmpty())
qInfo() << "ProcessOutput:" << processOutput;
m_process->close(); m_process->close();
return processOutput; return processOutput;

View File

@ -47,9 +47,9 @@
#include <QProcess> #include <QProcess>
#include <QScopeGuard> #include <QScopeGuard>
#include <QString> #include <QString>
#include <QThread>
#include <QtMath> #include <QtMath>
#include "createimportstates.h"
#include "util.h" #include "util.h"
namespace ScreenPlay { namespace ScreenPlay {
@ -59,46 +59,7 @@ class CreateImportVideo : public QObject {
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged) Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
public: public:
CreateImportVideo() { } explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, const QString& codec, const int quality, std::atomic<bool>& interrupt);
CreateImportVideo(QObject* parent = nullptr);
explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, const QString& codec, const int quality, QObject* parent = nullptr);
enum class ImportVideoState {
Idle,
Started,
AnalyseVideo,
AnalyseVideoFinished,
AnalyseVideoError,
AnalyseVideoHasNoVideoStreamError,
ConvertingPreviewVideo,
ConvertingPreviewVideoFinished,
ConvertingPreviewVideoError,
ConvertingPreviewGif,
ConvertingPreviewGifFinished, //10
ConvertingPreviewGifError,
ConvertingPreviewImage,
ConvertingPreviewImageFinished,
ConvertingPreviewImageError,
ConvertingPreviewImageThumbnail,
ConvertingPreviewImageThumbnailFinished,
ConvertingPreviewImageThumbnailError,
ConvertingAudio,
ConvertingAudioFinished,
ConvertingAudioError, //20
ConvertingVideo,
ConvertingVideoFinished,
ConvertingVideoError,
CopyFiles,
CopyFilesFinished,
CopyFilesError,
CreateProjectFile,
CreateProjectFileFinished,
CreateProjectFileError,
AbortCleanupError, //30
CreateTmpFolderError,
Finished,
};
Q_ENUM(ImportVideoState)
float progress() const { return m_progress; } float progress() const { return m_progress; }
@ -128,16 +89,13 @@ public:
}; };
signals: signals:
void createWallpaperStateChanged(CreateImportVideo::ImportVideoState state); void createWallpaperStateChanged(ImportVideoState::ImportVideoState state);
void processOutput(QString text); void processOutput(QString text);
void finished(); void finished();
void abortAndCleanup(); void abortAndCleanup();
void progressChanged(float progress); void progressChanged(float progress);
public slots: public slots:
void process();
void processGif();
bool createWallpaperInfo(); bool createWallpaperInfo();
bool createWallpaperVideoPreview(); bool createWallpaperVideoPreview();
bool createWallpaperGifPreview(); bool createWallpaperGifPreview();
@ -170,6 +128,7 @@ private:
QString m_ffprobeExecutable; QString m_ffprobeExecutable;
QString m_ffmpegExecutable; QString m_ffmpegExecutable;
std::unique_ptr<QProcess> m_process; std::unique_ptr<QProcess> m_process;
std::atomic<bool>& m_interrupt;
}; };
} }
Q_DECLARE_METATYPE(ScreenPlay::CreateImportVideo::ImportVideoState) Q_DECLARE_METATYPE(ScreenPlay::ImportVideoState::ImportVideoState)

View File

@ -1,4 +1,5 @@
#include "installedlistmodel.h" #include "installedlistmodel.h"
#include <QDebug>
namespace ScreenPlay { namespace ScreenPlay {
@ -44,27 +45,65 @@ void InstalledListModel::init()
/*! /*!
\brief Deleted the item from the local storage and removes it from the \brief Deleted the item from the local storage and removes it from the
installed list. installed list. We wait for the qml engine to free all resources before
we proceed. This like the preview.gif will be in use when clicking on an item
*/ */
bool InstalledListModel::deinstallItemAt(const int index) void InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath)
{ {
if (index < 0 || index >= m_screenPlayFiles.count()) { QTimer::singleShot(1000, this, [this, absoluteStoragePath]() {
qWarning() << "remove folder error, invalid index " << index; int index = -1;
return false; for (int i = 0; i < m_screenPlayFiles.size(); ++i) {
} if (m_screenPlayFiles.at(i).m_absoluteStoragePath.toString() == absoluteStoragePath) {
index = i;
break;
}
}
beginRemoveRows(QModelIndex(), index, index); if (index < 0 || index >= m_screenPlayFiles.count()) {
const QString path = QUrl::fromUserInput(m_screenPlayFiles.at(index).m_absoluteStoragePath.toString()).toLocalFile(); qWarning() << "Remove folder error, invalid index " << index;
return;
}
QDir dir(path); beginRemoveRows(QModelIndex(), index, index);
const bool success = dir.removeRecursively(); m_screenPlayFiles.removeAt(index);
endRemoveRows();
if (!success) const QString path = ScreenPlayUtil::toLocal(absoluteStoragePath);
qWarning() << "Could not remove folder: " << m_screenPlayFiles.at(index).m_absoluteStoragePath.toString();
m_screenPlayFiles.removeAt(index); QDir dir(path);
endRemoveRows(); bool success = true;
return success; if (!dir.exists()) {
qWarning() << "Directory does not exist!" << dir;
return;
}
// We must pause the QFileSystemWatcher to not trigger
// a reload for every removed file
m_fileSystemWatcher.blockSignals(true);
for (auto& item : dir.entryInfoList(QDir::Files)) {
if (!QFile::remove(item.absoluteFilePath())) {
qWarning() << "Unable to remove file:" << item;
success = false;
break;
}
}
if (!success) {
qWarning() << "Could not remove folder content at: " << path;
loadInstalledContent();
}
if (!dir.rmdir(path)) {
qWarning() << "Could not remove folder at: " << path;
return;
}
// Add delay to the watcher, because it was trigger by
// something when enabling after the removal.
QTimer::singleShot(3000, this, [this]() {
m_fileSystemWatcher.blockSignals(false);
});
});
} }
/*! /*!
@ -111,13 +150,15 @@ QVariant InstalledListModel::data(const QModelIndex& index, int role) const
return m_screenPlayFiles.at(row).m_publishedFileID; return m_screenPlayFiles.at(row).m_publishedFileID;
case static_cast<int>(ScreenPlayItem::Tags): case static_cast<int>(ScreenPlayItem::Tags):
return m_screenPlayFiles.at(row).m_tags; return m_screenPlayFiles.at(row).m_tags;
case static_cast<int>(ScreenPlayItem::IsNew):
return m_screenPlayFiles.at(row).m_isNew;
case static_cast<int>(ScreenPlayItem::LastModified): case static_cast<int>(ScreenPlayItem::LastModified):
return m_screenPlayFiles.at(row).m_lastModified; return m_screenPlayFiles.at(row).m_lastModified;
case static_cast<int>(ScreenPlayItem::SearchType): case static_cast<int>(ScreenPlayItem::SearchType):
return QVariant::fromValue(m_screenPlayFiles.at(row).m_searchType); return QVariant::fromValue(m_screenPlayFiles.at(row).m_searchType);
default:
return QVariant();
} }
qWarning() << "Unable to fetch value for row type:" << role;
return QVariant(); return QVariant();
} }
@ -137,26 +178,34 @@ QHash<int, QByteArray> InstalledListModel::roleNames() const
{ static_cast<int>(ScreenPlayItem::PublishedFileID), "m_publishedFileID" }, { static_cast<int>(ScreenPlayItem::PublishedFileID), "m_publishedFileID" },
{ static_cast<int>(ScreenPlayItem::Tags), "m_tags" }, { static_cast<int>(ScreenPlayItem::Tags), "m_tags" },
{ static_cast<int>(ScreenPlayItem::SearchType), "m_searchType" }, { static_cast<int>(ScreenPlayItem::SearchType), "m_searchType" },
{ static_cast<int>(ScreenPlayItem::LastModified), "m_lastModified" }, { static_cast<int>(ScreenPlayItem::IsNew), "m_isNew" },
{ static_cast<int>(ScreenPlayItem::LastModified), "m_lastModified" }
}; };
} }
/*! /*!
\brief Append an ProjectFile to the list. \brief Append an ProjectFile to the list.
*/ */
void InstalledListModel::append(const QJsonObject& obj, const QString& folderName, const QDateTime& lastModified) void InstalledListModel::append(const QJsonObject& obj, const QString& folderName, const bool isNew, const QDateTime& lastModified)
{ {
beginInsertRows(QModelIndex(), m_screenPlayFiles.size(), m_screenPlayFiles.size()); beginInsertRows(QModelIndex(), m_screenPlayFiles.size(), m_screenPlayFiles.size());
m_screenPlayFiles.append(ProjectFile(obj, folderName, m_globalVariables->localStoragePath(), lastModified)); m_screenPlayFiles.append(ProjectFile(obj, folderName, m_globalVariables->localStoragePath(), isNew, lastModified));
endInsertRows(); endInsertRows();
} }
/*! /*!
\brief Loads all installed content. Skips projects.json without a "type" field. \brief Loads all installed content.
- Skips if the loadContentFuture is already running.
- Skips projects.json without a "type" field.
*/ */
void InstalledListModel::loadInstalledContent() void InstalledListModel::loadInstalledContent()
{ {
QtConcurrent::run([this]() { if (m_loadContentFuture.isRunning()) {
qInfo() << "loadInstalledContent is already running. Skip.";
return;
}
m_loadContentFuture = QtConcurrent::run([this]() {
QFileInfoList list = QDir(m_globalVariables->localStoragePath().toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs); QFileInfoList list = QDir(m_globalVariables->localStoragePath().toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
int counter = 0; int counter = 0;
@ -166,6 +215,11 @@ void InstalledListModel::loadInstalledContent()
if (!QFile::exists(absoluteFilePath)) if (!QFile::exists(absoluteFilePath))
continue; continue;
bool isNew = false;
if (item.birthTime().date() == QDateTime::currentDateTime().date())
isNew = true;
if (auto obj = ScreenPlayUtil::openJsonFileToObject(absoluteFilePath)) { if (auto obj = ScreenPlayUtil::openJsonFileToObject(absoluteFilePath)) {
if (obj->isEmpty()) if (obj->isEmpty())
@ -176,7 +230,7 @@ void InstalledListModel::loadInstalledContent()
if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString())) { if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString())) {
if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString(), Qt::CaseInsensitive)) { if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString(), Qt::CaseInsensitive)) {
append(*obj, item.baseName(), item.lastModified()); append(*obj, item.baseName(), isNew, item.lastModified());
} }
counter += 1; counter += 1;
@ -189,26 +243,33 @@ void InstalledListModel::loadInstalledContent()
} }
/*! /*!
\brief . \brief Used for receiving values from qml. One must add all new fields
when adding new roles to this model.
*/ */
QVariantMap InstalledListModel::get(const QString& folderId) const QVariantMap InstalledListModel::get(const QString& folderName) const
{ {
if (m_screenPlayFiles.count() == 0) if (m_screenPlayFiles.count() == 0)
return {}; return {};
QVariantMap map; const QString localInstalledPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString());
for (int i = 0; i < m_screenPlayFiles.count(); i++) {
if (m_screenPlayFiles[i].m_folderId == folderId) { if (!QDir(localInstalledPath + "/" + folderName).exists()) {
map.insert("m_title", m_screenPlayFiles[i].m_title); return {};
map.insert("m_preview", m_screenPlayFiles[i].m_preview); }
map.insert("m_previewGIF", m_screenPlayFiles[i].m_previewGIF);
map.insert("m_file", m_screenPlayFiles[i].m_file); for (const auto& item : m_screenPlayFiles) {
map.insert("m_type", QVariant::fromValue(m_screenPlayFiles[i].m_type)); if (item.m_folderId == folderName) {
map.insert("m_absoluteStoragePath", m_screenPlayFiles[i].m_absoluteStoragePath); QVariantMap map;
map.insert("m_publishedFileID", m_screenPlayFiles[i].m_publishedFileID); map.insert("m_title", item.m_title);
map.insert("m_lastModified", m_screenPlayFiles[i].m_lastModified); map.insert("m_preview", item.m_preview);
map.insert("m_previewGIF", item.m_previewGIF);
map.insert("m_file", item.m_file);
map.insert("m_type", QVariant::fromValue(item.m_type));
map.insert("m_absoluteStoragePath", item.m_absoluteStoragePath);
map.insert("m_publishedFileID", item.m_publishedFileID);
map.insert("m_isNew", item.m_isNew);
map.insert("m_lastModified", item.m_lastModified);
return map; return map;
} }
} }
@ -217,7 +278,7 @@ QVariantMap InstalledListModel::get(const QString& folderId) const
} }
/*! /*!
\brief . \brief Removes all entires and loads it again.
*/ */
void InstalledListModel::reset() void InstalledListModel::reset()
{ {

View File

@ -89,6 +89,7 @@ public:
Tags, Tags,
SearchType, SearchType,
LastModified, LastModified,
IsNew,
}; };
Q_ENUM(ScreenPlayItem) Q_ENUM(ScreenPlayItem)
@ -98,13 +99,13 @@ public:
} }
public slots: public slots:
QVariantMap get(const QString& folderId) const; QVariantMap get(const QString& folderName) const;
void loadInstalledContent(); void loadInstalledContent();
void append(const QJsonObject&, const QString&, const QDateTime& lastModified); void append(const QJsonObject&, const QString&, const bool isNew, const QDateTime& lastModified);
void reset(); void reset();
void init(); void init();
bool deinstallItemAt(const int index); void deinstallItemAt(const QString& absoluteStoragePath);
void setCount(int count) void setCount(int count)
{ {
@ -123,6 +124,7 @@ private:
QFileSystemWatcher m_fileSystemWatcher; QFileSystemWatcher m_fileSystemWatcher;
QVector<ProjectFile> m_screenPlayFiles; QVector<ProjectFile> m_screenPlayFiles;
int m_count { 0 }; int m_count { 0 };
QFuture<void> m_loadContentFuture;
const std::shared_ptr<GlobalVariables>& m_globalVariables; const std::shared_ptr<GlobalVariables>& m_globalVariables;
}; };

View File

@ -90,7 +90,12 @@ void ScreenPlayManager::init(
}); });
} }
loadProfiles(); // Reset to default settings if we are unable to load
// the existing one
if (!loadProfiles()) {
qInfo() << "Reset default profiles.json at:" << m_globalVariables->localSettingsPath();
m_settings->writeJsonFileFromResource("profiles");
}
} }
/*! /*!
@ -418,10 +423,11 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID)
std::remove_if( std::remove_if(
m_screenPlayWallpapers.begin(), m_screenPlayWallpapers.begin(),
m_screenPlayWallpapers.end(), m_screenPlayWallpapers.end(),
[this, appID](auto& wallpaper) { [this, appID](std::shared_ptr<ScreenPlayWallpaper>& wallpaper) {
if (wallpaper->appID() != appID) { if (wallpaper->appID() != appID) {
return false; return false;
} }
wallpaper->messageQuit();
qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber(); qInfo() << "Remove wallpaper " << wallpaper->file() << "at monitor " << wallpaper->screenNumber();
@ -452,12 +458,14 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
std::remove_if( std::remove_if(
m_screenPlayWidgets.begin(), m_screenPlayWidgets.begin(),
m_screenPlayWidgets.end(), m_screenPlayWidgets.end(),
[this, appID](auto& widget) { [this, appID](std::shared_ptr<ScreenPlayWidget>& widget) {
if (widget->appID() != appID) { if (widget->appID() != appID) {
qInfo() << "No match " << widget->appID(); qInfo() << "No match " << widget->appID();
return false; return false;
} }
widget->messageQuit();
qInfo() << "Remove widget " << appID; qInfo() << "Remove widget " << appID;
decreaseActiveWidgetsCounter(); decreaseActiveWidgetsCounter();
@ -559,6 +567,21 @@ bool ScreenPlayManager::loadProfiles()
if (wallpaper.toObject().value("name").toString() != "default") if (wallpaper.toObject().value("name").toString() != "default")
continue; continue;
// Dry run to check if the config is outdated. This is when a wallpaper is configured
// but no longer available.
for (QJsonValueRef wallpaper : wallpaper.toObject().value("wallpaper").toArray()) {
QJsonObject wallpaperObj = wallpaper.toObject();
if (wallpaperObj.empty())
continue;
const QString absolutePath = wallpaperObj.value("absolutePath").toString();
if (!QFile(absolutePath).exists()) {
qWarning() << "Specified file does not exist! This means the profiles.json is no longer valid.";
return false;
}
}
for (QJsonValueRef wallpaper : wallpaper.toObject().value("wallpaper").toArray()) { for (QJsonValueRef wallpaper : wallpaper.toObject().value("wallpaper").toArray()) {
QJsonObject wallpaperObj = wallpaper.toObject(); QJsonObject wallpaperObj = wallpaper.toObject();

View File

@ -10,16 +10,6 @@ namespace ScreenPlay {
This class is only for managing the QProcess to an extern ScreenPlayWallpaper! This class is only for managing the QProcess to an extern ScreenPlayWallpaper!
*/ */
/*!
\brief Destructor for ScreenPlayWallpaper.
*/
ScreenPlayWallpaper::~ScreenPlayWallpaper()
{
m_connection->close();
qInfo() << "Remove wallpaper " << m_appID;
}
/*! /*!
\brief Constructor for ScreenPlayWallpaper. \brief Constructor for ScreenPlayWallpaper.
*/ */
@ -144,6 +134,15 @@ QJsonObject ScreenPlayWallpaper::getActiveSettingsJson()
return obj; return obj;
} }
/*!
\brief Sends command quit to the wallpaper.
*/
void ScreenPlayWallpaper::messageQuit()
{
QJsonObject obj;
obj.insert("command", "quit");
m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact));
}
/*! /*!
\brief Prints the exit code if != 0. \brief Prints the exit code if != 0.
*/ */

View File

@ -66,8 +66,8 @@ class ScreenPlayWallpaper : public QObject {
Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
public: public:
// Default constructor needed for qml engine
ScreenPlayWallpaper() { } ScreenPlayWallpaper() { }
~ScreenPlayWallpaper();
explicit ScreenPlayWallpaper( explicit ScreenPlayWallpaper(
const QVector<int>& screenNumber, const QVector<int>& screenNumber,
@ -127,6 +127,7 @@ signals:
void error(const QString& msg); void error(const QString& msg);
public slots: public slots:
void messageQuit();
void processExit(int exitCode, QProcess::ExitStatus exitStatus); void processExit(int exitCode, QProcess::ExitStatus exitStatus);
void processError(QProcess::ProcessError error); void processError(QProcess::ProcessError error);
bool setWallpaperValue(const QString& key, const QString& value, const bool save = false); bool setWallpaperValue(const QString& key, const QString& value, const bool save = false);

View File

@ -50,10 +50,9 @@ ScreenPlayWidget::ScreenPlayWidget(
QVariant::fromValue(m_type).toString(), QVariant::fromValue(m_type).toString(),
QString::number(m_position.x()), QString::number(m_position.x()),
QString::number(m_position.y()), QString::number(m_position.y()),
}; };
} }
bool ScreenPlayWidget::start() bool ScreenPlayWidget::start()
{ {
m_process.setArguments(m_appArgumentsList); m_process.setArguments(m_appArgumentsList);
@ -71,10 +70,14 @@ bool ScreenPlayWidget::start()
return success; return success;
} }
ScreenPlayWidget::~ScreenPlayWidget() /*!
\brief Sends command quit to the widget.
*/
void ScreenPlayWidget::messageQuit()
{ {
qInfo() << "Remove widget " << m_appID; QJsonObject obj;
m_connection->close(); obj.insert("command", "quit");
m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact));
} }
/*! /*!

View File

@ -69,7 +69,6 @@ public:
const QString& absolutePath, const QString& absolutePath,
const QString& previewImage, const QJsonObject& properties, const QString& previewImage, const QJsonObject& properties,
const InstalledType::InstalledType type); const InstalledType::InstalledType type);
~ScreenPlayWidget();
bool start(); bool start();
@ -86,6 +85,7 @@ public:
ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; } ProjectSettingsListModel* getProjectSettingsListModel() { return &m_projectSettingsListModel; }
public slots: public slots:
void messageQuit();
QJsonObject getActiveSettingsJson(); QJsonObject getActiveSettingsJson();
void setPreviewImage(QString previewImage) void setPreviewImage(QString previewImage)

View File

@ -18,7 +18,7 @@ ScreenPlay::SDKConnection::SDKConnection(QLocalSocket* socket, QObject* parent)
{ {
m_socket = socket; m_socket = socket;
connect(m_socket, &QLocalSocket::readyRead, this, &SDKConnection::readyRead); connect(m_socket, &QLocalSocket::readyRead, this, &SDKConnection::readyRead);
connect(m_socket, &QLocalSocket::errorOccurred, this, [](QLocalSocket::LocalSocketError socketError){ connect(m_socket, &QLocalSocket::errorOccurred, this, [](QLocalSocket::LocalSocketError socketError) {
qInfo() << "Localsocket error:" << socketError; qInfo() << "Localsocket error:" << socketError;
}); });
} }

View File

@ -140,16 +140,26 @@ void Settings::writeJsonFileFromResource(const QString& filename)
void Settings::setupWidgetAndWindowPaths() void Settings::setupWidgetAndWindowPaths()
{ {
QDir workingDir(QGuiApplication::applicationDirPath()); QDir workingDir(QGuiApplication::applicationDirPath());
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget" + ScreenPlayUtil::executableBinEnding())); m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget" + ScreenPlayUtil::executableBinEnding()));
m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper" + ScreenPlayUtil::executableBinEnding())); m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper" + ScreenPlayUtil::executableBinEnding()));
#endif #endif
#ifdef Q_OS_LINUX
m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget"));
m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper"));
#endif
#ifdef Q_OS_OSX #ifdef Q_OS_OSX
workingDir.cdUp(); // ScreenPlayTest is not bundled in an .app so the working directory
workingDir.cdUp(); // the the same as the executable.
workingDir.cdUp(); if (QFileInfo(QCoreApplication::applicationFilePath()).fileName() != "tst_ScreenPlay") {
workingDir.cdUp();
workingDir.cdUp();
workingDir.cdUp();
}
m_globalVariables->setWidgetExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget").toLocalFile()); m_globalVariables->setWidgetExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget").toLocalFile());
m_globalVariables->setWallpaperExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper").toLocalFile()); m_globalVariables->setWallpaperExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper").toLocalFile());
@ -157,10 +167,12 @@ void Settings::setupWidgetAndWindowPaths()
#endif #endif
if (!QFileInfo::exists(m_globalVariables->widgetExecutablePath().toString())) { if (!QFileInfo::exists(m_globalVariables->widgetExecutablePath().toString())) {
qFatal("widget executable not found!"); qInfo() << "widgetExecutablePath:" << m_globalVariables->widgetExecutablePath().toString();
qCritical("widget executable not found!");
} }
if (!QFileInfo::exists(m_globalVariables->wallpaperExecutablePath().toString())) { if (!QFileInfo::exists(m_globalVariables->wallpaperExecutablePath().toString())) {
qFatal("wallpaper executable not found!"); qInfo() << "wallpaperExecutablePath:" << m_globalVariables->wallpaperExecutablePath().toString();
qCritical("wallpaper executable not found!");
} }
} }

View File

@ -201,7 +201,7 @@ public slots:
QFile defaultPListFile(":/assets/macos/" + plistFileName); QFile defaultPListFile(":/assets/macos/" + plistFileName);
defaultPListFile.open(QIODevice::ReadOnly); defaultPListFile.open(QIODevice::ReadOnly);
QString settingsPlistContent = defaultPListFile.readAll(); QString settingsPlistContent = defaultPListFile.readAll();
if(!settingsPlistContent.contains("{{SCREENPLAY_PATH}}")){ if (!settingsPlistContent.contains("{{SCREENPLAY_PATH}}")) {
qCritical() << "Unable to load plist settings template from qrc to set autostart!"; qCritical() << "Unable to load plist settings template from qrc to set autostart!";
} }
@ -211,7 +211,7 @@ public slots:
workingDir.cdUp(); workingDir.cdUp();
const QString screenPlayPath = QUrl::fromUserInput(workingDir.path() + "/ScreenPlay.app/Contents/MacOS/ScreenPlay").toLocalFile(); const QString screenPlayPath = QUrl::fromUserInput(workingDir.path() + "/ScreenPlay.app/Contents/MacOS/ScreenPlay").toLocalFile();
settingsPlistContent.replace("{{SCREENPLAY_PATH}}", screenPlayPath); settingsPlistContent.replace("{{SCREENPLAY_PATH}}", screenPlayPath);
settingsPlistContent.replace("{{SCREENPLAY_AUTOSTART}}", autostart ? "true":"false"); settingsPlistContent.replace("{{SCREENPLAY_AUTOSTART}}", autostart ? "true" : "false");
const QString homePath = QDir::homePath(); const QString homePath = QDir::homePath();
QFile settingsPlist(homePath + "/Library/LaunchAgents/" + plistFileName); QFile settingsPlist(homePath + "/Library/LaunchAgents/" + plistFileName);

View File

@ -0,0 +1,238 @@
/****************************************************************************
**
** Copyright (C) 2020 Elias Steurer (Kelteseth)
** Contact: https://screen-play.app
**
** This file is part of ScreenPlay. ScreenPlay is licensed under a dual license in
** order to ensure its sustainability. When you contribute to ScreenPlay
** you accept that your work will be available under the two following licenses:
**
** $SCREENPLAY_BEGIN_LICENSE$
**
** #### Affero General Public License Usage (AGPLv3)
** Alternatively, this file may be used under the terms of the GNU Affero
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file "ScreenPlay License.md" included in the
** packaging of this App. Please review the following information to
** ensure the GNU Affero Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/agpl-3.0.en.html.
**
** #### Commercial License
** This code is owned by Elias Steurer. By changing/adding to the code you agree to the
** terms written in:
** * Legal/corporate_contributor_license_agreement.md - For corporate contributors
** * Legal/individual_contributor_license_agreement.md - For individual contributors
**
** #### Additional Limitations to the AGPLv3 and Commercial Lincese
** This License does not grant any rights in the trademarks,
** service marks, or logos.
**
**
** $SCREENPLAY_END_LICENSE$
**
****************************************************************************/
#include "app.h"
#include "create.h"
#include <QApplication>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QGuiApplication>
#include <QtTest>
#include <QQuickItem>
#define DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_CONFIG_SUPER_FAST_ASSERTS
#include <doctest/doctest.h>
class ScreenPlayTest : public QObject {
Q_OBJECT
private slots:
void initTestCase()
{
Q_INIT_RESOURCE(ScreenPlayQML);
Q_INIT_RESOURCE(ScreenPlayAssets);
app.init();
m_window = qobject_cast<QQuickWindow*>(app.mainWindowEngine()->rootObjects().first());
QVERIFY(m_window);
QVERIFY(QTest::qWaitForWindowExposed(m_window));
QTest::qWait(1000);
m_installedSidebar = m_window->findChild<QQuickItem*>("installedSidebar");
QVERIFY(m_installedSidebar);
QTest::qWait(1000);
}
void start_shutdown_wallpaper();
void import_convert_video();
private:
QQuickWindow* m_window = nullptr;
QQuickItem* m_installedSidebar = nullptr;
ScreenPlay::App app;
};
/*!
* For some reason a direct findChild does not work for item
* delegates.
* https://stackoverflow.com/questions/36767512/how-to-access-qml-listview-delegate-items-from-c
*
*/
QQuickItem* findItemDelegate(QQuickItem* listView, const QString objectName)
{
if (!listView->property("contentItem").isValid())
return {};
auto contentItem = listView->property("contentItem").value<QQuickItem*>();
auto contentItemChildren = contentItem->childItems();
QQuickItem* videoImportConvertButton {};
for (auto childItem : contentItemChildren) {
if (childItem->objectName() == objectName)
return childItem;
}
return {};
}
void clickItem(QQuickItem* item, Qt::MouseButton button = Qt::LeftButton)
{
QQuickWindow* itemWindow = item->window();
QVERIFY(itemWindow);
auto centre = item->mapToScene(QPoint(item->width() / 2, item->height() / 2)).toPoint();
qInfo() << "click_:" << centre;
QTest::mouseClick(itemWindow, button, Qt::NoModifier, centre);
}
void ScreenPlayTest::import_convert_video()
{
using namespace ScreenPlay;
auto* createTab = m_window->findChild<QQuickItem*>("createTab");
QVERIFY(createTab);
clickItem(createTab);
QTest::qWait(300);
auto* stackView = m_window->findChild<QQuickItem*>("stackView");
QVERIFY(stackView);
QVERIFY(stackView->property("currentItem").isValid());
auto* createView = qvariant_cast<QQuickItem*>(stackView->property("currentItem"));
QVERIFY(createView);
QTest::qWait(300);
auto* wizardsListView = m_window->findChild<QQuickItem*>("wizardsListView");
QVERIFY(wizardsListView);
QQuickItem* videoImportConvertButton = findItemDelegate(wizardsListView, "videoImportConvert");
QVERIFY(videoImportConvertButton);
clickItem(videoImportConvertButton);
QTest::qWait(300);
auto* createWallpaperInit = m_window->findChild<QQuickItem*>("createWallpaperInit");
QVERIFY(createWallpaperInit);
const QString originalVideoPath = QString(SOURCE_DIR) + "/ScreenPlay/assets/tests/video_import.mp4";
qInfo() << originalVideoPath;
QVERIFY(QMetaObject::invokeMethod(createWallpaperInit,
QString("startConvert").toLatin1().constData(),
Qt::ConnectionType::AutoConnection,
Q_ARG(QVariant, originalVideoPath),
Q_ARG(QVariant, 1))); // VideoCodec::VP9
QTest::qWait(1000);
// Wait for Create::createWallpaperStart
{
ImportVideoState::ImportVideoState status = ImportVideoState::ImportVideoState::Idle;
QObject::connect(app.create(), &Create::createWallpaperStateChanged, this, [&status](ImportVideoState::ImportVideoState state) {
status = state;
});
while (true) {
QSignalSpy videoConvertFinishSpy(app.create(), &Create::createWallpaperStateChanged);
if (status == ImportVideoState::ImportVideoState::Finished || status == ImportVideoState::ImportVideoState::Failed) {
QVERIFY(status == ImportVideoState::ImportVideoState::Finished);
QTest::qWait(1000); // Wait for the ui to process the event
break;
}
videoConvertFinishSpy.wait();
}
}
QTest::qWait(1000);
auto* btnSave = m_window->findChild<QQuickItem*>("btnSave");
QVERIFY(btnSave);
clickItem(btnSave);
// Wait for Create::saveWallpaper
{
ImportVideoState::ImportVideoState status = ImportVideoState::ImportVideoState::Idle;
QObject::connect(app.create(), &Create::createWallpaperStateChanged, this, [&status](ImportVideoState::ImportVideoState state) {
status = state;
});
while (true) {
QSignalSpy videoConvertFinishSpy(app.create(), &Create::createWallpaperStateChanged);
if (status == ImportVideoState::ImportVideoState::CreateProjectFileFinished || status == ImportVideoState::ImportVideoState::CreateProjectFileError || status == ImportVideoState::ImportVideoState::CopyFilesError) {
QVERIFY(status == ImportVideoState::ImportVideoState::CreateProjectFileFinished);
QTest::qWait(1000); // Wait for the ui to process the event
break;
}
videoConvertFinishSpy.wait();
}
}
QTest::qWait(1000);
auto* installedTab = m_window->findChild<QQuickItem*>("installedTab");
QVERIFY(installedTab);
clickItem(installedTab);
QTest::qWait(1000);
auto* gridView = m_window->findChild<QQuickItem*>("gridView");
QVERIFY(gridView);
const QString installedListItemIndex = "0";
auto* firstInstalledItem = findItemDelegate(gridView, "installedItem" + installedListItemIndex);
QVERIFY(firstInstalledItem);
clickItem(firstInstalledItem, Qt::RightButton);
QTest::qWait(1000);
auto* installedItemContextMenu = m_window->findChild<QQuickItem*>("installedItemContextMenu");
QVERIFY(installedItemContextMenu);
auto* removeItem = findItemDelegate(installedItemContextMenu, "removeItem");
QVERIFY(removeItem);
clickItem(removeItem);
}
void ScreenPlayTest::start_shutdown_wallpaper()
{
QTest::qWait(1000);
auto* stackView = m_window->findChild<QQuickItem*>("stackView");
QVERIFY(stackView);
QVERIFY(stackView->property("currentItem").isValid());
auto* installedView = qvariant_cast<QQuickItem*>(stackView->property("currentItem"));
QVERIFY(installedView);
QTest::qWait(1000);
auto* gridView = m_window->findChild<QQuickItem*>("gridView");
QVERIFY(gridView);
const QString installedListItemIndex = "0";
auto* firstInstalledItem = findItemDelegate(gridView, "installedItem" + installedListItemIndex);
QVERIFY(firstInstalledItem);
clickItem(firstInstalledItem);
auto* monitorSelection = m_installedSidebar->findChild<QQuickItem*>("monitorSelection");
QVERIFY(monitorSelection);
QTest::qWait(1000);
QVERIFY(QMetaObject::invokeMethod(monitorSelection,
QString("selectOnly").toLatin1().constData(),
Qt::ConnectionType::AutoConnection,
Q_ARG(QVariant, 0))); // First monitor
QTest::qWait(1000);
auto* btnSetWallpaper = m_installedSidebar->findChild<QQuickItem*>("btnSetWallpaper");
QVERIFY(btnSetWallpaper);
clickItem(btnSetWallpaper);
QTest::qWait(10000);
}
QTEST_MAIN(ScreenPlayTest)
#include "tst_main.moc"

View File

@ -1,7 +0,0 @@
### How-to Update Translations?
1. Open PowerShell (in this Directory)
2. Check if you have execution policy set to bypass by executing `Get-ExecutionPolicy`
+ If you have "Bypass" or "Unrestricted" then you are good.
+ If not then execute **in Administrator PowerShell** `Set-ExecutionPolicy Bypass -Scope Process` to set current PowerShell session to Bypass or `Set-ExecutionPolicy Bypass` to set All PowerShell session to Bypass.
3. Execute `./UpdateTranslations.ps1` and follow the instruction printed on the screen.

File diff suppressed because it is too large Load Diff

View File

@ -110,65 +110,37 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CreateEmptyHtmlWallpaper</name>
<message>
<source>Abort</source>
<translation type="obsolete">Cancel</translation>
</message>
</context>
<context>
<name>CreateEmptyWidget</name>
<message>
<source>Abort</source>
<translation type="obsolete">Cancel</translation>
</message>
</context>
<context>
<name>CreateImport</name>
<message>
<source>Import a Creation</source>
<translation type="vanished">Import a Creation</translation>
</message>
</context>
<context>
<name>CreateUpload</name>
<message>
<source>Upload a Creation</source>
<translation type="vanished">Upload a Creation</translation>
</message>
</context>
<context> <context>
<name>CreateWallpaperInit</name> <name>CreateWallpaperInit</name>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="31"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="32"/>
<source>Import any video type</source> <source>Import any video type</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="37"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="38"/>
<source>Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are: <source>Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are:
*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</source> *.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="52"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="53"/>
<source>Set your preffered video codec:</source> <source>Set your preffered video codec:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="97"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="98"/>
<source>Quality slider. Lower value means better quality.</source> <source>Quality slider. Lower value means better quality.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="112"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="113"/>
<source>Open Documentation</source> <source>Open Documentation</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="130"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="132"/>
<source>Select file</source> <source>Select file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -193,88 +165,88 @@
</context> </context>
<context> <context>
<name>CreateWallpaperVideoImportConvert</name> <name>CreateWallpaperVideoImportConvert</name>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="47"/>
<source>Generating preview image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="50"/>
<source>Generating preview thumbnail image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="57"/>
<source>Generating 5 second preview video...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="60"/>
<source>Generating preview gif...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="69"/>
<source>Converting Audio...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="72"/>
<source>Converting Video... This can take some time!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="75"/>
<source>Converting Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="78"/>
<source>Analyse Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="106"/>
<source>Convert a video to a wallpaper</source>
<translation type="unfinished">Convert a video to a background live wallpaper</translation>
</message>
<message> <message>
<location filename="../qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml" line="164"/> <location filename="../qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml" line="164"/>
<source></source> <source></source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="221"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="48"/>
<source>Generating preview image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="51"/>
<source>Generating preview thumbnail image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="58"/>
<source>Generating 5 second preview video...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="61"/>
<source>Generating preview gif...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="70"/>
<source>Converting Audio...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="73"/>
<source>Converting Video... This can take some time!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="77"/>
<source>Converting Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="80"/>
<source>Analyse Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="108"/>
<source>Convert a video to a wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="219"/>
<source>Generating preview video...</source> <source>Generating preview video...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="281"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="275"/>
<source>Name (required!)</source> <source>Name (required!)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="295"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="289"/>
<source>Description</source> <source>Description</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="303"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="297"/>
<source>Youtube URL</source> <source>Youtube URL</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="334"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="327"/>
<source>Abort</source> <source>Abort</source>
<translation type="unfinished">Cancel</translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="347"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="340"/>
<source>Save</source> <source>Save</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="382"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="377"/>
<source>Save Wallpaper...</source> <source>Save Wallpaper...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -327,13 +299,6 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>FFMPEGPopup</name>
<message>
<source>Abort</source>
<translation type="obsolete">Cancel</translation>
</message>
</context>
<context> <context>
<name>FileSelector</name> <name>FileSelector</name>
<message> <message>
@ -492,88 +457,88 @@
</context> </context>
<context> <context>
<name>ImportWebmConvert</name> <name>ImportWebmConvert</name>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="42"/>
<source>AnalyseVideo...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="45"/>
<source>Generating preview image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="48"/>
<source>Generating preview thumbnail image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="55"/>
<source>Generating 5 second preview video...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="58"/>
<source>Generating preview gif...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="67"/>
<source>Converting Audio...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="70"/>
<source>Converting Video... This can take some time!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="73"/>
<source>Converting Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="76"/>
<source>Analyse Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="104"/>
<source>Import a video to a wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="189"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="189"/>
<source></source> <source></source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="214"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="43"/>
<source>AnalyseVideo...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="46"/>
<source>Generating preview image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="49"/>
<source>Generating preview thumbnail image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="56"/>
<source>Generating 5 second preview video...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="59"/>
<source>Generating preview gif...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="68"/>
<source>Converting Audio...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="71"/>
<source>Converting Video... This can take some time!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="74"/>
<source>Converting Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="77"/>
<source>Analyse Video ERROR!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="105"/>
<source>Import a video to a wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="215"/>
<source>Generating preview video...</source> <source>Generating preview video...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="274"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="275"/>
<source>Name (required!)</source> <source>Name (required!)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="288"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="289"/>
<source>Description</source> <source>Description</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="296"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="297"/>
<source>Youtube URL</source> <source>Youtube URL</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="327"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="328"/>
<source>Abort</source> <source>Abort</source>
<translation type="unfinished">Cancel</translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="340"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="341"/>
<source>Save</source> <source>Save</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -619,46 +584,51 @@
<context> <context>
<name>Installed</name> <name>Installed</name>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="130"/> <location filename="../qml/Installed/Installed.qml" line="329"/>
<source></source>
<translation></translation>
</message>
<message>
<location filename="../qml/Installed/Installed.qml" line="131"/>
<source>Refreshing!</source> <source>Refreshing!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="133"/> <location filename="../qml/Installed/Installed.qml" line="134"/>
<location filename="../qml/Installed/Installed.qml" line="148"/> <location filename="../qml/Installed/Installed.qml" line="149"/>
<source>Pull to refresh!</source> <source>Pull to refresh!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="178"/> <location filename="../qml/Installed/Installed.qml" line="179"/>
<source>Get more Wallpaper &amp; Widgets via the Steam workshop!</source> <source>Get more Wallpaper &amp; Widgets via the Steam workshop!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="242"/> <location filename="../qml/Installed/Installed.qml" line="244"/>
<source>Open containing folder</source> <source>Open containing folder</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="250"/> <location filename="../qml/Installed/Installed.qml" line="252"/>
<source>Deinstall Item</source> <source>Remove Item</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Installed/Installed.qml" line="252"/>
<source>Remove via Workshop</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="261"/> <location filename="../qml/Installed/Installed.qml" line="261"/>
<source>Open workshop Page</source> <source>Open Workshop Page</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="276"/> <location filename="../qml/Installed/Installed.qml" line="277"/>
<source>Are you sure you want to delete this item?</source> <source>Are you sure you want to delete this item?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Installed/Installed.qml" line="329"/>
<source></source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>InstalledWelcomeScreen</name> <name>InstalledWelcomeScreen</name>
@ -702,13 +672,13 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Common/LicenseSelector.qml" line="78"/> <location filename="../qml/Common/LicenseSelector.qml" line="71"/>
<source>You do not share any rights and nobody is allowed to use or remix it (Not recommended). Can also used to credit work others.</source> <source>You grant other to remix your work but it must remain under the GPLv3. We recommend this license for all code wallpaper!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Common/LicenseSelector.qml" line="71"/> <location filename="../qml/Common/LicenseSelector.qml" line="78"/>
<source>You grant other to remix your work but it must remain under the GPLv3. We recommend this license for all code wallpaper!</source> <source>You do not share any rights and nobody is allowed to use or remix it (Not recommended). Can also used to credit work others.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -929,6 +899,14 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>ScreenPlayItem</name>
<message>
<location filename="../qml/Installed/ScreenPlayItem.qml" line="206"/>
<source>NEW</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>Search</name> <name>Search</name>
<message> <message>
@ -949,6 +927,11 @@
<source>Autostart</source> <source>Autostart</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="73"/>
<source>ScreenPlay will start with Windows and will setup your Desktop every time for you.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="84"/> <location filename="../qml/Settings/Settings.qml" line="84"/>
<source>High priority Autostart</source> <source>High priority Autostart</source>
@ -966,7 +949,7 @@
</message> </message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="99"/> <location filename="../qml/Settings/Settings.qml" line="99"/>
<source>Help us make ScreenPlay faster and more stable. All collected data is purely anonymous and only used for development purposes!</source> <source>Help us make ScreenPlay faster and more stable. All collected data is purely anonymous and only used for development purposes! We use &lt;a href=&quot;https://sentry.io&quot;&gt;sentry.io&lt;/a&gt; to collect and analyze this data. A &lt;b&gt;big thanks to them&lt;/b&gt; for providing us with free premium support for open source projects!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -979,6 +962,11 @@
<source>Set location</source> <source>Set location</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="116"/>
<source>Your storage path is empty!</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="139"/> <location filename="../qml/Settings/Settings.qml" line="139"/>
<source>Important: Changing this directory has no effect on the workshop download path. ScreenPlay only supports having one content folder!</source> <source>Important: Changing this directory has no effect on the workshop download path. ScreenPlay only supports having one content folder!</source>
@ -992,26 +980,6 @@
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="162"/> <location filename="../qml/Settings/Settings.qml" line="162"/>
<source>Set the ScreenPlay UI Language</source> <source>Set the ScreenPlay UI Language</source>
<translation type="unfinished">Set the ScreenPlay userinterface Language</translation>
</message>
<message>
<location filename="../qml/Settings/Settings.qml" line="176"/>
<source>Chinese - Simplified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Settings/Settings.qml" line="243"/>
<source>Performance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Settings/Settings.qml" line="73"/>
<source>ScreenPlay will start with Windows and will setup your Desktop every time for you.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Settings/Settings.qml" line="116"/>
<source>Your storage path is empty!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -1024,6 +992,11 @@
<source>German</source> <source>German</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="176"/>
<source>Chinese - Simplified</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="179"/> <location filename="../qml/Settings/Settings.qml" line="179"/>
<source>Russian</source> <source>Russian</source>
@ -1079,6 +1052,11 @@
<source>Light</source> <source>Light</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="243"/>
<source>Performance</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="262"/> <location filename="../qml/Settings/Settings.qml" line="262"/>
<source>Pause wallpaper video rendering while another app is in the foreground</source> <source>Pause wallpaper video rendering while another app is in the foreground</source>
@ -1210,6 +1188,56 @@
</context> </context>
<context> <context>
<name>Sidebar</name> <name>Sidebar</name>
<message>
<location filename="../qml/Create/Sidebar.qml" line="118"/>
<source>Tools Overview</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="124"/>
<source>Video import and convert (all types)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="131"/>
<source>Video Import (.webm)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="137"/>
<source>GIF Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="143"/>
<source>QML Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="149"/>
<source>HTML5 Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="155"/>
<source>Website Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="161"/>
<source>QML Widget</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="167"/>
<source>HTML Widget</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Installed/Sidebar.qml" line="65"/>
<source>Set Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="68"/> <location filename="../qml/Installed/Sidebar.qml" line="68"/>
<source>Set Widget</source> <source>Set Widget</source>
@ -1226,55 +1254,50 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="287"/> <location filename="../qml/Installed/Sidebar.qml" line="288"/>
<source>Set Volume</source> <source>Set Volume</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="306"/> <location filename="../qml/Installed/Sidebar.qml" line="307"/>
<source>Fill Mode</source> <source>Fill Mode</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="325"/> <location filename="../qml/Installed/Sidebar.qml" line="326"/>
<source>Stretch</source> <source>Stretch</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="328"/> <location filename="../qml/Installed/Sidebar.qml" line="329"/>
<source>Fill</source> <source>Fill</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="331"/> <location filename="../qml/Installed/Sidebar.qml" line="332"/>
<source>Contain</source> <source>Contain</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="334"/> <location filename="../qml/Installed/Sidebar.qml" line="335"/>
<source>Cover</source> <source>Cover</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="337"/> <location filename="../qml/Installed/Sidebar.qml" line="338"/>
<source>Scale-Down</source> <source>Scale-Down</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Installed/Sidebar.qml" line="65"/>
<source>Set Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Sidebar.qml" line="81"/>
<source> MB</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Workshop/Sidebar.qml" line="81"/> <location filename="../qml/Workshop/Sidebar.qml" line="81"/>
<source>Size: </source> <source>Size: </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Workshop/Sidebar.qml" line="81"/>
<source> MB</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../qml/Workshop/Sidebar.qml" line="87"/> <location filename="../qml/Workshop/Sidebar.qml" line="87"/>
<source>No description...</source> <source>No description...</source>
@ -1310,46 +1333,6 @@
<source>Subscribe</source> <source>Subscribe</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="116"/>
<source>Tools Overview</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="128"/>
<source>Video Import (.webm)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="134"/>
<source>GIF Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="140"/>
<source>QML Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="146"/>
<source>HTML5 Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="152"/>
<source>Website Wallpaper</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="158"/>
<source>QML Widget</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="164"/>
<source>HTML Widget</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StartInfo</name> <name>StartInfo</name>
@ -1372,6 +1355,123 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>SteamProfile</name>
<message>
<location filename="../qml/Workshop/SteamProfile.qml" line="78"/>
<location filename="../qml/Workshop/SteamProfile.qml" line="138"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamProfile.qml" line="160"/>
<source>Forward</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SteamWorkshop</name>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="151"/>
<source>Loading</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="163"/>
<source>Download now!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="168"/>
<source>Downloading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="176"/>
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="202"/>
<source>Open In Steam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="286"/>
<source>Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="305"/>
<source>Search for Wallpaper and Widgets...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="349"/>
<source>Open Workshop in Steam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="373"/>
<source>Ranked By Vote</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="376"/>
<source>Publication Date</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="379"/>
<source>Ranked By Trend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="382"/>
<source>Favorited By Friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="385"/>
<source>Created By Friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="388"/>
<source>Created By Followed Users</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="391"/>
<source>Not Yet Rated</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="394"/>
<source>Total VotesAsc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="397"/>
<source>Votes Up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="400"/>
<source>Total Unique Subscriptions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="449"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="473"/>
<source>Forward</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>TagSelector</name> <name>TagSelector</name>
<message> <message>
@ -1458,7 +1558,7 @@
<message> <message>
<location filename="../qml/Workshop/upload/UploadProject.qml" line="142"/> <location filename="../qml/Workshop/upload/UploadProject.qml" line="142"/>
<source>Abort</source> <source>Abort</source>
<translation type="unfinished">Cancel</translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/Workshop/upload/UploadProject.qml" line="157"/> <location filename="../qml/Workshop/upload/UploadProject.qml" line="157"/>
@ -2123,109 +2223,6 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>Workshop</name>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="171"/>
<source>Loading</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="183"/>
<source>Download now!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="188"/>
<source>Downloading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="196"/>
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="222"/>
<source>Open In Steam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="281"/>
<source>Search for Wallpaper and Widgets...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="347"/>
<source>Open Workshop in Steam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="359"/>
<source>Open GameHub in Steam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="383"/>
<source>Ranked By Vote</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="386"/>
<source>Publication Date</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="389"/>
<source>Ranked By Trend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="392"/>
<source>Favorited By Friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="395"/>
<source>Created By Friends</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="398"/>
<source>Created By Followed Users</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="401"/>
<source>Not Yet Rated</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="404"/>
<source>Total VotesAsc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="407"/>
<source>Votes Up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="410"/>
<source>Total Unique Subscriptions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="460"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="484"/>
<source>Forward</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>WorkshopItem</name> <name>WorkshopItem</name>
<message> <message>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -89,7 +89,7 @@
<message> <message>
<location filename="../qml/Community/Community.qml" line="56"/> <location filename="../qml/Community/Community.qml" line="56"/>
<source>Issue List</source> <source>Issue List</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Community/Community.qml" line="62"/> <location filename="../qml/Community/Community.qml" line="62"/>
@ -99,7 +99,7 @@
<message> <message>
<location filename="../qml/Community/Community.qml" line="68"/> <location filename="../qml/Community/Community.qml" line="68"/>
<source>Steam Workshop</source> <source>Steam Workshop</source>
<translation></translation> <translation>Steam </translation>
</message> </message>
</context> </context>
<context> <context>
@ -107,42 +107,42 @@
<message> <message>
<location filename="../qml/Community/CommunityNavItem.qml" line="57"/> <location filename="../qml/Community/CommunityNavItem.qml" line="57"/>
<source>Open in browser</source> <source>Open in browser</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
<name>CreateWallpaperInit</name> <name>CreateWallpaperInit</name>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="31"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="32"/>
<source>Import any video type</source> <source>Import any video type</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="37"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="38"/>
<source>Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are: <source>Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are:
*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</source> *.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</source>
<translation>PC配置QML壁纸 <translation>PC配置 QML
*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</translation> *.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="52"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="53"/>
<source>Set your preffered video codec:</source> <source>Set your preffered video codec:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="97"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="98"/>
<source>Quality slider. Lower value means better quality.</source> <source>Quality slider. Lower value means better quality.</source>
<translation> </translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="112"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="113"/>
<source>Open Documentation</source> <source>Open Documentation</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="130"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml" line="132"/>
<source>Select file</source> <source>Select file</source>
<translation></translation> <translation></translation>
</message> </message>
@ -157,7 +157,7 @@
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml" line="91"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml" line="91"/>
<source>Copy text to clipboard</source> <source>Copy text to clipboard</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml" line="102"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml" line="102"/>
@ -167,90 +167,90 @@
</context> </context>
<context> <context>
<name>CreateWallpaperVideoImportConvert</name> <name>CreateWallpaperVideoImportConvert</name>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="47"/>
<source>Generating preview image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="50"/>
<source>Generating preview thumbnail image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="57"/>
<source>Generating 5 second preview video...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="60"/>
<source>Generating preview gif...</source>
<translation>gif...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="69"/>
<source>Converting Audio...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="72"/>
<source>Converting Video... This can take some time!</source>
<translation>... </translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="75"/>
<source>Converting Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="78"/>
<source>Analyse Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="106"/>
<source>Convert a video to a wallpaper</source>
<translation></translation>
</message>
<message> <message>
<location filename="../qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml" line="198"/> <location filename="../qml/Create/Wizards/CreateWallpaper/CreateWallpaperVideoImportConvert.qml" line="198"/>
<source></source> <source></source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="221"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="48"/>
<source>Generating preview video...</source> <source>Generating preview image...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="281"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="51"/>
<source>Generating preview thumbnail image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="58"/>
<source>Generating 5 second preview video...</source>
<translation>5...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="61"/>
<source>Generating preview gif...</source>
<translation>GIF...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="70"/>
<source>Converting Audio...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="73"/>
<source>Converting Video... This can take some time!</source>
<translation>... </translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="77"/>
<source>Converting Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="80"/>
<source>Analyse Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="108"/>
<source>Convert a video to a wallpaper</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="219"/>
<source>Generating preview video...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="275"/>
<source>Name (required!)</source> <source>Name (required!)</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="295"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="289"/>
<source>Description</source> <source>Description</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="303"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="297"/>
<source>Youtube URL</source> <source>Youtube URL</source>
<translation>Youtube链接</translation> <translation>Youtube </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="334"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="327"/>
<source>Abort</source> <source>Abort</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="347"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="340"/>
<source>Save</source> <source>Save</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="382"/> <location filename="../qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml" line="377"/>
<source>Save Wallpaper...</source> <source>Save Wallpaper...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
</context> </context>
<context> <context>
@ -268,7 +268,7 @@
<message> <message>
<location filename="../qml/Monitors/DefaultVideoControls.qml" line="66"/> <location filename="../qml/Monitors/DefaultVideoControls.qml" line="66"/>
<source>Current Video Time</source> <source>Current Video Time</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Monitors/DefaultVideoControls.qml" line="83"/> <location filename="../qml/Monitors/DefaultVideoControls.qml" line="83"/>
@ -298,7 +298,7 @@
<message> <message>
<location filename="../qml/Monitors/DefaultVideoControls.qml" line="114"/> <location filename="../qml/Monitors/DefaultVideoControls.qml" line="114"/>
<source>Scale_Down</source> <source>Scale_Down</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -324,17 +324,17 @@
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="26"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="26"/>
<source>Import a Gif Wallpaper</source> <source>Import a Gif Wallpaper</source>
<translation>GIF壁纸</translation> <translation> GIF </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="82"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="82"/>
<source>Drop a *.gif file here or use &apos;Select file&apos; below.</source> <source>Drop a *.gif file here or use &apos;Select file&apos; below.</source>
<translation>gif文件拖到这使&apos;&apos;</translation> <translation> *.gif 使 &apos;&apos;</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="105"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="105"/>
<source>Select your gif</source> <source>Select your gif</source>
<translation>GIF</translation> <translation> GIF</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="120"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="120"/>
@ -344,7 +344,7 @@
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="127"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="127"/>
<source>Wallpaper name</source> <source>Wallpaper name</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/GifWallpaper.qml" line="135"/> <location filename="../qml/Create/Wizards/GifWallpaper.qml" line="135"/>
@ -362,7 +362,7 @@
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="29"/> <location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="29"/>
<source>Create a HTML Wallpaper</source> <source>Create a HTML Wallpaper</source>
<translation>HTML壁</translation> <translation> HTML </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="34"/> <location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="34"/>
@ -372,12 +372,12 @@
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="44"/> <location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="44"/>
<source>Wallpaper name</source> <source>Wallpaper name</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="53"/> <location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="53"/>
<source>Created By</source> <source>Created By</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="62"/> <location filename="../qml/Create/Wizards/HTMLWallpaper.qml" line="62"/>
@ -400,7 +400,7 @@
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWidget.qml" line="20"/> <location filename="../qml/Create/Wizards/HTMLWidget.qml" line="20"/>
<source>Create a HTML widget</source> <source>Create a HTML widget</source>
<translation>HTML部</translation> <translation> HTML </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWidget.qml" line="74"/> <location filename="../qml/Create/Wizards/HTMLWidget.qml" line="74"/>
@ -410,7 +410,7 @@
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWidget.qml" line="82"/> <location filename="../qml/Create/Wizards/HTMLWidget.qml" line="82"/>
<source>Widget name</source> <source>Widget name</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/HTMLWidget.qml" line="90"/> <location filename="../qml/Create/Wizards/HTMLWidget.qml" line="90"/>
@ -436,7 +436,7 @@
<message> <message>
<location filename="../qml/Common/HeadlineSection.qml" line="6"/> <location filename="../qml/Common/HeadlineSection.qml" line="6"/>
<source>Headline Section</source> <source>Headline Section</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -444,7 +444,7 @@
<message> <message>
<location filename="../qml/Common/ImageSelector.qml" line="118"/> <location filename="../qml/Common/ImageSelector.qml" line="118"/>
<source>Set your own preview image</source> <source>Set your own preview image</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Common/ImageSelector.qml" line="159"/> <location filename="../qml/Common/ImageSelector.qml" line="159"/>
@ -459,95 +459,95 @@
</context> </context>
<context> <context>
<name>ImportWebmConvert</name> <name>ImportWebmConvert</name>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="42"/>
<source>AnalyseVideo...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="45"/>
<source>Generating preview image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="48"/>
<source>Generating preview thumbnail image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="55"/>
<source>Generating 5 second preview video...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="58"/>
<source>Generating preview gif...</source>
<translation>gif...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="67"/>
<source>Converting Audio...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="70"/>
<source>Converting Video... This can take some time!</source>
<translation>... </translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="73"/>
<source>Converting Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="76"/>
<source>Analyse Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="104"/>
<source>Import a video to a wallpaper</source>
<translation></translation>
</message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="189"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="189"/>
<source></source> <source></source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="214"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="43"/>
<source>Generating preview video...</source> <source>AnalyseVideo...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="274"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="46"/>
<source>Generating preview image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="49"/>
<source>Generating preview thumbnail image...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="56"/>
<source>Generating 5 second preview video...</source>
<translation>5...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="59"/>
<source>Generating preview gif...</source>
<translation> GIF...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="68"/>
<source>Converting Audio...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="71"/>
<source>Converting Video... This can take some time!</source>
<translation>... </translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="74"/>
<source>Converting Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="77"/>
<source>Analyse Video ERROR!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="105"/>
<source>Import a video to a wallpaper</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="215"/>
<source>Generating preview video...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="275"/>
<source>Name (required!)</source> <source>Name (required!)</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="288"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="289"/>
<source>Description</source> <source>Description</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="296"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="297"/>
<source>Youtube URL</source> <source>Youtube URL</source>
<translation>Youtube链接</translation> <translation>Youtube </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="327"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="328"/>
<source>Abort</source> <source>Abort</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="340"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="341"/>
<source>Save</source> <source>Save</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="375"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml" line="375"/>
<source>Save Wallpaper...</source> <source>Save Wallpaper...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
</context> </context>
<context> <context>
@ -555,17 +555,17 @@
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="32"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="32"/>
<source>Import a .webm video</source> <source>Import a .webm video</source>
<translation>webm视</translation> <translation> .webm </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="48"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="48"/>
<source>When importing webm we can skip the long conversion. When you get unsatisfying results with the ScreenPlay importer from &apos;ideo import and convert (all types)&apos; you can also convert via the free and open source HandBrake!</source> <source>When importing webm we can skip the long conversion. When you get unsatisfying results with the ScreenPlay importer from &apos;ideo import and convert (all types)&apos; you can also convert via the free and open source HandBrake!</source>
<translation>webm时&apos;ideo导入和转&apos;ScreenPlay导入器得到的结果不满意时使HandBrake!</translation> <translation>webm时&apos;&apos; ScreenPlay 使HandBrake!</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="74"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="74"/>
<source>Invalid file type. Must be valid VP8 or VP9 (*.webm)!</source> <source>Invalid file type. Must be valid VP8 or VP9 (*.webm)!</source>
<translation>VP8/VP9*.webm</translation> <translation> VP8 / VP9*.webm</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="97"/> <location filename="../qml/Create/Wizards/ImportWebm/ImportWebmInit.qml" line="97"/>
@ -586,38 +586,43 @@
<context> <context>
<name>Installed</name> <name>Installed</name>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="130"/> <location filename="../qml/Installed/Installed.qml" line="131"/>
<source>Refreshing!</source> <source>Refreshing!</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="133"/> <location filename="../qml/Installed/Installed.qml" line="134"/>
<location filename="../qml/Installed/Installed.qml" line="148"/> <location filename="../qml/Installed/Installed.qml" line="149"/>
<source>Pull to refresh!</source> <source>Pull to refresh!</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="178"/> <location filename="../qml/Installed/Installed.qml" line="179"/>
<source>Get more Wallpaper &amp; Widgets via the Steam workshop!</source> <source>Get more Wallpaper &amp; Widgets via the Steam workshop!</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="242"/> <location filename="../qml/Installed/Installed.qml" line="244"/>
<source>Open containing folder</source> <source>Open containing folder</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="250"/> <location filename="../qml/Installed/Installed.qml" line="252"/>
<source>Deinstall Item</source> <source>Remove Item</source>
<translation></translation> <translation></translation>
</message>
<message>
<location filename="../qml/Installed/Installed.qml" line="252"/>
<source>Remove via Workshop</source>
<translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="261"/> <location filename="../qml/Installed/Installed.qml" line="261"/>
<source>Open workshop Page</source> <source>Open Workshop Page</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Installed.qml" line="276"/> <location filename="../qml/Installed/Installed.qml" line="277"/>
<source>Are you sure you want to delete this item?</source> <source>Are you sure you want to delete this item?</source>
<translation></translation> <translation></translation>
</message> </message>
@ -892,6 +897,14 @@
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>ScreenPlayItem</name>
<message>
<location filename="../qml/Installed/ScreenPlayItem.qml" line="206"/>
<source>NEW</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>Search</name> <name>Search</name>
<message> <message>
@ -927,11 +940,6 @@
<source>Send anonymous crash reports and statistics</source> <source>Send anonymous crash reports and statistics</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="99"/>
<source>Help us make ScreenPlay faster and more stable. All collected data is purely anonymous and only used for development purposes!</source>
<translation>ScreenPlay更快更稳定</translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="110"/> <location filename="../qml/Settings/Settings.qml" line="110"/>
<source>Set save location</source> <source>Set save location</source>
@ -967,6 +975,11 @@
<source>ScreenPlay will start with Windows and will setup your Desktop every time for you.</source> <source>ScreenPlay will start with Windows and will setup your Desktop every time for you.</source>
<translation>ScreenPlay将在操作系统启动时启动</translation> <translation>ScreenPlay将在操作系统启动时启动</translation>
</message> </message>
<message>
<location filename="../qml/Settings/Settings.qml" line="99"/>
<source>Help us make ScreenPlay faster and more stable. All collected data is purely anonymous and only used for development purposes! We use &lt;a href=&quot;https://sentry.io&quot;&gt;sentry.io&lt;/a&gt; to collect and analyze this data. A &lt;b&gt;big thanks to them&lt;/b&gt; for providing us with free premium support for open source projects!</source>
<translation> ScreenPlay 使&lt;a href=&quot;https://sentry.io&quot;&gt;sentry.io&lt;/a&gt; 收集与分析数据。&lt;b&gt;感谢他们&lt;/b&gt; 为我们提供对开源项目免费而优质的服务!</translation>
</message>
<message> <message>
<location filename="../qml/Settings/Settings.qml" line="116"/> <location filename="../qml/Settings/Settings.qml" line="116"/>
<source>Your storage path is empty!</source> <source>Your storage path is empty!</source>
@ -1189,37 +1202,37 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="287"/> <location filename="../qml/Installed/Sidebar.qml" line="288"/>
<source>Set Volume</source> <source>Set Volume</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="306"/> <location filename="../qml/Installed/Sidebar.qml" line="307"/>
<source>Fill Mode</source> <source>Fill Mode</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="325"/> <location filename="../qml/Installed/Sidebar.qml" line="326"/>
<source>Stretch</source> <source>Stretch</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="328"/> <location filename="../qml/Installed/Sidebar.qml" line="329"/>
<source>Fill</source> <source>Fill</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="331"/> <location filename="../qml/Installed/Sidebar.qml" line="332"/>
<source>Contain</source> <source>Contain</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="334"/> <location filename="../qml/Installed/Sidebar.qml" line="335"/>
<source>Cover</source> <source>Cover</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Installed/Sidebar.qml" line="337"/> <location filename="../qml/Installed/Sidebar.qml" line="338"/>
<source>Scale-Down</source> <source>Scale-Down</source>
<translation></translation> <translation></translation>
</message> </message>
@ -1274,42 +1287,47 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="116"/> <location filename="../qml/Create/Sidebar.qml" line="118"/>
<source>Tools Overview</source> <source>Tools Overview</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="128"/> <location filename="../qml/Create/Sidebar.qml" line="124"/>
<source>Video import and convert (all types)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/Create/Sidebar.qml" line="131"/>
<source>Video Import (.webm)</source> <source>Video Import (.webm)</source>
<translation> (.webm)</translation> <translation> (.webm)</translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="134"/> <location filename="../qml/Create/Sidebar.qml" line="137"/>
<source>GIF Wallpaper</source> <source>GIF Wallpaper</source>
<translation>GIF </translation> <translation>GIF </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="140"/> <location filename="../qml/Create/Sidebar.qml" line="143"/>
<source>QML Wallpaper</source> <source>QML Wallpaper</source>
<translation>QML </translation> <translation>QML </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="146"/> <location filename="../qml/Create/Sidebar.qml" line="149"/>
<source>HTML5 Wallpaper</source> <source>HTML5 Wallpaper</source>
<translation>HTML5 </translation> <translation>HTML5 </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="152"/> <location filename="../qml/Create/Sidebar.qml" line="155"/>
<source>Website Wallpaper</source> <source>Website Wallpaper</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="158"/> <location filename="../qml/Create/Sidebar.qml" line="161"/>
<source>QML Widget</source> <source>QML Widget</source>
<translation>QML </translation> <translation>QML </translation>
</message> </message>
<message> <message>
<location filename="../qml/Create/Sidebar.qml" line="164"/> <location filename="../qml/Create/Sidebar.qml" line="167"/>
<source>HTML Widget</source> <source>HTML Widget</source>
<translation>HTML </translation> <translation>HTML </translation>
</message> </message>
@ -1335,6 +1353,123 @@
<translation>steam集成</translation> <translation>steam集成</translation>
</message> </message>
</context> </context>
<context>
<name>SteamProfile</name>
<message>
<location filename="../qml/Workshop/SteamProfile.qml" line="78"/>
<location filename="../qml/Workshop/SteamProfile.qml" line="138"/>
<source>Back</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamProfile.qml" line="160"/>
<source>Forward</source>
<translation></translation>
</message>
</context>
<context>
<name>SteamWorkshop</name>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="151"/>
<source>Loading</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="163"/>
<source>Download now!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="168"/>
<source>Downloading...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="176"/>
<source>Details</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="202"/>
<source>Open In Steam</source>
<translation>Steam打开</translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="286"/>
<source>Profile</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="305"/>
<source>Search for Wallpaper and Widgets...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="349"/>
<source>Open Workshop in Steam</source>
<translation>Steam中打开创意工坊</translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="373"/>
<source>Ranked By Vote</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="376"/>
<source>Publication Date</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="379"/>
<source>Ranked By Trend</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="382"/>
<source>Favorited By Friends</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="385"/>
<source>Created By Friends</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="388"/>
<source>Created By Followed Users</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="391"/>
<source>Not Yet Rated</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="394"/>
<source>Total VotesAsc</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="397"/>
<source>Votes Up</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="400"/>
<source>Total Unique Subscriptions</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="449"/>
<source>Back</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/SteamWorkshop.qml" line="473"/>
<source>Forward</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>TagSelector</name> <name>TagSelector</name>
<message> <message>
@ -2086,109 +2221,6 @@
<translation>...</translation> <translation>...</translation>
</message> </message>
</context> </context>
<context>
<name>Workshop</name>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="171"/>
<source>Loading</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="183"/>
<source>Download now!</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="188"/>
<source>Downloading...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="196"/>
<source>Details</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="222"/>
<source>Open In Steam</source>
<translation>Steam打开</translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="281"/>
<source>Search for Wallpaper and Widgets...</source>
<translation>...</translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="347"/>
<source>Open Workshop in Steam</source>
<translation>Steam中打开创意工坊</translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="359"/>
<source>Open GameHub in Steam</source>
<translation>Steam中打开游戏社区</translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="383"/>
<source>Ranked By Vote</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="386"/>
<source>Publication Date</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="389"/>
<source>Ranked By Trend</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="392"/>
<source>Favorited By Friends</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="395"/>
<source>Created By Friends</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="398"/>
<source>Created By Followed Users</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="401"/>
<source>Not Yet Rated</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="404"/>
<source>Total VotesAsc</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="407"/>
<source>Votes Up</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="410"/>
<source>Total Unique Subscriptions</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="460"/>
<source>Back</source>
<translation></translation>
</message>
<message>
<location filename="../qml/Workshop/Workshop.qml" line="484"/>
<source>Forward</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>WorkshopItem</name> <name>WorkshopItem</name>
<message> <message>

View File

@ -1,42 +0,0 @@
Function Execute-Command ($commandTitle, $commandPath, $commandArguments)
{
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "$commandPath"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.WorkingDirectory = "$PSScriptRoot"
$pinfo.Arguments = $commandArguments
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$exitcodestr = $p.ExitCode.ToString()
Write-Output $p.StandardOutput.ReadToEnd()
Write-Output $p.StandardError.ReadToEnd()
Write-Output "Exit code: $exitcodestr"
}
$MSVCPATH = Read-Host 'Type your ABSOLUTE Qt "bin" directory (default is C:\Qt\5.15.2\msvc2019_64\bin)'
if ($MSVCPATH -eq "") {
echo "Using default directory..."
$MSVCPATH = "C:\Qt\5.15.2\msvc2019_64\bin"
}
echo "Testing directory..."
if (((Test-Path -Path "$MSVCPATH\lupdate.exe") -eq $true) -and ((Test-Path -Path "$MSVCPATH\lrelease.exe") -eq $true)) {
echo "Begin update translations..."
$files = Get-ChildItem ".\*.ts"
foreach ($f in $files){
echo $PSScriptRoot
echo "Processing $f (1/2)"
Execute-Command -commandTitle "Update translation file: $f" -commandPath "$MSVCPATH\lupdate.exe" -commandArguments "-extensions qml ..\qml -ts ""$f"""
echo "Processing $f (2/2)"
Execute-Command -commandTitle "Compile translation file: $f" -commandPath "$MSVCPATH\lrelease.exe" -commandArguments """$f"""
echo "Done"
}
echo "Updated translations."
}
else
{
echo "lupdate or lrelease dosen't exist, failed to update translations..."
}
pause

View File

@ -1,28 +0,0 @@
#!/bin/bash
read -p 'Type your ABSOLUTE Qt "bin" directory (default is /usr/bin): ' path
if [ o$path == "o" ]
then
echo "Using default directory..."
path="/usr/bin"
fi
echo "Testing directory..."
if [[ -f "$path/lupdate" ]] && [[ -f "$path/lrelease" ]]
then
echo "Begin update translations..."
for f in ls *.ts
do
echo "Processing $f (1/2)"
$path/lupdate -extensions qml ../qml -ts $f
echo "Processing $f (2/2)"
$path/lrelease $f
echo "Done"
done
echo "Updated translations."
else
echo "lupdate or lrelease dosen't exist, failed to update translations..."
fi
echo Enter to exit.
read

View File

@ -3,12 +3,9 @@ project(ScreenPlaySDK LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package( find_package(
QT NAMES Qt6 Qt5 Qt6
COMPONENTS Quick Network Core
REQUIRED)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Quick Network Core COMPONENTS Quick Network Core
REQUIRED) REQUIRED)
@ -20,5 +17,4 @@ add_library(${PROJECT_NAME} ${src} ${headers})
target_include_directories(${PROJECT_NAME} PUBLIC inc) target_include_directories(${PROJECT_NAME} PUBLIC inc)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick Qt${QT_VERSION_MAJOR}::Gui target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Gui Qt6::Network)
Qt${QT_VERSION_MAJOR}::Network)

View File

@ -3,12 +3,9 @@ project(ScreenPlayShader LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package( find_package(
QT NAMES Qt6 Qt5 Qt6
COMPONENTS Quick Core
REQUIRED)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Quick Core COMPONENTS Quick Core
REQUIRED) REQUIRED)
@ -26,7 +23,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC inc)
set(URI "ScreenPlay/Shader") set(URI "ScreenPlay/Shader")
string(REPLACE "." "/" TARGETPATH ${URI}) string(REPLACE "." "/" TARGETPATH ${URI})
if(NOT DEFINED QT_QMAKE_EXECUTABLE) if(NOT DEFINED QT_QMAKE_EXECUTABLE)
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION) get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)
if(NOT QT_QMAKE_EXECUTABLE) if(NOT QT_QMAKE_EXECUTABLE)
message(FATAL_ERROR "Cannot find qmake") message(FATAL_ERROR "Cannot find qmake")
endif() endif()
@ -56,4 +53,4 @@ else()
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ScreenPlayShader> ${DESTDIR}/$<TARGET_FILE_NAME:ScreenPlayShader>) COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ScreenPlayShader> ${DESTDIR}/$<TARGET_FILE_NAME:ScreenPlayShader>)
endif() endif()
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick Qt${QT_VERSION_MAJOR}::Gui) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Gui)

View File

@ -5,13 +5,9 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package(infoware CONFIG REQUIRED) find_package(infoware CONFIG REQUIRED)
find_package(
QT NAMES Qt6 Qt5
COMPONENTS Quick Core
REQUIRED)
find_package( find_package(
Qt${QT_VERSION_MAJOR} Qt6
COMPONENTS Quick Core COMPONENTS Quick Core
REQUIRED) REQUIRED)
@ -40,7 +36,7 @@ add_library(${PROJECT_NAME} SHARED ${src} ${headers})
set(URI "ScreenPlay/Sysinfo") set(URI "ScreenPlay/Sysinfo")
string(REPLACE "." "/" TARGETPATH ${URI}) string(REPLACE "." "/" TARGETPATH ${URI})
if(NOT DEFINED QT_QMAKE_EXECUTABLE) if(NOT DEFINED QT_QMAKE_EXECUTABLE)
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION) get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)
if(NOT QT_QMAKE_EXECUTABLE) if(NOT QT_QMAKE_EXECUTABLE)
message(FATAL_ERROR "Cannot find qmake") message(FATAL_ERROR "Cannot find qmake")
endif() endif()
@ -61,4 +57,4 @@ add_custom_command(
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ScreenPlaySysInfo> ${DESTDIR}/$<TARGET_FILE_NAME:ScreenPlaySysInfo>) COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ScreenPlaySysInfo> ${DESTDIR}/$<TARGET_FILE_NAME:ScreenPlaySysInfo>)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick infoware) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick infoware)

View File

@ -3,12 +3,9 @@ project(ScreenPlayUtil LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package( find_package(
QT NAMES Qt6 Qt5 Qt6
COMPONENTS Core
REQUIRED)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core COMPONENTS Core
REQUIRED) REQUIRED)
@ -17,10 +14,8 @@ set(SOURCES src/util.cpp src/contenttypes.cpp)
set(HEADER inc/public/ScreenPlayUtil/util.h inc/public/ScreenPlayUtil/contenttypes.h inc/public/ScreenPlayUtil/projectfile.h) set(HEADER inc/public/ScreenPlayUtil/util.h inc/public/ScreenPlayUtil/contenttypes.h inc/public/ScreenPlayUtil/projectfile.h)
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADER}) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADER})
target_include_directories( target_include_directories(
${PROJECT_NAME} ${PROJECT_NAME}
PUBLIC inc/public/ PUBLIC inc/public/
PRIVATE src/) PRIVATE src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core)

View File

@ -34,6 +34,7 @@
#pragma once #pragma once
#include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
@ -58,6 +59,7 @@ struct ProjectFile {
const QJsonObject& obj, const QJsonObject& obj,
const QString& folderName, const QString& folderName,
const QUrl& absolutePath, const QUrl& absolutePath,
const bool isNew,
const QDateTime& lastModified) const QDateTime& lastModified)
{ {
@ -114,6 +116,7 @@ struct ProjectFile {
m_preview = m_previewGIF; m_preview = m_previewGIF;
} }
m_searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(m_type); m_searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(m_type);
m_isNew = isNew;
m_lastModified = lastModified; m_lastModified = lastModified;
} }
@ -135,6 +138,7 @@ struct ProjectFile {
InstalledType::InstalledType m_type = InstalledType::InstalledType::Unknown; InstalledType::InstalledType m_type = InstalledType::InstalledType::Unknown;
SearchType::SearchType m_searchType = SearchType::SearchType::All; SearchType::SearchType m_searchType = SearchType::SearchType::All;
bool m_isNew = false;
QDateTime m_lastModified; QDateTime m_lastModified;
}; };
} }

View File

@ -4,7 +4,21 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core) find_package(QT NAMES Qt6 COMPONENTS Core)
find_package(
Qt6
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
Multimedia
WebEngineCore
WebEngineQuick
WebChannel
Positioning)
if(WIN32) if(WIN32)
set(src_plattform src/windowsdesktopproperties.cpp src/winwindow.cpp) set(src_plattform src/windowsdesktopproperties.cpp src/winwindow.cpp)
@ -21,13 +35,25 @@ set(src main.cpp src/basewindow.cpp)
set(headers src/basewindow.h) set(headers src/basewindow.h)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
qt6_add_resources (resources SPWResources.qrc) qt6_add_resources(resources SPWResources.qrc)
else() else()
qt6_add_resources (resources SPWResources.qrc) qt6_add_resources(resources SPWResources.qrc)
endif() endif()
add_executable(${PROJECT_NAME} ${src} ${headers} ${src_plattform} ${headers_plattform} ${resources}) add_executable(${PROJECT_NAME} ${src} ${headers} ${src_plattform} ${headers_plattform} ${resources})
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt6::Quick
Qt6::Gui
Qt6::Widgets
Qt6::Core
Qt6::WebSockets
Qt6::Svg
Qt6::Multimedia
Qt6::WebEngineCore
Qt6::WebEngineQuick)
if(WIN32) if(WIN32)
# Disable console window on Windows # Disable console window on Windows
# https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows # https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows
@ -42,48 +68,14 @@ endif()
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySDK ScreenPlayUtil) target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySDK ScreenPlayUtil)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) if(WIN32)
find_package( # Disable console window on Windows
Qt${QT_VERSION_MAJOR} # https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows
COMPONENTS Core set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true)
Quick target_link_libraries(${PROJECT_NAME} PRIVATE shcore.lib)
Gui endif()
Widgets
WebSockets if(APPLE)
Svg set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
Multimedia target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")
WebEngineCore
WebEngineQuick
WebChannel
Positioning)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt6::Multimedia
Qt6::WebEngineCore
Qt6::WebEngineQuick)
else()
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
WebEngine)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt5::WebEngine)
endif() endif()

View File

@ -16,10 +16,12 @@
<string>${PRODUCT_NAME}</string> <string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>ScreenPlayWallpaper</string> <string>ScreenPlayWallpaper</string>
<key>CFBundleVersion</key>
<string>0.14</string>
<key>CFBundleShortVersionString</key>
<string>0.14</string>
<key>NSUIElement</key> <key>NSUIElement</key>
<string>1</string> <string>1</string>
<key>LSUIElement</key> <key>LSUIElement</key>

View File

@ -1,13 +1,13 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>Wallpaper.qml</file>
<file>Test.qml</file>
<file>dot.png</file> <file>dot.png</file>
<file>qtquickcontrols2.conf</file> <file>qtquickcontrols2.conf</file>
<file>WebView.qml</file>
<file>index.html</file> <file>index.html</file>
<file>GifWallpaper.qml</file> <file>qml/GifWallpaper.qml</file>
<file>WebsiteWallpaper.qml</file> <file>qml/Test.qml</file>
<file>MultimediaView.qml</file> <file>qml/Wallpaper.qml</file>
<file>qml/WebsiteWallpaper.qml</file>
<file>qml/WebView.qml</file>
<file>qml/MultimediaView.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -47,9 +47,9 @@ int main(int argc, char* argv[])
WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true); WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true);
//WinWindow window1({ 0 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/_tmp_171806", "appID=test", "1", "fill", "videoWallpaper", true, true); //WinWindow window1({ 0 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/_tmp_171806", "appID=test", "1", "fill", "videoWallpaper", true, true);
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
LinuxWindow window({ 0 }, "test", "appid", "1", "fill", false); LinuxWindow window({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", false, true);
#elif defined(Q_OS_OSX) #elif defined(Q_OS_OSX)
MacWindow window({ 0 }, "test", "appID=test", "1", "fill","videoWallpaper", true, true); MacWindow window({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true);
#endif #endif
return app.exec(); return app.exec();
} }
@ -93,21 +93,23 @@ int main(int argc, char* argv[])
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
LinuxWindow window( LinuxWindow window(
activeScreensList.value(), activeScreensList.value(),
projectPath, projectFilePath,
appID, appID,
fillmode,
volume, volume,
checkWallpaperVisible); fillmode,
type,
checkWallpaperVisible,
debugMode);
#elif defined(Q_OS_OSX) #elif defined(Q_OS_OSX)
MacWindow window( MacWindow window(
activeScreensList.value(), activeScreensList.value(),
projectFilePath, projectFilePath,
appID, appID,
volume, volume,
fillmode, fillmode,
type, type,
checkWallpaperVisible, checkWallpaperVisible,
debugMode); debugMode);
#endif #endif
return app.exec(); return app.exec();

View File

@ -3,8 +3,6 @@ import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import ScreenPlayWallpaper 1.0 import ScreenPlayWallpaper 1.0
import ScreenPlay.Enums.InstalledType 1.0 import ScreenPlay.Enums.InstalledType 1.0
import ScreenPlay.Shader 1.0
import "ShaderWrapper" as ShaderWrapper
Rectangle { Rectangle {
id: root id: root
@ -17,7 +15,7 @@ Rectangle {
loader.source = "qrc:/MultimediaView.qml"; loader.source = "qrc:/MultimediaView.qml";
break; break;
case InstalledType.HTMLWallpaper: case InstalledType.HTMLWallpaper:
loader.setSource("qrc:/WebView.qml", { loader.setSource("qrc:/qml/WebView.qml", {
"url": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) "url": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute)
}); });
break; break;
@ -26,13 +24,13 @@ Rectangle {
fadeIn(); fadeIn();
break; break;
case InstalledType.WebsiteWallpaper: case InstalledType.WebsiteWallpaper:
loader.setSource("qrc:/WebsiteWallpaper.qml", { loader.setSource("qrc:/qml/WebsiteWallpaper.qml", {
"url": Wallpaper.projectSourceFileAbsolute "url": Wallpaper.projectSourceFileAbsolute
}); });
fadeIn(); fadeIn();
break; break;
case InstalledType.GifWallpaper: case InstalledType.GifWallpaper:
loader.setSource("qrc:/GifWallpaper.qml", { loader.setSource("qrc:/qml/GifWallpaper.qml", {
"source": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) "source": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute)
}); });
fadeIn(); fadeIn();
@ -96,7 +94,7 @@ Rectangle {
return ; return ;
imgCover.state = "showDefaultBackgroundImage"; imgCover.state = "showDefaultBackgroundImage";
loader.source = "qrc:/WebView.qml"; loader.source = "qrc:/qml/WebView.qml";
} }
target: Wallpaper target: Wallpaper

View File

@ -8,31 +8,31 @@ Item {
property alias url: webView.url property alias url: webView.url
signal requestFadeIn() signal requestFadeIn
function getSetVideoCommand() { function getSetVideoCommand() {
// TODO 30: // TODO 30:
// Currently wont work. Commit anyways til QtCreator and Qt work with js template literals // Currently wont work. Commit anyways til QtCreator and Qt work with js template literals
var src = ""; var src = ""
src += "var videoPlayer = document.getElementById('videoPlayer');"; src += "var videoPlayer = document.getElementById('videoPlayer');"
src += "var videoSource = document.getElementById('videoSource');"; src += "var videoSource = document.getElementById('videoSource');"
src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';"; src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';"
src += "videoPlayer.load();"; src += "videoPlayer.load();"
src += "videoPlayer.volume = " + Wallpaper.volume + ";"; src += "videoPlayer.volume = " + Wallpaper.volume + ";"
src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');"; src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');"
src += "videoPlayer.play();"; src += "videoPlayer.play();"
return src; return src
} }
Component.onCompleted: { Component.onCompleted: {
WebEngine.settings.localContentCanAccessFileUrls = true; WebEngine.settings.localContentCanAccessFileUrls = true
WebEngine.settings.localContentCanAccessRemoteUrls = true; WebEngine.settings.localContentCanAccessRemoteUrls = true
WebEngine.settings.allowRunningInsecureContent = true; WebEngine.settings.allowRunningInsecureContent = true
WebEngine.settings.accelerated2dCanvasEnabled = true; WebEngine.settings.accelerated2dCanvasEnabled = true
WebEngine.settings.javascriptCanOpenWindows = false; WebEngine.settings.javascriptCanOpenWindows = false
WebEngine.settings.showScrollBars = false; WebEngine.settings.showScrollBars = false
WebEngine.settings.playbackRequiresUserGesture = false; WebEngine.settings.playbackRequiresUserGesture = false
WebEngine.settings.focusOnNavigationEnabled = true; WebEngine.settings.focusOnNavigationEnabled = true
} }
WebEngineView { WebEngineView {
@ -45,18 +45,18 @@ Item {
onLoadProgressChanged: { onLoadProgressChanged: {
if ((loadProgress === 100)) { if ((loadProgress === 100)) {
if (Wallpaper.type === InstalledType.VideoWallpaper) if (Wallpaper.type === InstalledType.VideoWallpaper)
webView.runJavaScript(root.getSetVideoCommand(), function(result) { webView.runJavaScript(root.getSetVideoCommand(),
requestFadeIn(); function (result) {
}); requestFadeIn()
})
else else
requestFadeIn(); requestFadeIn()
} }
} }
} }
Text { Text {
id: txtVisualsPaused id: txtVisualsPaused
text: qsTr("If you can read this, then the VisualsPaused optimization does not work on your system. You can fix this by disable this in: \n Settings -> Perfromance -> Pause wallpaper video rendering while another app is in the foreground ") text: qsTr("If you can read this, then the VisualsPaused optimization does not work on your system. You can fix this by disable this in: \n Settings -> Perfromance -> Pause wallpaper video rendering while another app is in the foreground ")
font.pointSize: 32 font.pointSize: 32
visible: false visible: false
@ -73,77 +73,82 @@ Item {
interval: 300 interval: 300
onTriggered: { onTriggered: {
webView.visible = !Wallpaper.visualsPaused; webView.visible = !Wallpaper.visualsPaused
txtVisualsPaused.visible = Wallpaper.visualsPaused; txtVisualsPaused.visible = Wallpaper.visualsPaused
} }
} }
Connections { Connections {
function onReloadVideo(oldType) { function onReloadVideo(oldType) {
webView.runJavaScript(root.getSetVideoCommand()); webView.runJavaScript(root.getSetVideoCommand())
} }
function onQmlExit() { function onQmlExit() {
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
} }
function onMutedChanged(muted) { function onMutedChanged(muted) {
if (muted) if (muted)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
else else
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";")
} }
function onFillModeChanged(fillMode) { function onFillModeChanged(fillMode) {
if (webView.loadProgress === 100) if (webView.loadProgress === 100)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');")
} }
function onLoopsChanged(loops) { function onLoopsChanged(loops) {
if (webView.loadProgress === 100) if (webView.loadProgress === 100)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";")
} }
function onVolumeChanged(volume) { function onVolumeChanged(volume) {
if (webView.loadProgress === 100) if (webView.loadProgress === 100)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";")
} }
function onCurrentTimeChanged(currentTime) { function onCurrentTimeChanged(currentTime) {
if (webView.loadProgress === 100) if (webView.loadProgress === 100)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = " + currentTime + " * videoPlayer.duration;"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = "
+ currentTime + " * videoPlayer.duration;")
} }
function onPlaybackRateChanged(playbackRate) { function onPlaybackRateChanged(playbackRate) {
if (webView.loadProgress === 100) if (webView.loadProgress === 100)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";")
} }
function onVisualsPausedChanged(visualsPaused) { function onVisualsPausedChanged(visualsPaused) {
if (visualsPaused) { if (visualsPaused) {
// Wait until Wallpaper animation is finsihed // Wait until Wallpaper animation is finsihed
timerCover.restart(); timerCover.restart()
} else { } else {
webView.visible = true; webView.visible = true
txtVisualsPaused.visible = false; txtVisualsPaused.visible = false
} }
} }
function onIsPlayingChanged(isPlaying) { function onIsPlayingChanged(isPlaying) {
if (webView.loadProgress === 100) { if (webView.loadProgress === 100) {
if (isPlaying) if (isPlaying)
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();")
else else
webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();"); webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();")
} }
} }
target: Wallpaper target: Wallpaper
} }
} }

View File

@ -54,7 +54,7 @@ BaseWindow::BaseWindow(
if (projectFilePath == "test") { if (projectFilePath == "test") {
setType(ScreenPlay::InstalledType::InstalledType::QMLWallpaper); setType(ScreenPlay::InstalledType::InstalledType::QMLWallpaper);
setProjectSourceFileAbsolute({ "qrc:/Test.qml" }); setProjectSourceFileAbsolute({ "qrc:/qml/Test.qml" });
setupLiveReloading(); setupLiveReloading();
return; return;
} }

View File

@ -150,6 +150,7 @@ public slots:
virtual void destroyThis() { } virtual void destroyThis() { }
virtual void setVisible(bool show) { Q_UNUSED(show) } virtual void setVisible(bool show) { Q_UNUSED(show) }
virtual void messageReceived(QString key, QString value) final; virtual void messageReceived(QString key, QString value) final;
virtual void clearComponentCache() {}
virtual void replaceWallpaper( virtual void replaceWallpaper(
const QString absolutePath, const QString absolutePath,
const QString file, const QString file,
@ -357,31 +358,31 @@ private:
private: private:
bool m_checkWallpaperVisible { false }; bool m_checkWallpaperVisible { false };
bool m_visualsPaused { false }; bool m_visualsPaused { false };
bool m_loops { true }; bool m_loops { true };
bool m_isPlaying { true }; bool m_isPlaying { true };
bool m_muted { false }; bool m_muted { false };
bool m_canFade { false }; bool m_canFade { false };
bool m_debugMode { false };
float m_volume { 1.0f }; float m_volume { 1.0f };
float m_playbackRate { 1.0f }; float m_playbackRate { 1.0f };
float m_currentTime { 0.0f }; float m_currentTime { 0.0f };
QString m_contentBasePath;
QString m_projectPath;
QString m_projectSourceFile;
QString m_appID; QString m_appID;
ScreenPlay::InstalledType::InstalledType m_type = ScreenPlay::InstalledType::InstalledType::Unknown;
QString m_OSVersion; QString m_OSVersion;
QString m_fillMode; QString m_fillMode;
int m_width { 0 }; int m_width { 0 };
int m_height { 0 }; int m_height { 0 };
ScreenPlay::InstalledType::InstalledType m_type = ScreenPlay::InstalledType::InstalledType::Unknown;
QVector<int> m_activeScreensList; QVector<int> m_activeScreensList;
QFileSystemWatcher m_fileSystemWatcher; QFileSystemWatcher m_fileSystemWatcher;
QTimer m_liveReloadLimiter; QTimer m_liveReloadLimiter;
QSysInfo m_sysinfo; QSysInfo m_sysinfo;
bool m_debugMode = false;
std::unique_ptr<ScreenPlaySDK> m_sdk; std::unique_ptr<ScreenPlaySDK> m_sdk;
QString m_contentBasePath;
QString m_projectPath;
QString m_projectSourceFile;
QUrl m_projectSourceFileAbsolute; QUrl m_projectSourceFileAbsolute;
}; };

View File

@ -1,15 +1,28 @@
#include "linuxwindow.h" #include "linuxwindow.h"
LinuxWindow::LinuxWindow(QVector<int> activeScreensList, QString projectPath, QString id, QString volume, const QString fillmode, const bool checkWallpaperVisible, QObject* parent) LinuxWindow::LinuxWindow(
: BaseWindow(projectPath, activeScreensList, checkWallpaperVisible) const QVector<int>& activeScreensList,
const QString& projectFilePath,
const QString& appID,
const QString& volume,
const QString& fillmode,
const QString& type,
const bool checkWallpaperVisible,
const bool debugMode,
QObject* parent)
: BaseWindow(
activeScreensList,
projectFilePath,
type,
checkWallpaperVisible,
appID,
debugMode)
{ {
m_window.setWidth(1920); m_window.setWidth(1920);
m_window.setHeight(1080); m_window.setHeight(1080);
m_window.show(); m_window.show();
setAppID(id);
bool ok = false; bool ok = false;
float volumeParsed = volume.toFloat(&ok); float volumeParsed = volume.toFloat(&ok);
if (!ok) { if (!ok) {

View File

@ -50,7 +50,16 @@
class LinuxWindow : public BaseWindow { class LinuxWindow : public BaseWindow {
Q_OBJECT Q_OBJECT
public: public:
explicit LinuxWindow(QVector<int> activeScreensList, QString projectPath, QString id, QString volume, const QString fillmode, const bool checkWallpaperVisible, QObject* parent = nullptr); explicit LinuxWindow(
const QVector<int>& activeScreensList,
const QString& projectFilePath,
const QString& appID,
const QString& volume,
const QString& fillmode,
const QString& type,
const bool checkWallpaperVisible,
const bool debugMode,
QObject* parent = nullptr);
signals: signals:

View File

@ -46,7 +46,7 @@ MacWindow::MacWindow(
m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::Desktop); m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::Desktop);
m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView);
m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering);
m_window.setSource(QUrl("qrc:/Wallpaper.qml")); m_window.setSource(QUrl("qrc:/qml/Wallpaper.qml"));
MacIntegration* macIntegration = new MacIntegration(this); MacIntegration* macIntegration = new MacIntegration(this);
macIntegration->SetBackgroundLevel(&m_window); macIntegration->SetBackgroundLevel(&m_window);
@ -63,3 +63,8 @@ void MacWindow::destroyThis()
{ {
QCoreApplication::quit(); QCoreApplication::quit();
} }
void MacWindow::clearComponentCache()
{
m_window.engine()->clearComponentCache();
}

View File

@ -65,6 +65,7 @@ signals:
public slots: public slots:
void setVisible(bool show) override; void setVisible(bool show) override;
void destroyThis() override; void destroyThis() override;
void clearComponentCache() override;
private: private:
QQuickView m_window; QQuickView m_window;

View File

@ -189,6 +189,15 @@ WinWindow::WinWindow(
connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &WinWindow::messageReceived); connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &WinWindow::messageReceived);
connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &WinWindow::replaceWallpaper); connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &WinWindow::replaceWallpaper);
connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow);
connect(
&m_window, &QQuickView::statusChanged,
this, [](auto status) {
if (status == QQuickView::Status::Error) {
qInfo() << status;
QCoreApplication::exit(-1);
}
},
Qt::QueuedConnection);
const auto screens = QApplication::screens(); const auto screens = QApplication::screens();
for (const auto& screen : screens) { for (const auto& screen : screens) {
@ -480,7 +489,7 @@ void WinWindow::configureWindowGeometry()
// Instead of setting "renderType: Text.NativeRendering" every time we can set it here once // Instead of setting "renderType: Text.NativeRendering" every time we can set it here once
m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering);
m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView);
m_window.setSource(QUrl("qrc:/Wallpaper.qml")); m_window.setSource(QUrl("qrc:/qml/Wallpaper.qml"));
m_window.hide(); m_window.hide();
} }

View File

@ -73,7 +73,7 @@ public slots:
void setVisible(bool show) override; void setVisible(bool show) override;
void destroyThis() override; void destroyThis() override;
void terminate(); void terminate();
void clearComponentCache(); void clearComponentCache() override;
void setWindowsDesktopProperties(WindowsDesktopProperties* windowsDesktopProperties) void setWindowsDesktopProperties(WindowsDesktopProperties* windowsDesktopProperties)
{ {

View File

@ -4,11 +4,24 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core) find_package(QT NAMES Qt6 COMPONENTS Core)
set(src main.cpp src/widgetwindow.cpp) set(src main.cpp src/widgetwindow.cpp)
set(headers src/widgetwindow.h) set(headers src/widgetwindow.h)
find_package(
Qt6
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
WebEngineCore
WebEngineQuick
WebChannel
Positioning)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
qt_add_resources(resources SPWidgetResources.qrc) qt_add_resources(resources SPWidgetResources.qrc)
else() else()
@ -17,6 +30,19 @@ endif()
add_executable(${PROJECT_NAME} ${src} ${headers} ${resources}) add_executable(${PROJECT_NAME} ${src} ${headers} ${resources})
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt6::Quick
Qt6::Gui
Qt6::Widgets
Qt6::Core
Qt6::WebSockets
Qt6::Svg
Qt6::WebEngineCore
Qt6::WebEngineQuick)
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySDK ScreenPlayUtil)
if(WIN32) if(WIN32)
# Disable console window on Windows # Disable console window on Windows
# https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows # https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows
@ -26,49 +52,3 @@ endif()
if(APPLE) if(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
endif() endif()
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySDK ScreenPlayUtil)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
WebEngineCore
WebEngineQuick
WebChannel
Positioning)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt6::WebEngineCore
Qt6::WebEngineQuick)
else()
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
Quick
Gui
Widgets
WebSockets
Svg
WebEngine)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::WebSockets
Qt${QT_VERSION_MAJOR}::Svg
Qt5::WebEngine)
endif()

Some files were not shown because too many files have changed in this diff Show More