diff --git a/vkconfig_core/configurator.cpp b/vkconfig_core/configurator.cpp index 2c27691622..6e336f42d8 100644 --- a/vkconfig_core/configurator.cpp +++ b/vkconfig_core/configurator.cpp @@ -824,8 +824,12 @@ bool Configurator::Load() { const QJsonObject& json_object = json_interface_object.value(GetToken(TAB_PREFERENCES)).toObject(); this->use_layer_dev_mode = json_object.value("use_layer_dev_mode").toBool(); + this->latest_sdk_version = Version(json_object.value("latest_sdk_version").toString().toStdString().c_str()); this->use_system_tray = json_object.value("use_system_tray").toBool(); ::SetHomePath(json_object.value("VK_HOME").toString().toStdString()); + if (json_object.value("VK_DOWNLOAD") != QJsonValue::Undefined) { + ::SetDownloadPath(json_object.value("VK_DOWNLOAD").toString().toStdString()); + } } this->executables.Load(json_root_object); @@ -873,7 +877,9 @@ bool Configurator::Save() const { QJsonObject json_object; json_object.insert("use_system_tray", this->use_system_tray); json_object.insert("use_layer_dev_mode", this->use_layer_dev_mode); + json_object.insert("latest_sdk_version", this->latest_sdk_version.str().c_str()); json_object.insert("VK_HOME", ::Path(Path::HOME).RelativePath().c_str()); + json_object.insert("VK_DOWNLOAD", ::Path(Path::DOWNLOAD).RelativePath().c_str()); json_interface_object.insert(GetToken(TAB_PREFERENCES), json_object); } diff --git a/vkconfig_core/configurator.h b/vkconfig_core/configurator.h index 0e30166b7f..6f451e2152 100644 --- a/vkconfig_core/configurator.h +++ b/vkconfig_core/configurator.h @@ -136,6 +136,8 @@ class Configurator { TabType active_tab = TAB_CONFIGURATIONS; bool advanced = true; Path last_path_status = Path(Path::HOME).RelativePath() + "/vkconfig.txt"; + Version latest_sdk_version = Version::VKHEADER; + Version online_sdk_version = Version::NONE; private: int hide_message_boxes_flags = 0; diff --git a/vkconfig_core/path.cpp b/vkconfig_core/path.cpp index 7970bdc8b1..f950041da3 100644 --- a/vkconfig_core/path.cpp +++ b/vkconfig_core/path.cpp @@ -38,9 +38,10 @@ struct BuiltinDesc { const Path::Builtin path; }; -static const BuiltinDesc VARIABLES[] = { - {"${VK_HOME}", Path::HOME}, {"${VK_APPDATA}", Path::APPDATA}, {"${VULKAN_BIN}", Path::BIN}, - {"${VULKAN_SDK}", Path::SDK}, {"${VULKAN_PROFILES}", Path::PROFILES}, {"${VULKAN_CONTENT}", Path::CONTENT}}; +static const BuiltinDesc VARIABLES[] = {{"${VK_HOME}", Path::HOME}, {"${VK_DOWNLOAD}", Path::DOWNLOAD}, + {"${VK_APPDATA}", Path::APPDATA}, {"${VULKAN_BIN}", Path::BIN}, + {"${VULKAN_SDK}", Path::SDK}, {"${VULKAN_PROFILES}", Path::PROFILES}, + {"${VULKAN_CONTENT}", Path::CONTENT}}; static std::string ConvertSeparators(const std::string& path, const char* native_separator, const char* alien_separator) { const std::size_t native_separator_size = std::strlen(native_separator); @@ -74,13 +75,13 @@ static std::string ConvertSeparators(const std::string& path, const char* native return current_path; } -static const char* GetNativeSeparator() { +const char* Path::Separator() { static const char* native_separator = VKC_ENV == VKC_ENV_WIN32 ? "\\" : "/"; return native_separator; } static std::string ConvertNativeSeparators(const std::string& path) { - const char* native_separator = GetNativeSeparator(); + const char* native_separator = Path::Separator(); const char* alien_separator = VKC_ENV != VKC_ENV_WIN32 ? "\\" : "/"; return ConvertSeparators(path, native_separator, alien_separator); @@ -247,6 +248,20 @@ static const std::string GetHomeDir() { return absolute_path; } +static std::string VK_CURRENT_DOWNLOAD_PATH = GetDefaultHomeDir() + "/Releases"; + +void SetDownloadPath(const std::string& path) { ::VK_CURRENT_DOWNLOAD_PATH = path; } + +static const std::string GetDownloadDir() { + std::string absolute_path = qgetenv("VK_DOWNLOAD").toStdString(); + + if (absolute_path.empty()) { // Default path + absolute_path = VK_CURRENT_DOWNLOAD_PATH; + } + + return absolute_path; +} + static const std::string GetAppDataDir() { const char* TABLE[] = { "/AppData/Local/LunarG", // ENVIRONMENT_WIN32 @@ -392,6 +407,9 @@ Path::Path(Path::Builtin path) { case HOME: this->data = ::GetHomeDir(); break; + case DOWNLOAD: + this->data = ::GetDownloadDir(); + break; case DEFAULT_HOME: this->data = ::GetDefaultHomeDir(); break; diff --git a/vkconfig_core/path.h b/vkconfig_core/path.h index ec1e5bef5f..22076e4034 100644 --- a/vkconfig_core/path.h +++ b/vkconfig_core/path.h @@ -28,6 +28,7 @@ class Path { public: enum Builtin { HOME, // Vulkan SDK user directory + DOWNLOAD, DEFAULT_HOME, APPDATA, INIT, @@ -69,6 +70,8 @@ class Path { bool Empty() const { return this->data.empty(); } + static const char* Separator(); + private: std::string data; @@ -85,6 +88,8 @@ bool operator<(const Path& a, const Path& b); void SetHomePath(const std::string& path); +void SetDownloadPath(const std::string& path); + std::vector CollectFilePaths(const Path& directory, const char* filter = "*json"); std::vector CollectProfileNamesFromFile(const Path& profile_path); diff --git a/vkconfig_core/test/test_version.cpp b/vkconfig_core/test/test_version.cpp index 82ce0cf46d..609d5ac646 100644 --- a/vkconfig_core/test/test_version.cpp +++ b/vkconfig_core/test/test_version.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020-2021 Valve Corporation - * Copyright (c) 2020-2021 LunarG, Inc. + * Copyright (c) 2020-2025 Valve Corporation + * Copyright (c) 2020-2025 LunarG, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,17 +27,148 @@ TEST(test_version, string) { const std::string version_a("1.1.130"); const std::string version_b("1.2.145"); + const std::string version_c("1.3.298.0"); + const std::string version_d("1.4"); EXPECT_EQ(version_a, Version(version_a.c_str()).str()); EXPECT_EQ(version_b, Version(version_b.c_str()).str()); + EXPECT_EQ(version_c, Version(version_c.c_str()).str()); + EXPECT_EQ(version_d, Version(version_d.c_str()).str()); } -TEST(test_version, string_ctr) { EXPECT_EQ(Version(1, 1, 130), Version("1.1.130")); } +TEST(test_version, string_ctr) { + EXPECT_EQ(Version(2, 0), Version("2")); + EXPECT_EQ(Version(1, 4), Version("1.4")); + EXPECT_EQ(Version(1, 1, 130), Version("1.1.130")); + EXPECT_EQ(Version(1, 4, 304, 1), Version("1.4.304.1")); +} -TEST(test_version, compare) { - const std::string version_a("1.1.130"); - const std::string version_b("1.2.135"); - const std::string version_c("1.2.145"); +TEST(test_version, compare_2) { + const Version version_a("1.1"); + const Version version_b("1.2"); + const Version version_c("2.0"); + const Version version_d("2.1"); + + EXPECT_TRUE(version_a == version_a); + EXPECT_TRUE(version_b == version_b); + EXPECT_TRUE(version_c == version_c); + + EXPECT_TRUE(version_a != version_b); + EXPECT_TRUE(version_b != version_c); + EXPECT_TRUE(version_a != version_c); + EXPECT_TRUE(version_a != version_d); + + EXPECT_TRUE(version_a < version_b); + EXPECT_TRUE(version_b < version_c); + EXPECT_TRUE(version_a < version_c); + EXPECT_TRUE(version_a < version_d); + + EXPECT_TRUE(version_a <= version_a); + EXPECT_TRUE(version_b <= version_b); + EXPECT_TRUE(version_c <= version_c); + EXPECT_TRUE(version_d <= version_d); + + EXPECT_TRUE(version_a <= version_b); + EXPECT_TRUE(version_b <= version_c); + EXPECT_TRUE(version_b <= version_d); + EXPECT_TRUE(version_c <= version_d); + + EXPECT_TRUE(version_b > version_a); + EXPECT_TRUE(version_c > version_b); + EXPECT_TRUE(version_c > version_a); + EXPECT_TRUE(version_d > version_b); + + EXPECT_TRUE(version_a >= version_a); + EXPECT_TRUE(version_b >= version_b); + EXPECT_TRUE(version_c >= version_c); + EXPECT_TRUE(version_d >= version_d); + + EXPECT_TRUE(version_b >= version_a); + EXPECT_TRUE(version_c >= version_b); + EXPECT_TRUE(version_c >= version_a); + EXPECT_TRUE(version_d >= version_b); +} + +TEST(test_version, compare_3) { + const Version version_a("1.1.130"); + const Version version_b("1.2.135"); + const Version version_c("1.2.145"); + + EXPECT_TRUE(version_a == version_a); + EXPECT_TRUE(version_b == version_b); + EXPECT_TRUE(version_c == version_c); + + EXPECT_TRUE(version_a != version_b); + EXPECT_TRUE(version_b != version_c); + EXPECT_TRUE(version_a != version_c); + + EXPECT_TRUE(version_a < version_b); + EXPECT_TRUE(version_b < version_c); + EXPECT_TRUE(version_a < version_c); + + EXPECT_TRUE(version_a <= version_a); + EXPECT_TRUE(version_b <= version_b); + EXPECT_TRUE(version_c <= version_c); + + EXPECT_TRUE(version_a <= version_b); + EXPECT_TRUE(version_b <= version_c); + EXPECT_TRUE(version_a <= version_c); + + EXPECT_TRUE(version_b > version_a); + EXPECT_TRUE(version_c > version_b); + EXPECT_TRUE(version_c > version_a); + + EXPECT_TRUE(version_a >= version_a); + EXPECT_TRUE(version_b >= version_b); + EXPECT_TRUE(version_c >= version_c); + + EXPECT_TRUE(version_b >= version_a); + EXPECT_TRUE(version_c >= version_b); + EXPECT_TRUE(version_c >= version_a); +} + +TEST(test_version, compare_4) { + const Version version_a("1.2.135.1"); + const Version version_b("1.2.145.0"); + const Version version_c("1.2.145.1"); + + EXPECT_TRUE(version_a == version_a); + EXPECT_TRUE(version_b == version_b); + EXPECT_TRUE(version_c == version_c); + + EXPECT_TRUE(version_a != version_b); + EXPECT_TRUE(version_b != version_c); + EXPECT_TRUE(version_a != version_c); + + EXPECT_TRUE(version_a < version_b); + EXPECT_TRUE(version_b < version_c); + EXPECT_TRUE(version_a < version_c); + + EXPECT_TRUE(version_a <= version_a); + EXPECT_TRUE(version_b <= version_b); + EXPECT_TRUE(version_c <= version_c); + + EXPECT_TRUE(version_a <= version_b); + EXPECT_TRUE(version_b <= version_c); + EXPECT_TRUE(version_a <= version_c); + + EXPECT_TRUE(version_b > version_a); + EXPECT_TRUE(version_c > version_b); + EXPECT_TRUE(version_c > version_a); + + EXPECT_TRUE(version_a >= version_a); + EXPECT_TRUE(version_b >= version_b); + EXPECT_TRUE(version_c >= version_c); + + EXPECT_TRUE(version_b >= version_a); + EXPECT_TRUE(version_c >= version_b); + EXPECT_TRUE(version_c >= version_a); +} + +TEST(test_version, compare_mix) { + const Version version_a("1.1"); + const Version version_b("1.1.135"); + const Version version_c("1.1.135.1"); EXPECT_TRUE(version_a == version_a); EXPECT_TRUE(version_b == version_b); diff --git a/vkconfig_core/type_platform.cpp b/vkconfig_core/type_platform.cpp index 5d1f59664a..170c159d1a 100644 --- a/vkconfig_core/type_platform.cpp +++ b/vkconfig_core/type_platform.cpp @@ -65,6 +65,8 @@ std::vector GetPlatformTokens(int platform_flags) { return result; } +bool IsDesktop(PlatformType type) { return type >= PLATFORM_DESKTOP_FIRST && type <= PLATFORM_DESKTOP_LAST; } + bool IsPlatformSupported(int platform_flags) { return platform_flags & (1 << VKC_PLATFORM); } const char* GetLabel(PlatformType type) { @@ -84,3 +86,67 @@ const char* GetLabel(PlatformType type) { return TABLE[type]; } + +const char* GetLatestReleaseSDK(PlatformType type) { + assert(IsDesktop(type)); + + static const char* TABLE[] = { + "https://vulkan.lunarg.com/sdk/latest/windows.txt", // PLATFORM_WINDOWS_X86 + "https://vulkan.lunarg.com/sdk/latest/warm.txt", // PLATFORM_WINDOWS_ARM + "https://vulkan.lunarg.com/sdk/latest/linux.txt", // PLATFORM_LINUX + "https://vulkan.lunarg.com/sdk/latest/mac.txt", // PLATFORM_MACOS + "N/A", // PLATFORM_ANDROID + "N/A", // PLATFORM_IOS + }; + static_assert(std::size(TABLE) == PLATFORM_COUNT, "The tranlation table size doesn't match the enum number of elements"); + + return TABLE[type]; +} + +const char* GetInstallerFilename(PlatformType type) { + assert(IsDesktop(type)); + + static const char* TABLE[] = { + "vulkan_sdk.exe", // PLATFORM_WINDOWS_X86 + "vulkan_sdk.exe", // PLATFORM_WINDOWS_ARM + "vulkan_sdk.tar.xz", // PLATFORM_LINUX + "vulkan_sdk.zip", // PLATFORM_MACOS + "N/A", // PLATFORM_ANDROID + "N/A", // PLATFORM_IOS + }; + static_assert(std::size(TABLE) == PLATFORM_COUNT, "The tranlation table size doesn't match the enum number of elements"); + + return TABLE[type]; +} + +const char* GetVersionedFilename(PlatformType type) { + assert(IsDesktop(type)); + + static const char* TABLE[] = { + "vulkan_sdk-%s.exe", // PLATFORM_WINDOWS_X86 + "vulkan_sdk-%s.exe", // PLATFORM_WINDOWS_ARM + "vulkan_sdk-%s.tar.xz", // PLATFORM_LINUX + "vulkan_sdk-%s.zip", // PLATFORM_MACOS + "N/A", // PLATFORM_ANDROID + "N/A", // PLATFORM_IOS + }; + static_assert(std::size(TABLE) == PLATFORM_COUNT, "The tranlation table size doesn't match the enum number of elements"); + + return TABLE[type]; +} + +const char* GetLatestPackageSDK(PlatformType type) { + assert(IsDesktop(type)); + + static const char* TABLE[] = { + "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan_sdk.exe", // PLATFORM_WINDOWS_X86 + "https://sdk.lunarg.com/sdk/download/latest/warm/vulkan_sdk.exe", // PLATFORM_WINDOWS_ARM + "https://sdk.lunarg.com/sdk/download/latest/linux/vulkan_sdk.tar.xz", // PLATFORM_LINUX + "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan_sdk.zip", // PLATFORM_MACOS + "N/A", // PLATFORM_ANDROID + "N/A", // PLATFORM_IOS + }; + static_assert(std::size(TABLE) == PLATFORM_COUNT, "The tranlation table size doesn't match the enum number of elements"); + + return TABLE[type]; +} diff --git a/vkconfig_core/type_platform.h b/vkconfig_core/type_platform.h index 66dca43b59..9bb48c7fa1 100644 --- a/vkconfig_core/type_platform.h +++ b/vkconfig_core/type_platform.h @@ -45,7 +45,10 @@ enum PlatformType { PLATFORM_IOS = 5, PLATFORM_FIRST = PLATFORM_WINDOWS_X86, - PLATFORM_LAST = PLATFORM_IOS + PLATFORM_LAST = PLATFORM_IOS, + + PLATFORM_DESKTOP_FIRST = PLATFORM_WINDOWS_X86, + PLATFORM_DESKTOP_LAST = PLATFORM_MACOS }; enum { PLATFORM_COUNT = PLATFORM_LAST - PLATFORM_FIRST + 1 }; @@ -88,6 +91,16 @@ std::vector GetPlatformTokens(int platform_flags); #error "Unknown platform" #endif +bool IsDesktop(PlatformType type); + bool IsPlatformSupported(int platform_flags); const char* GetLabel(PlatformType type); + +const char* GetLatestReleaseSDK(PlatformType type); + +const char* GetLatestPackageSDK(PlatformType type); + +const char* GetInstallerFilename(PlatformType type); + +const char* GetVersionedFilename(PlatformType type); diff --git a/vkconfig_core/util.cpp b/vkconfig_core/util.cpp index c8fb2b0fcf..cdc6fa3364 100644 --- a/vkconfig_core/util.cpp +++ b/vkconfig_core/util.cpp @@ -88,6 +88,18 @@ bool IsFloat(const std::string& s) { return std::regex_search(s, FRAME_REGEX); } +std::size_t CountChar(const std::string& value, char c) { + std::size_t count = 0; + + for (std::size_t i = 0, n = value.size(); i < n; ++i) { + if (value[i] == c) { + ++count; + } + } + + return count; +} + void RemoveString(std::vector& list, const std::string& value) { std::vector new_list; new_list.reserve(list.size()); diff --git a/vkconfig_core/util.h b/vkconfig_core/util.h index dc3b2d5fb8..9b3a0e37c6 100644 --- a/vkconfig_core/util.h +++ b/vkconfig_core/util.h @@ -53,6 +53,8 @@ bool IsNumber(const std::string& s); bool IsFloat(const std::string& s); +std::size_t CountChar(const std::string& value, char c); + // Remove a value if it's present void RemoveString(std::vector& list, const std::string& value); diff --git a/vkconfig_core/version.cpp b/vkconfig_core/version.cpp index d5cc7d33ce..75b6c26e37 100644 --- a/vkconfig_core/version.cpp +++ b/vkconfig_core/version.cpp @@ -41,19 +41,42 @@ static Version GetVersionData(const char *version) { uint32_t version_major = 0; uint32_t version_minor = 0; uint32_t version_patch = 0; - - std::sscanf(version, "%d.%d.%d", &version_major, &version_minor, &version_patch); - - return Version(version_major, version_minor, version_patch); + uint32_t version_revision = 0; + + std::size_t count = CountChar(version, '.'); + + switch (count) { + default: + assert(0); + return Version::NONE; + case 0: + std::sscanf(version, "%d", &version_major); + return Version(version_major, version_minor); + case 1: + std::sscanf(version, "%d.%d", &version_major, &version_minor); + return Version(version_major, version_minor); + case 2: + std::sscanf(version, "%d.%d.%d", &version_major, &version_minor, &version_patch); + return Version(version_major, version_minor, version_patch); + case 3: + std::sscanf(version, "%d.%d.%d.%d", &version_major, &version_minor, &version_patch, &version_revision); + return Version(version_major, version_minor, version_patch, version_revision); + } } Version::Version(uint32_t version_complete) : _major(VK_VERSION_MAJOR(version_complete)), _minor(VK_VERSION_MINOR(version_complete)), - _patch(VK_VERSION_PATCH(version_complete)) {} + _patch(VK_VERSION_PATCH(version_complete)), + _revision(VK_API_VERSION_VARIANT(version_complete)) {} + +Version::Version(uint32_t version_major, uint32_t version_minor) : _major(version_major), _minor(version_minor), type(WITH_MINOR) {} Version::Version(uint32_t version_major, uint32_t version_minor, uint32_t version_patch) - : _major(version_major), _minor(version_minor), _patch(version_patch) {} + : _major(version_major), _minor(version_minor), _patch(version_patch), type(WITH_PATCH) {} + +Version::Version(uint32_t version_major, uint32_t version_minor, uint32_t version_patch, uint32_t version_revision) + : _major(version_major), _minor(version_minor), _patch(version_patch), _revision(version_revision), type(WITH_REVISION) {} Version::Version(const char *version) : Version(GetVersionData(version)) {} @@ -63,36 +86,46 @@ std::string Version::str() const { if (*this == LATEST) { return "Latest"; } else { - return format("%d.%d.%d", _major, _minor, _patch); + switch (this->type) { + case WITH_MAJOR: + return format("%d", _major); + case WITH_MINOR: + return format("%d.%d", _major, _minor); + default: + case WITH_PATCH: + return format("%d.%d.%d", _major, _minor, _patch); + case WITH_REVISION: + return format("%d.%d.%d.%d", _major, _minor, _patch, _revision); + } } } bool Version::operator!=(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) != - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) != + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } bool Version::operator==(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) == - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) == + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } bool Version::operator<(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) < - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) < + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } bool Version::operator>=(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) >= - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) >= + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } bool Version::operator>(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) > - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) > + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } bool Version::operator<=(const Version &other_version) const { - return VK_MAKE_VERSION(_major, _minor, _patch) <= - VK_MAKE_VERSION(other_version._major, other_version._minor, other_version._patch); + return VK_MAKE_API_VERSION(this->_major, this->_minor, this->_patch, this->_revision) <= + VK_MAKE_API_VERSION(other_version._major, other_version._minor, other_version._patch, other_version._revision); } diff --git a/vkconfig_core/version.h b/vkconfig_core/version.h index 64e4da1298..1f952d1125 100644 --- a/vkconfig_core/version.h +++ b/vkconfig_core/version.h @@ -29,6 +29,8 @@ extern const char *VKCONFIG_NAME; extern const char *VKCONFIG_SHORT_NAME; class Version { + enum type { WITH_MAJOR = 0, WITH_MINOR, WITH_PATCH, WITH_REVISION }; + public: static const Version VKCONFIG; static const Version VKHEADER; @@ -36,9 +38,11 @@ class Version { static const Version LATEST; static const Version REQUIRED_LOADER_VERSION; - explicit Version() : _major(0), _minor(0), _patch(0) {} + explicit Version() : _major(0), _minor(0), _patch(0), _revision(0) {} explicit Version(uint32_t version_complete); + explicit Version(uint32_t version_major, uint32_t version_minor); explicit Version(uint32_t version_major, uint32_t version_minor, uint32_t version_patch); + explicit Version(uint32_t version_major, uint32_t version_minor, uint32_t version_patch, uint32_t version_revision); explicit Version(const char *version); explicit Version(const std::string &version); @@ -54,11 +58,14 @@ class Version { uint32_t GetMajor() const { return _major; }; uint32_t GetMinor() const { return _minor; }; uint32_t GetPatch() const { return _patch; }; + uint32_t GetRevision() const { return _revision; }; private: - uint32_t _major; - uint32_t _minor; - uint32_t _patch; + uint32_t _major = 0; + uint32_t _minor = 0; + uint32_t _patch = 0; + uint32_t _revision = 0; + type type = WITH_PATCH; }; #define VKC_ASSERT_VERSION(expression, required_version, current_version) \ diff --git a/vkconfig_gui/mainwindow.cpp b/vkconfig_gui/mainwindow.cpp index f630d4027b..0200444279 100644 --- a/vkconfig_gui/mainwindow.cpp +++ b/vkconfig_gui/mainwindow.cpp @@ -288,9 +288,9 @@ void MainWindow::closeEvent(QCloseEvent *event) { alert.setDefaultButton(QMessageBox::Ok); alert.setCheckBox(new QCheckBox("Do not show again.")); - QPalette palette, palette_saved = this->ui->settings_keep_running->palette(); + QPalette palette, palette_saved = this->ui->preferences_keep_running->palette(); palette.setColor(QPalette::WindowText, QColor(Qt::red)); - this->ui->settings_keep_running->setPalette(palette); + this->ui->preferences_keep_running->setPalette(palette); this->ui->tab_widget->setCurrentIndex(TAB_PREFERENCES); @@ -299,7 +299,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { configurator.Set(HIDE_MESSAGE_USE_SYSTEM_TRAY); } - this->ui->settings_keep_running->setPalette(palette_saved); + this->ui->preferences_keep_running->setPalette(palette_saved); if (ret_val == QMessageBox::Cancel) { event->ignore(); // Not closing the window diff --git a/vkconfig_gui/mainwindow.h b/vkconfig_gui/mainwindow.h index 7bfdbb096c..d3c7c72079 100644 --- a/vkconfig_gui/mainwindow.h +++ b/vkconfig_gui/mainwindow.h @@ -59,11 +59,11 @@ class MainWindow : public QMainWindow { std::unique_ptr vk_info_dialog; std::unique_ptr vk_installation_dialog; - QSystemTrayIcon *_tray_icon; - QMenu *_tray_icon_menu; - QAction *_tray_restore_action; + QSystemTrayIcon *_tray_icon = nullptr; + QMenu *_tray_icon_menu = nullptr; + QAction *_tray_restore_action = nullptr; std::array _tray_layers; - QAction *_tray_quit_action; + QAction *_tray_quit_action = nullptr; private slots: void trayActionRestore(); @@ -71,6 +71,7 @@ class MainWindow : public QMainWindow { void on_tray_any(bool checked); void on_tray_all(bool checked); void on_tray_per(bool checked); + void iconActivated(QSystemTrayIcon::ActivationReason reason); public Q_SLOTS: diff --git a/vkconfig_gui/mainwindow.ui b/vkconfig_gui/mainwindow.ui index b0523a5969..bed26c33c6 100644 --- a/vkconfig_gui/mainwindow.ui +++ b/vkconfig_gui/mainwindow.ui @@ -6,7 +6,7 @@ 0 0 - 1024 + 1200 640 @@ -82,10 +82,10 @@ false - QTabWidget::Rounded + QTabWidget::TabShape::Rounded - 0 + 5 @@ -116,7 +116,7 @@ 0 - Qt::Horizontal + Qt::Orientation::Horizontal true @@ -132,7 +132,7 @@ 0 - Qt::Vertical + Qt::Orientation::Vertical false @@ -211,7 +211,7 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents @@ -330,19 +330,19 @@ false - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain 1 - Qt::ScrollBarAlwaysOn + Qt::ScrollBarPolicy::ScrollBarAlwaysOn - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers false @@ -443,7 +443,7 @@ Execute Closer to the Vulkan Application - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -463,31 +463,31 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain 1 - Qt::ScrollBarAlwaysOn + Qt::ScrollBarPolicy::ScrollBarAlwaysOn 0 - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers true - QAbstractItemView::DragDrop + QAbstractItemView::DragDropMode::DragDrop - Qt::MoveAction + Qt::DropAction::MoveAction true @@ -520,7 +520,7 @@ Execute Closer to the Vulkan Driver - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter 0 @@ -634,7 +634,7 @@ 0 - Qt::Vertical + Qt::Orientation::Vertical @@ -727,25 +727,25 @@ - QFrame::Box + QFrame::Shape::Box - QFrame::Plain + QFrame::Shadow::Plain 0 - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - QAbstractScrollArea::AdjustToContentsOnFirstShow + QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow 0 - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers true @@ -855,7 +855,7 @@ 24 - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter true @@ -933,7 +933,7 @@ - Qt::ScrollBarAlwaysOn + Qt::ScrollBarPolicy::ScrollBarAlwaysOn true @@ -1331,7 +1331,7 @@ Arguments: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1348,7 +1348,7 @@ Env Variables: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1486,7 +1486,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1598,7 +1598,7 @@ - Qt::ScrollBarAlwaysOn + Qt::ScrollBarPolicy::ScrollBarAlwaysOn true @@ -1692,13 +1692,13 @@ <a style="color:%s;" href="https://vulkan.lunarg.com/doc/view/latest/windows/antora/spec/latest/chapters/introduction.html">Latest HTML</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1715,13 +1715,13 @@ <a style="color:%s;" href="https://registry.khronos.org/vulkan/specs/latest/pdf/vkspec.pdf">Latest PDF</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1766,13 +1766,13 @@ <a style="color:%s;" href="https://docs.vulkan.org/spec/latest/index.html">Official Vulkan Documentation</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1789,13 +1789,13 @@ <a style="color:%s;" href="https://registry.khronos.org/vulkan/">Khronos Vulkan Registry</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1812,13 +1812,13 @@ <a style="color:%s;" href="https://vulkan.gpuinfo.org/">vulkan.gpuinfo.org</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1863,13 +1863,13 @@ Vulkan SDK: <a style="color:%s;" href="https://vulkan.lunarg.com/doc/sdk/latest/windows/release_notes.html">Release Notes</a>, <a style="color:%s;" href="https://vulkan.lunarg.com/sdk/home">Download Page</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1886,13 +1886,13 @@ Vulkan Configurator: <a style="color:%s;" href="https://github.com/LunarG/VulkanTools/blob/main/vkconfig_gui/README.md">Readme</a>, <a style="color:%s;" href="https://github.com/LunarG/VulkanTools/blob/main/vkconfig_gui/CHANGELOG.md">Changelog</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1909,13 +1909,13 @@ Vulkan Loader: <a style="color:%s;" href="https://vulkan.lunarg.com/doc/view/latest/windows/layer_configuration.html">Layers Configuration</a>, <a style="color:%s;" href="https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDebugging.md">Loader Debugging Guide</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1932,13 +1932,13 @@ Vulkan Validation Layer: <a style="color:%s;" href="https://vulkan.lunarg.com/doc/sdk/latest/windows/khronos_validation_layer.html">Readme</a>, <a style="color:%s;" href="https://vulkan.lunarg.com/doc/sdk/latest/windows/validation_error_database.html">Coverage</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1955,13 +1955,13 @@ Vulkan API Capture and Replay - GFXReconstruct: <a style="color:%s;" href="https://vulkan.lunarg.com/doc/sdk/latest/windows/capture_tools.html">Usage</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -1978,13 +1978,13 @@ Vulkan Profiles Tools: <a style="color:%s;" href="https://github.com/KhronosGroup/Vulkan-Profiles/blob/main/OVERVIEW.md">Overview</a>, <a style="color:%s;" href="https://github.com/KhronosGroup/Vulkan-Profiles/blob/main/CHANGELOG.md">Changelog</a>, <a style="color:%s;" href="https://www.lunarg.com/wp-content/uploads/2024/04/The-Vulkan-Profiles-Tools-LunarG-Christophe-Riccio-04-11-2024.pdf">Whitepaper</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -2029,13 +2029,13 @@ <a style="color:%s;" href="https://discord.com/invite/vulkan">Vulkan Discord</a> - <a style="color:%s;" href="https://reddit.com/r/vulkan">Reddit</a> - <a style="color:%s;" href="https://stackoverflow.com/questions/tagged/vulkan">Stack Overflow</a> - <a style="color:%s;" href="https://fosstodon.org/@vulkan">Mastodon</a> - Qt::RichText + Qt::TextFormat::RichText true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -2045,7 +2045,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -2066,7 +2066,7 @@ - + Arial @@ -2094,7 +2094,7 @@ 5 - + Arial @@ -2108,7 +2108,7 @@ - + Arial @@ -2156,7 +2156,7 @@ - + Arial @@ -2167,7 +2167,7 @@ - + 32 @@ -2195,10 +2195,136 @@ + + + + Vulkan SDK Releases + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Notify new Vulkan SDK release at Vulkan Configurator launch + + + true + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Open Vulkan SDK download web page + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ${VK_DOWNLOAD}: + + + + + + + 0 + + + + + + + + + + + 32 + 16777215 + + + + + + + + + + + + + + + + + + + - Qt::Vertical + Qt::Orientation::Vertical @@ -2219,7 +2345,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2230,7 +2356,7 @@ - + Resetting Vulkan Configurator to default... @@ -2303,7 +2429,7 @@ :/resourcefiles/lunarg_logo.png - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -2342,7 +2468,7 @@ Vulkan Configurator licensed under Apache 2.0 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter true @@ -2365,13 +2491,13 @@ - Qt::LeftToRight + Qt::LayoutDirection::LeftToRight Copyright (c) 2020-2025 LunarG, Inc. - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter true @@ -2410,7 +2536,7 @@ Qt licensed under LGPL 3.0 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter true @@ -2447,7 +2573,7 @@ true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction @@ -2468,7 +2594,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame diff --git a/vkconfig_gui/tab_preferences.cpp b/vkconfig_gui/tab_preferences.cpp index d3df24b0c8..08479f331c 100644 --- a/vkconfig_gui/tab_preferences.cpp +++ b/vkconfig_gui/tab_preferences.cpp @@ -20,21 +20,38 @@ #include "tab_preferences.h" #include "style.h" +#include "file_downloader.h" #include "../vkconfig_core/configurator.h" #include #include +#include TabPreferences::TabPreferences(MainWindow &window, std::shared_ptr ui) : Tab(TAB_DIAGNOSTIC, window, ui) { - this->ui->settings_reset->setIcon(::Get(::ICON_RESET)); - this->ui->settings_vk_home_browse->setIcon(::Get(::ICON_FOLDER_SEARCH)); - - this->connect(this->ui->settings_keep_running, SIGNAL(toggled(bool)), this, SLOT(on_keep_running_toggled(bool))); - this->connect(this->ui->settings_vk_home_text, SIGNAL(returnPressed()), this, SLOT(on_vk_home_text_pressed())); - this->connect(this->ui->settings_vk_home_browse, SIGNAL(clicked()), this, SLOT(on_vk_home_browse_pressed())); - this->connect(this->ui->settings_reset, SIGNAL(clicked()), this, SLOT(on_reset_hard_pressed())); - this->connect(this->ui->settings_layer_dev_mode, SIGNAL(toggled(bool)), this, SLOT(on_layer_dev_mode_toggled(bool))); + this->ui->preferences_reset->setIcon(::Get(::ICON_RESET)); + this->ui->preferences_vk_home_browse->setIcon(::Get(::ICON_FOLDER_SEARCH)); + this->ui->preferences_vk_download_browse->setIcon(::Get(::ICON_FOLDER_SEARCH)); + + this->connect(this->ui->preferences_keep_running, SIGNAL(toggled(bool)), this, SLOT(on_keep_running_toggled(bool))); + this->connect(this->ui->preferences_vk_home_text, SIGNAL(returnPressed()), this, SLOT(on_vk_home_text_pressed())); + this->connect(this->ui->preferences_vk_home_browse, SIGNAL(clicked()), this, SLOT(on_vk_home_browse_pressed())); + this->connect(this->ui->preferences_vk_download_browse, SIGNAL(clicked()), this, SLOT(on_vk_download_browse_pressed())); + this->connect(this->ui->preferences_reset, SIGNAL(clicked()), this, SLOT(on_reset_hard_pressed())); + this->connect(this->ui->preferences_layer_dev_mode, SIGNAL(toggled(bool)), this, SLOT(on_layer_dev_mode_toggled(bool))); + this->connect(this->ui->preferences_open_page, SIGNAL(clicked()), this, SLOT(on_open_page_pressed())); + this->connect(this->ui->preferences_download, SIGNAL(clicked()), this, SLOT(on_download_pressed())); + + this->ui->preferences_progress->setVisible(false); + + QUrl url(GetLatestReleaseSDK(VKC_PLATFORM)); + QNetworkRequest request(url); + this->network_manager.get(request); + this->connect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(on_release_downloaded(QNetworkReply *))); + + Configurator &configurator = Configurator::Get(); + this->ui->preferences_download->setText( + format("Download Latest Vulkan SDK %s", configurator.latest_sdk_version.str().c_str()).c_str()); } TabPreferences::~TabPreferences() {} @@ -44,18 +61,23 @@ void TabPreferences::UpdateUI(UpdateUIMode mode) { Configurator &configurator = Configurator::Get(); - this->ui->settings_keep_running->blockSignals(true); - this->ui->settings_keep_running->setChecked(configurator.GetUseSystemTray()); - this->ui->settings_keep_running->blockSignals(false); + this->ui->preferences_keep_running->blockSignals(true); + this->ui->preferences_keep_running->setChecked(configurator.GetUseSystemTray()); + this->ui->preferences_keep_running->blockSignals(false); + + this->ui->preferences_vk_home_text->blockSignals(true); + this->ui->preferences_vk_home_text->setText(::Path(Path::HOME).RelativePath().c_str()); + this->ui->preferences_vk_home_text->setToolTip(::Path(Path::HOME).AbsolutePath().c_str()); + this->ui->preferences_vk_home_text->blockSignals(false); - this->ui->settings_vk_home_text->blockSignals(true); - this->ui->settings_vk_home_text->setText(::Path(Path::HOME).RelativePath().c_str()); - this->ui->settings_vk_home_text->setToolTip(::Path(Path::HOME).AbsolutePath().c_str()); - this->ui->settings_vk_home_text->blockSignals(false); + this->ui->preferences_layer_dev_mode->blockSignals(true); + this->ui->preferences_layer_dev_mode->setChecked(configurator.GetUseLayerDevMode()); + this->ui->preferences_layer_dev_mode->blockSignals(false); - this->ui->settings_layer_dev_mode->blockSignals(true); - this->ui->settings_layer_dev_mode->setChecked(configurator.GetUseLayerDevMode()); - this->ui->settings_layer_dev_mode->blockSignals(false); + this->ui->preferences_vk_download_text->blockSignals(true); + this->ui->preferences_vk_download_text->setText(::Path(Path::DOWNLOAD).RelativePath().c_str()); + this->ui->preferences_vk_download_text->setToolTip(::Path(Path::DOWNLOAD).AbsolutePath().c_str()); + this->ui->preferences_vk_download_text->blockSignals(false); } void TabPreferences::CleanUI() {} @@ -73,35 +95,48 @@ void TabPreferences::on_keep_running_toggled(bool checked) { } void TabPreferences::on_vk_home_text_pressed() { - Path path(this->ui->settings_vk_home_text->text().toStdString()); + Path path(this->ui->preferences_vk_home_text->text().toStdString()); if (path.Exists()) { - ::SetHomePath(this->ui->settings_vk_home_text->text().toStdString()); + ::SetHomePath(this->ui->preferences_vk_home_text->text().toStdString()); } else { QMessageBox message; message.setIcon(QMessageBox::Critical); message.setWindowTitle("Invalid ${VK_HOME} path..."); message.setText( - format("'%s' is not a valid, it doesn't exist.", this->ui->settings_vk_home_text->text().toStdString().c_str()) + format("'%s' is not a valid, it doesn't exist.", this->ui->preferences_vk_home_text->text().toStdString().c_str()) .c_str()); message.setInformativeText(format("Restoring the previous path '%s'.", ::Path(Path::HOME).AbsolutePath().c_str()).c_str()); message.exec(); - this->ui->settings_vk_home_text->setText(::Path(Path::HOME).AbsolutePath().c_str()); + this->ui->preferences_vk_home_text->setText(::Path(Path::HOME).AbsolutePath().c_str()); } } void TabPreferences::on_vk_home_browse_pressed() { const QString selected_path = QFileDialog::getExistingDirectory( - this->ui->settings_vk_home_browse, "Select the Vulkan Home Default Working Folder (Set ${VK_HOME} value)...", + this->ui->preferences_vk_home_browse, "Select the Vulkan Home Default Working Folder (Set ${VK_HOME} value)...", ::Path(Path::HOME).AbsolutePath().c_str()); if (!selected_path.isEmpty()) { - this->ui->settings_vk_home_text->setText(selected_path); + this->ui->preferences_vk_home_text->setText(selected_path); ::SetHomePath(selected_path.toStdString()); } } +void TabPreferences::on_vk_download_browse_pressed() { + const QString selected_path = + QFileDialog::getExistingDirectory(this->ui->preferences_vk_download_browse, + "Select the Vulkan Configurator Download Default Folder (Set ${VK_DOWNLOAD} value)...", + ::Path(Path::DOWNLOAD).AbsolutePath().c_str()); + + if (!selected_path.isEmpty()) { + this->ui->preferences_vk_download_browse->setText(selected_path); + + ::SetDownloadPath(selected_path.toStdString()); + } +} + void TabPreferences::on_reset_hard_pressed() { QMessageBox message; message.setIcon(QMessageBox::Critical); @@ -122,3 +157,100 @@ void TabPreferences::on_layer_dev_mode_toggled(bool checked) { Configurator &configurator = Configurator::Get(); configurator.SetUseLayerDevMode(checked); } + +void TabPreferences::on_open_page_pressed() { QDesktopServices::openUrl(QUrl("https://vulkan.lunarg.com/sdk/home")); } + +void TabPreferences::on_download_pressed() { + this->ui->preferences_download->setEnabled(false); + this->ui->preferences_progress->setVisible(true); + this->ui->preferences_vk_download_text->setVisible(false); + + this->connect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(on_package_downloaded(QNetworkReply *))); + + QUrl url(GetLatestPackageSDK(VKC_PLATFORM)); + QNetworkRequest request(url); + QNetworkReply *reply = this->network_manager.get(request); + this->connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(on_download_progress(qint64, qint64))); + + Configurator &configurator = Configurator::Get(); + this->ui->preferences_progress->setFormat((std::string(GetLatestPackageSDK(VKC_PLATFORM)) + " - %p%").c_str()); +} + +void TabPreferences::on_release_downloaded(QNetworkReply *pReply) { + this->disconnect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), 0, 0); + + Configurator &configurator = Configurator::Get(); + + configurator.online_sdk_version = Version(pReply->readAll().toStdString()); + this->ui->preferences_download->setText( + format("Download Latest Vulkan SDK %s", configurator.online_sdk_version.str().c_str()).c_str()); + + pReply->deleteLater(); + + if (configurator.latest_sdk_version < configurator.online_sdk_version) { + QMessageBox alert; + alert.setWindowTitle("A new version of the Vulkan SDK is available"); + alert.setText(format("Do you want to download Vulkan SDK %s?", configurator.online_sdk_version.str().c_str()).c_str()); + alert.setIcon(QMessageBox::Question); + alert.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + alert.setDefaultButton(QMessageBox::Yes); + alert.setCheckBox(new QCheckBox("Do not show again for this version.")); + + int ret_val = alert.exec(); + if (alert.checkBox()->isChecked()) { + configurator.latest_sdk_version = configurator.online_sdk_version; + } + + if (ret_val == QMessageBox::Yes) { + this->ui->tab_widget->setCurrentIndex(TAB_PREFERENCES); + this->on_download_pressed(); + } + } +} + +void TabPreferences::on_package_downloaded(QNetworkReply *pReply) { + this->ui->preferences_download->setEnabled(true); + this->ui->preferences_progress->setVisible(false); + this->ui->preferences_vk_download_text->setVisible(true); + + Configurator &configurator = Configurator::Get(); + configurator.latest_sdk_version = configurator.online_sdk_version; + + this->downloaded_data = pReply->readAll(); + pReply->deleteLater(); + + const Path &path_latest = ::AbsolutePath(Path::DOWNLOAD) + Path::Separator() + GetInstallerFilename(VKC_PLATFORM); + QFile file_latest(path_latest.AbsolutePath().c_str()); + + const bool result_latest = file_latest.open(QFile::WriteOnly); + if (result_latest) { + file_latest.write(this->downloaded_data); + file_latest.close(); + } + + const Path &path_version = ::AbsolutePath(Path::DOWNLOAD) + Path::Separator() + + format(GetVersionedFilename(VKC_PLATFORM), configurator.latest_sdk_version.str().c_str()); + QFile file_version(path_version.AbsolutePath().c_str()); + + const bool result_version = file_version.open(QFile::WriteOnly); + if (result_latest) { + file_version.write(this->downloaded_data); + file_version.close(); + } + + if (!result_latest && !result_version) { + QMessageBox alert; + alert.setWindowTitle("Couldn't save downloaded Vulkan SDK installer..."); + alert.setIcon(QMessageBox::Critical); + alert.exec(); + } + + QDesktopServices::openUrl(QUrl::fromLocalFile(path_latest.AbsoluteDir().c_str())); + + // qApp->quit(); +} + +void TabPreferences::on_download_progress(qint64 bytesReceived, qint64 bytesTotal) { + this->ui->preferences_progress->setMaximum(bytesTotal); + this->ui->preferences_progress->setValue(bytesReceived); +} diff --git a/vkconfig_gui/tab_preferences.h b/vkconfig_gui/tab_preferences.h index f84cc82940..d184bbd02e 100644 --- a/vkconfig_gui/tab_preferences.h +++ b/vkconfig_gui/tab_preferences.h @@ -22,6 +22,9 @@ #include "tab.h" +#include +#include + class TabPreferences : public Tab { Q_OBJECT @@ -37,8 +40,16 @@ class TabPreferences : public Tab { void on_keep_running_toggled(bool checked); void on_vk_home_text_pressed(); void on_vk_home_browse_pressed(); + void on_vk_download_browse_pressed(); void on_reset_hard_pressed(); void on_layer_dev_mode_toggled(bool checked); + void on_open_page_pressed(); + void on_download_pressed(); + void on_release_downloaded(QNetworkReply *pReply); + void on_package_downloaded(QNetworkReply *pReply); + void on_download_progress(qint64 bytesReceived, qint64 bytesTotal); private: + QNetworkAccessManager network_manager; + QByteArray downloaded_data; };