diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d88a0cf6..a27732a0 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ { "recommendations": [ - "sanaajani.taskrunnercode" + "sanaajani.taskrunnercode", + "delgan.qml-format" ] } \ No newline at end of file diff --git a/ScreenPlay/inc/public/ScreenPlay/installedlistfilter.h b/ScreenPlay/inc/public/ScreenPlay/installedlistfilter.h index 234e1918..c4c77cd1 100644 --- a/ScreenPlay/inc/public/ScreenPlay/installedlistfilter.h +++ b/ScreenPlay/inc/public/ScreenPlay/installedlistfilter.h @@ -14,7 +14,7 @@ namespace ScreenPlay { class InstalledListFilter : public QSortFilterProxyModel { Q_OBJECT QML_UNCREATABLE("") - + public: InstalledListFilter(const std::shared_ptr& ilm); diff --git a/ScreenPlay/qml/Create/Create.qml b/ScreenPlay/qml/Create/Create.qml index f9c9c296..849ce0ca 100644 --- a/ScreenPlay/qml/Create/Create.qml +++ b/ScreenPlay/qml/Create/Create.qml @@ -14,7 +14,7 @@ Item { property Item modalSource - Component.onCompleted: { + StackView.onActivated: { wizardContentWrapper.state = "in"; stackView.push("qrc:/qml/ScreenPlayApp/qml/Create/StartInfo.qml"); } diff --git a/ScreenPlay/qml/Installed/Installed.qml b/ScreenPlay/qml/Installed/Installed.qml index 8a3aca5e..50499a30 100644 --- a/ScreenPlay/qml/Installed/Installed.qml +++ b/ScreenPlay/qml/Installed/Installed.qml @@ -39,7 +39,7 @@ Item { } } - Component.onCompleted: { + StackView.onActivated: { navWrapper.state = "in"; App.installedListFilter.sortBySearchType(SearchType.All); checkIsContentInstalled(); diff --git a/ScreenPlay/qml/Settings/Settings.qml b/ScreenPlay/qml/Settings/Settings.qml index 2fbf8e91..e6e6a1e4 100644 --- a/ScreenPlay/qml/Settings/Settings.qml +++ b/ScreenPlay/qml/Settings/Settings.qml @@ -76,19 +76,6 @@ Item { SettingsHorizontalSeperator { } - SettingBool { - headline: qsTr("High priority Autostart") - available: false - description: qsTr("This options grants ScreenPlay a higher autostart priority than other apps.") - isChecked: App.settings.highPriorityStart - onCheckboxChanged: { - App.settings.setHighPriorityStart(checked); - } - } - - SettingsHorizontalSeperator { - } - SettingBool { height: 70 headline: qsTr("Send anonymous crash reports and statistics") @@ -240,7 +227,7 @@ Item { header: SettingsHeader { id: headerPerformance - text: qsTr("Performance") + text: qsTr("Wallpaper and Widgets") image: "qrc:/qml/ScreenPlayApp/assets/icons/icon_build.svg" } @@ -249,22 +236,10 @@ Item { anchors.margins: 20 spacing: 20 - SettingBool { - headline: qsTr("Pause wallpaper video rendering while another app is in the foreground") - description: qsTr("We disable the video rendering (not the audio!) for the best performance. If you have problem you can disable this behaviour here. Wallpaper restart required!") - isChecked: App.settings.checkWallpaperVisible - onCheckboxChanged: function (checked) { - App.settings.setCheckWallpaperVisible(checked); - } - } - - SettingsHorizontalSeperator { - } - SettingsComboBox { id: cbVideoFillMode - headline: qsTr("Default Fill Mode") + headline: qsTr("Default Wallpaper Fill Mode") description: qsTr("Set this property to define how the video is scaled to fit the target area.") Component.onCompleted: { cbVideoFillMode.comboBox.currentIndex = root.indexOfValue(cbVideoFillMode.comboBox.model, App.settings.videoFillMode); diff --git a/ScreenPlaySysInfo/CMakeLists.txt b/ScreenPlaySysInfo/CMakeLists.txt index 862bf6be..78483208 100644 --- a/ScreenPlaySysInfo/CMakeLists.txt +++ b/ScreenPlaySysInfo/CMakeLists.txt @@ -24,6 +24,7 @@ set(QML_PLUGIN_SOURCES src/ipaddress.cpp src/ram.cpp src/storage.cpp + src/audiolevel.cpp src/sysinfo.cpp src/uptime.cpp) @@ -35,6 +36,7 @@ set(QML_PLUGIN_HEADER src/mathhelper.h src/ram.h src/storage.h + src/audiolevel.h src/sysinfo.h src/uptime.h) @@ -43,7 +45,8 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick infoware) target_include_directories(${PROJECT_NAME} PUBLIC src/) if(WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE ole32.lib winmm.lib) + find_package(wil CONFIG REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE ole32.lib winmm.lib WIL::WIL) endif() qt_add_qml_module( diff --git a/ScreenPlaySysInfo/qml/TestMain.qml b/ScreenPlaySysInfo/qml/TestMain.qml index d7cccd17..94bbc46f 100644 --- a/ScreenPlaySysInfo/qml/TestMain.qml +++ b/ScreenPlaySysInfo/qml/TestMain.qml @@ -16,6 +16,10 @@ Window { property string fontFamily: "Arial" property int fontPointSize: 14 + AudioLevel { + id: audioLevel + } + SysInfo { id: sysInfo } diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/contenttypes.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/contenttypes.h index 46f6ed54..8ccccd41 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/contenttypes.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/contenttypes.h @@ -1,8 +1,8 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #pragma once -#include - +#include +#include namespace ScreenPlay { /*! \namespace ScreenPlay::SearchType diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 8abf4ad5..a06f5ef6 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -20,7 +20,7 @@ ScreenPlay::WallpaperExitCode MacWindow::start() // OSX Development workaround: // This folder needs then to be copied into the .app/Contents/MacOS/ // for the deploy version. - m_window.engine()->addImportPath(QGuiApplication::instance()->applicationDirPath()+ "/qml"); + m_window.engine()->addImportPath(QGuiApplication::instance()->applicationDirPath() + "/qml"); // WARNING: Setting Window flags must be called *here*! Qt::WindowFlags flags = m_window.flags(); diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index 2a14a425..8253b13c 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) // If we start with only one argument (path, appID, type), // it means we want to test a single widget if (argumentList.length() == 1) { - //WidgetWindow spwmw("test", "appid", "qmlWidget", { 100, 100 }, true); + // WidgetWindow spwmw("test", "appid", "qmlWidget", { 100, 100 }, true); QString exampleContentPath = QString(SCREENPLAY_SOURCE_DIR) + "/Content"; QStringList contentFolder = { diff --git a/ScreenPlayWorkshop/CMakeLists.txt b/ScreenPlayWorkshop/CMakeLists.txt index b7981fa6..5140f144 100644 --- a/ScreenPlayWorkshop/CMakeLists.txt +++ b/ScreenPlayWorkshop/CMakeLists.txt @@ -10,11 +10,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package( Qt6 - COMPONENTS Core Quick QuickControls2 + COMPONENTS Core Quick QuickControls2 QuickTest REQUIRED) set(QML # cmake-format: sort + qml/tests/tst_profile.qml qml/Background.qml qml/Forum.qml qml/Navigation.qml @@ -41,6 +42,7 @@ set(SOURCES src/steamaccount.cpp src/steamapiwrapper.cpp src/steamqmlimageprovider.cpp + src/steamprofilepicture.cpp src/steamworkshop.cpp src/steamworkshopitem.cpp src/steamworkshoplistmodel.cpp) @@ -52,6 +54,7 @@ set(HEADER src/steamaccount.h src/steamapiwrapper.h src/steamqmlimageprovider.h + src/steamprofilepicture.h src/steamworkshop.h src/steamworkshopitem.h src/steamworkshoplistmodel.h @@ -142,5 +145,16 @@ if(${SCREENPLAY_STEAM}) ScreenPlayUtilplugin SteamSDK SteamSDKQtEnums) - endif() + + qt_add_executable(tst_ScreenPlayWorkshop_QTest src/QuickTestMain.cpp) + target_link_libraries( + tst_ScreenPlayWorkshop_QTest + PRIVATE Qt6::Quick + Qt6::QuickControls2 + Qt6::QuickTest + ${PROJECT_NAME}plugin + ScreenPlayUtilplugin + SteamSDK + SteamSDKQtEnums) +endif() endif() diff --git a/ScreenPlayWorkshop/qml/PopupOffline.qml b/ScreenPlayWorkshop/qml/PopupOffline.qml index 37dffd11..3ae03910 100644 --- a/ScreenPlayWorkshop/qml/PopupOffline.qml +++ b/ScreenPlayWorkshop/qml/PopupOffline.qml @@ -5,8 +5,6 @@ import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects import ScreenPlayWorkshop import ScreenPlayUtil -import ScreenPlayApp -import ScreenPlay Popup { id: root diff --git a/ScreenPlayWorkshop/qml/SteamProfile.qml b/ScreenPlayWorkshop/qml/SteamProfile.qml index b3124897..09a15d60 100644 --- a/ScreenPlayWorkshop/qml/SteamProfile.qml +++ b/ScreenPlayWorkshop/qml/SteamProfile.qml @@ -8,12 +8,12 @@ import "upload/" Item { id: root + objectName: "WorkshopProfilePage" property ScreenPlayWorkshop screenPlayWorkshop property SteamWorkshop steamWorkshop - - signal requestBack - Component.onCompleted: steamWorkshop.requestUserItems() + property StackView stackView + StackView.onActivated: steamWorkshop.requestUserItems() Flickable { id: scrollView @@ -39,28 +39,11 @@ Item { verticalCenter: parent.verticalCenter } spacing: 20 - SteamImage { + SteamProfilePicture { id: avatar width: 70 height: 70 - Component.onCompleted: { - root.steamWorkshop.steamAccount.loadAvatar(); - } - - Connections { - function onAvatarChanged(_avatar) { - avatar.setImage(_avatar); - avatarPlaceholder.opacity = 0; - } - - target: root.steamWorkshop.steamAccount - } - Image { - id: avatarPlaceholder - anchors.fill: parent - source: "qrc:/qml/ScreenPlayWorkshop/assets/images/steam_default_avatar.png" - } } Text { @@ -71,7 +54,9 @@ Item { Button { text: qsTr("Back") - onClicked: root.requestBack() + onClicked: { + stackView.pop(); + } } } } diff --git a/ScreenPlayWorkshop/qml/SteamWorkshop.qml b/ScreenPlayWorkshop/qml/SteamWorkshop.qml index ae1bf12e..9b808137 100644 --- a/ScreenPlayWorkshop/qml/SteamWorkshop.qml +++ b/ScreenPlayWorkshop/qml/SteamWorkshop.qml @@ -44,15 +44,6 @@ Item { StackView { id: stackView property int duration: 300 - - Connections { - target: stackView.currentItem - ignoreUnknownSignals: true - function onRequestBack() { - stackView.pop(); - } - } - anchors.fill: parent replaceEnter: Transition { OpacityAnimator { diff --git a/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml b/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml index e530ab31..b2ea7101 100644 --- a/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml +++ b/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml @@ -15,7 +15,7 @@ Item { property SteamWorkshop steamWorkshop property Background background - Component.onCompleted: { + StackView.onActivated: { root.state = "searching"; root.steamWorkshop.searchWorkshopByText(""); } @@ -239,6 +239,7 @@ Item { Button { id: btnSteamProfile + objectName: "btnSteamProfile" anchors { verticalCenter: parent.verticalCenter @@ -251,7 +252,8 @@ Item { onClicked: { stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/SteamProfile.qml", { "screenPlayWorkshop": root.screenPlayWorkshop, - "steamWorkshop": root.steamWorkshop + "steamWorkshop": root.steamWorkshop, + "stackView": root.stackView }); } } @@ -270,7 +272,8 @@ Item { onClicked: { stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/upload/UploadProject.qml", { "screenPlayWorkshop": root.screenPlayWorkshop, - "steamWorkshop": root.steamWorkshop + "steamWorkshop": root.steamWorkshop, + "stackView": root.stackView }); } } @@ -287,43 +290,44 @@ Item { leftMargin: 20 verticalCenter: parent.verticalCenter } - ToolButton { - icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_search.svg" - onClicked: { - root.state = "searching"; - root.steamWorkshop.searchWorkshopByText(tiSearch.text); - } - icon.width: 20 - icon.height: 20 - anchors { - left: parent.left - leftMargin: -3 - bottom: parent.bottom - bottomMargin: 3 - } - } TextField { id: tiSearch placeholderTextColor: Material.secondaryTextColor placeholderText: qsTr("Search for Wallpaper and Widgets...") - // WORKAROUND: - // onEditingFinished causes internal qml layout crash in Qt 6.4 Keys.onReturnPressed: event => { event.accepted = true; + tiSearch.searchWorkshop(); + } + + // WORKAROUND: + // onEditingFinished causes internal qml layout crash in Qt 6.4 + Timer { + id: timer + interval: 300 + repeat: false + onTriggered: tiSearch.searchWorkshop() + } + + onTextEdited: timer.restart() + function searchWorkshop() { if (root.state === "searching") { print("SEARCHING"); return; } root.state = "searching"; print("EDITING FINISHED", root.state); - if (tiSearch.text === "") - return root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); - root.steamWorkshop.searchWorkshopByText(tiSearch.text); + if (tiSearch.text === "") { + Qt.callLater(function () { + root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); + }); + return; + } + Qt.callLater(function () { + root.steamWorkshop.searchWorkshopByText(tiSearch.text); + }); } - leftInset: -20 - leftPadding: 20 anchors { top: parent.top right: parent.right @@ -333,20 +337,29 @@ Item { } } ToolButton { - icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_close.svg" + property bool hasContent: tiSearch.text.length > 0 + icon.source: hasContent ? "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_close.svg" : "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_search.svg" onClicked: { + if (hasContent) { + root.state = "searching"; + tiSearch.clear(); + Qt.callLater(function () { + root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); + }); + return; + } root.state = "searching"; - tiSearch.text = ""; - root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); + Qt.callLater(function () { + root.steamWorkshop.searchWorkshopByText(tiSearch.text); + }); } - enabled: tiSearch.text !== "" icon.width: 20 icon.height: 20 anchors { right: parent.right - rightMargin: -3 + rightMargin: 0 bottom: parent.bottom - bottomMargin: 3 + bottomMargin: 0 } } } diff --git a/ScreenPlayWorkshop/qml/TestMain.qml b/ScreenPlayWorkshop/qml/TestMain.qml index d91939b2..fcded756 100644 --- a/ScreenPlayWorkshop/qml/TestMain.qml +++ b/ScreenPlayWorkshop/qml/TestMain.qml @@ -3,6 +3,7 @@ import QtQuick.Layouts import QtQuick.Controls import QtQuick.Controls.Material import ScreenPlayWorkshop +import QtTest Window { id: root @@ -14,6 +15,7 @@ Window { root.Material.theme = Material.Dark; } + ScreenPlayWorkshop { id: screenPlayWorkshop Component.onCompleted: { diff --git a/ScreenPlayWorkshop/qml/upload/UploadProject.qml b/ScreenPlayWorkshop/qml/upload/UploadProject.qml index 97f37d72..9dda758b 100644 --- a/ScreenPlayWorkshop/qml/upload/UploadProject.qml +++ b/ScreenPlayWorkshop/qml/upload/UploadProject.qml @@ -9,8 +9,7 @@ Item { property ScreenPlayWorkshop screenPlayWorkshop property SteamWorkshop steamWorkshop - - signal requestBack + property StackView stackView Item { id: headerWrapper @@ -109,7 +108,7 @@ Item { text: qsTr("Abort") onClicked: { - root.requestBack(); + stackView.pop(); } anchors { diff --git a/ScreenPlayWorkshop/src/steamaccount.cpp b/ScreenPlayWorkshop/src/steamaccount.cpp index 2f625512..d8ac8030 100644 --- a/ScreenPlayWorkshop/src/steamaccount.cpp +++ b/ScreenPlayWorkshop/src/steamaccount.cpp @@ -14,6 +14,9 @@ SteamAccount::SteamAccount(QObject* parent) void SteamAccount::loadAvatar() { + if (!m_avatar.isNull()) { + return; + } int largeFriendAvatarHandle = SteamFriends()->GetLargeFriendAvatar(m_steamID); // Returns 0 if no avatar is set for the user. @@ -43,40 +46,33 @@ void SteamAccount::loadAmountSubscribedItems() void SteamAccount::onAvatarImageLoaded(AvatarImageLoaded_t* avatarImage) { - // If called from another steam app if (m_avatarLoaded) return; const int largeFriendAvatarHandle = SteamFriends()->GetLargeFriendAvatar(m_steamID); if (largeFriendAvatarHandle <= 0) { - qWarning() << "onAvatarImageLoaded: getLargeFriendAvatarResult retunred: " << largeFriendAvatarHandle; + qWarning() << "onAvatarImageLoaded: GetLargeFriendAvatar returned: " << largeFriendAvatarHandle; return; } uint32 width = 0; uint32 height = 0; - if (!SteamUtils()->GetImageSize(avatarImage->m_iImage, &width, &height)) { - qWarning() << "Failed GetImageSize"; + const bool sizeRetrieved = SteamUtils()->GetImageSize(avatarImage->m_iImage, &width, &height); + if (!sizeRetrieved) { + qWarning() << "onAvatarImageLoaded: Failed to get image size"; return; } - const int size = width * height * 4; - QVector imageData; - imageData.resize(size); - - if (!SteamUtils()->GetImageRGBA(avatarImage->m_iImage, imageData.data(), size)) { - qWarning() << "Failed to load image buffer from callback"; + const int imageSize = width * height * 4; + QVector imageData(imageSize); + const bool imageRetrieved = SteamUtils()->GetImageRGBA(avatarImage->m_iImage, imageData.data(), imageSize); + if (!imageRetrieved) { + qWarning() << "onAvatarImageLoaded: Failed to load image buffer from callback"; return; } - QImage avatar { - imageData.data(), - static_cast(width), - static_cast(height), - QImage::Format_RGBA8888 - }; - + const QImage avatar { imageData.data(), static_cast(width), static_cast(height), QImage::Format_RGBA8888 }; setAvatar(avatar); m_avatarLoaded = true; } diff --git a/ScreenPlayWorkshop/src/steamapiwrapper.cpp b/ScreenPlayWorkshop/src/steamapiwrapper.cpp index eace7533..6f214f24 100644 --- a/ScreenPlayWorkshop/src/steamapiwrapper.cpp +++ b/ScreenPlayWorkshop/src/steamapiwrapper.cpp @@ -11,17 +11,16 @@ #include "steamapiwrapper.h" namespace SteamApiWrapper { -bool setItemTags(const QVariant& updateHandle, const QStringList tags) +bool setItemTags(const QVariant& updateHandle, const QStringList& tags) { - SteamParamStringArray_t* pTags = new SteamParamStringArray_t(); - const uint32 strCount = tags.size(); - pTags->m_ppStrings = new const char*[strCount]; - pTags->m_nNumStrings = strCount; - for (uint32 i = 0; i < strCount; i++) { - pTags->m_ppStrings[i] = tags.at(i).toUtf8().data(); + auto pTags = std::make_unique(); + const uint32_t numTags = tags.size(); + pTags->m_nNumStrings = numTags; + auto tagStrings = std::make_unique(numTags); + for (uint32_t i = 0; i < numTags; ++i) { + tagStrings[i] = tags.at(i).toUtf8().constData(); } - - return SteamUGC()->SetItemTags(updateHandle.toULongLong(), pTags); + pTags->m_ppStrings = tagStrings.get(); + return SteamUGC()->SetItemTags(updateHandle.toULongLong(), pTags.get()); } - } diff --git a/ScreenPlayWorkshop/src/steamworkshopitem.cpp b/ScreenPlayWorkshop/src/steamworkshopitem.cpp index 10cf4c93..5b5b4e3e 100644 --- a/ScreenPlayWorkshop/src/steamworkshopitem.cpp +++ b/ScreenPlayWorkshop/src/steamworkshopitem.cpp @@ -37,9 +37,14 @@ void SteamWorkshopItem::checkUploadProgress() if (progress > 0.0f && progress < 1.0f) setUploadProgress((progress * 100)); } - void SteamWorkshopItem::uploadItemToWorkshop(CreateItemResult_t* pCallback, bool bIOFailure) { + if (!pCallback) { + qWarning() << "Invalid CreateItemResult_t pointer"; + emit removeThis(this); + return; + } + if (pCallback->m_bUserNeedsToAcceptWorkshopLegalAgreement) { emit userNeedsToAcceptWorkshopLegalAgreement(); } @@ -87,7 +92,7 @@ void SteamWorkshopItem::uploadItemToWorkshop(CreateItemResult_t* pCallback, bool QString youtube; if (jsonObject.contains("youtube")) { - language = jsonObject.value("youtube").toString(); + youtube = jsonObject.value("youtube").toString(); } if (!youtube.isEmpty()) { @@ -132,21 +137,21 @@ void SteamWorkshopItem::uploadItemToWorkshop(CreateItemResult_t* pCallback, bool m_UGCUpdateHandle = SteamUGC()->StartItemUpdate(m_appID, pCallback->m_nPublishedFileId); - QVector tagByteArray; + QVector tagCharArray; for (const auto& tag : tags) { if (tag.length() > 255) { - qInfo() << "Skip to long tag (max 255) " << tag << " with length:" << tag.length(); + qInfo() << "Skip too long tag (max 255):" << tag; continue; } - tagByteArray.append(tag.toUtf8()); - pTags->m_ppStrings[i] = tagByteArray.at(i).data(); - qInfo() << tag.toStdString().c_str() << pTags->m_ppStrings[i]; - i++; + tagCharArray.append(tag.toUtf8()); } - pTags->m_nNumStrings = count; - bool success = SteamUGC()->SetItemTags(m_UGCUpdateHandle, pTags); - qInfo() << "SetItemTags" << success; + pTags->m_nNumStrings = tagCharArray.count(); + pTags->m_ppStrings = tagCharArray.data(); + bool success = SteamUGC()->SetItemTags(m_UGCUpdateHandle, pTags); + if (!success) { + qWarning() << "Failed to set item tags"; + } SteamUGC()->AddItemPreviewFile(m_UGCUpdateHandle, QByteArray(preview.toUtf8()).data(), EItemPreviewType::k_EItemPreviewType_Image); SteamUGC()->SetItemTitle(m_UGCUpdateHandle, QByteArray(title.toUtf8().data())); SteamUGC()->SetItemDescription(m_UGCUpdateHandle, QByteArray(description.toUtf8()).data()); @@ -159,6 +164,11 @@ void SteamWorkshopItem::uploadItemToWorkshop(CreateItemResult_t* pCallback, bool saveWorkshopID(); SteamAPICall_t apicall = SteamUGC()->SubmitItemUpdate(m_UGCUpdateHandle, nullptr); + if (apicall == k_uAPICallInvalid) { + qWarning() << "Failed to submit item update"; + return; + } + m_submitItemUpdateResultResult.Set(apicall, this, &SteamWorkshopItem::submitItemUpdateStatus); m_updateTimer.start(m_updateTimerInterval); } diff --git a/ScreenPlayWorkshop/src/uploadlistmodel.h b/ScreenPlayWorkshop/src/uploadlistmodel.h index e05a4946..238b511c 100644 --- a/ScreenPlayWorkshop/src/uploadlistmodel.h +++ b/ScreenPlayWorkshop/src/uploadlistmodel.h @@ -94,37 +94,39 @@ public slots: m_uploadListModelItems.clear(); endResetModel(); } - void append(const QString& name, const QString& path, const quint64 appID) { auto item = std::make_unique(name, path, appID); + + const auto roles = QVector { + static_cast(UploadListModelRole::UploadProgressRole), + static_cast(UploadListModelRole::NameRole), + static_cast(UploadListModelRole::AbsolutePreviewImagePath), + static_cast(UploadListModelRole::Status) + }; + + const auto onDataChanged = [&]() { + emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), roles); + }; + QObject::connect(item.get(), &SteamWorkshopItem::userNeedsToAcceptWorkshopLegalAgreement, this, &UploadListModel::userNeedsToAcceptWorkshopLegalAgreement); + QObject::connect(item.get(), &SteamWorkshopItem::uploadProgressChanged, this, onDataChanged); + QObject::connect(item.get(), &SteamWorkshopItem::nameChanged, this, onDataChanged); + QObject::connect(item.get(), &SteamWorkshopItem::absolutePreviewImagePathChanged, this, onDataChanged); + QObject::connect(item.get(), &SteamWorkshopItem::uploadComplete, this, [=](bool successful) { + onDataChanged(); + }); + QObject::connect(item.get(), &SteamWorkshopItem::statusChanged, this, [=](ScreenPlayWorkshopSteamEnums::EResult status) { + onDataChanged(); - QObject::connect(item.get(), &SteamWorkshopItem::uploadProgressChanged, this, [this]() { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::UploadProgressRole) }); - }); - QObject::connect(item.get(), &SteamWorkshopItem::nameChanged, this, [this]() { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::NameRole) }); - }); - QObject::connect(item.get(), &SteamWorkshopItem::absolutePreviewImagePathChanged, this, [this]() { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); - }); - QObject::connect(item.get(), &SteamWorkshopItem::uploadComplete, this, [this](bool successful) { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::AbsolutePreviewImagePath) }); - }); - QObject::connect(item.get(), &SteamWorkshopItem::statusChanged, this, [this](ScreenPlayWorkshopSteamEnums::EResult status) { - emit this->dataChanged(index(0, 0), index(rowCount() - 1, 0), QVector { static_cast(UploadListModelRole::Status) }); + bool allItemsUploaded = std::all_of(m_uploadListModelItems.cbegin(), m_uploadListModelItems.cend(), [](const auto& item) { + const auto status = item->status(); + return status == ScreenPlayWorkshopSteamEnums::EResult::K_EResultOK || status == ScreenPlayWorkshopSteamEnums::EResult::K_EResultFail; + }); - // Check if all items are - - for (const auto& item : m_uploadListModelItems) { - qDebug() << "item->status() " << item->status(); - if (!(item->status() != ScreenPlayWorkshopSteamEnums::EResult::K_EResultOK - || item->status() != ScreenPlayWorkshopSteamEnums::EResult::K_EResultFail)) { - return; - } + if (allItemsUploaded) { + emit this->uploadCompleted(); } - emit this->uploadCompleted(); }); beginInsertRows(QModelIndex(), rowCount(), rowCount()); diff --git a/Tools/chocolatey/ScreenPlay/ReadMe.md b/Tools/chocolatey/ScreenPlay/ReadMe.md index 7da71fcb..3a2242fc 100644 --- a/Tools/chocolatey/ScreenPlay/ReadMe.md +++ b/Tools/chocolatey/ScreenPlay/ReadMe.md @@ -7,7 +7,7 @@ choco pack Install the generated nupkg: ``` -choco install screenplay.0.15.0-RC5.nupkg -dv -s . +choco install screenplay.0.15.0-RC6.nupkg -dv -s . ``` Set api key from [https://community.chocolatey.org/account](https://community.chocolatey.org/account): @@ -17,5 +17,5 @@ choco apikey --key AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAA --source https://push.chocol Psuh: ``` -choco push screenplay.0.15.0-RC5.nupkg --source https://push.chocolatey.org/ +choco push screenplay.0.15.0-RC6.nupkg --source https://push.chocolatey.org/ ``` \ No newline at end of file diff --git a/Tools/chocolatey/ScreenPlay/screenplay.nuspec b/Tools/chocolatey/ScreenPlay/screenplay.nuspec index e5150208..dcf58fa8 100644 --- a/Tools/chocolatey/ScreenPlay/screenplay.nuspec +++ b/Tools/chocolatey/ScreenPlay/screenplay.nuspec @@ -26,7 +26,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe - 0.15.0-RC5 + 0.15.0-RC6 https://gitlab.com/kelteseth/ScreenPlay/-/tree/master/Tools/chocolatey/ScreenPlay Elias Steurer diff --git a/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 b/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 index 4c0c93ef..438e9382 100644 --- a/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 +++ b/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 @@ -2,7 +2,7 @@ $ErrorActionPreference = 'Stop'; $toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" $url = '' -$url64 = 'https://kelteseth.com/releases/0.15.0-RC5/ScreenPlay-0.15.0-RC5-x64-windows-release.zip' +$url64 = 'https://kelteseth.com/releases/0.15.0-RC6/ScreenPlay-0.15.0-RC6-x64-windows-release.zip' $packageArgs = @{ packageName = $env:ChocolateyPackageName diff --git a/Tools/defines.py b/Tools/defines.py index 12d06511..6a714d3d 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -20,10 +20,10 @@ elif sys.platform == "linux": SCREENPLAY_VERSION = "0.15.0-RC6" QT_PATH = path = Path(os.path.join(os.path.realpath(__file__), "../../../aqt")).resolve() -QT_VERSION = "6.5.0" +QT_VERSION = "6.6.0" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") QT_IFW_VERSION = "4.5" -VCPKG_VERSION = "1cc9525" # Master 15.02.2023 +VCPKG_VERSION = "b81bc3a" # Master 25.03.2023 PYTHON_EXECUTABLE = "python" if sys.platform == "win32" else "python3" FFMPEG_VERSION = "5.0.1" diff --git a/Tools/setup.py b/Tools/setup.py index a7e5049a..3b093099 100755 --- a/Tools/setup.py +++ b/Tools/setup.py @@ -117,6 +117,7 @@ def main(): vcpkg_command = "vcpkg.exe" vcpkg_packages_list.append("infoware[d3d]") vcpkg_packages_list.append("sentry-native[transport]") + vcpkg_packages_list.append("wil") platform_command = commands_list() platform_command.add("bootstrap-vcpkg.bat", vcpkg_path, False) vcpkg_triplet = ["x64-windows"]