diff --git a/GlosSIConfig/.clang-format b/GlosSIConfig/.clang-format
new file mode 100644
index 0000000..dc813fd
--- /dev/null
+++ b/GlosSIConfig/.clang-format
@@ -0,0 +1,7 @@
+UseTab: false
+IndentWidth: 4
+BreakBeforeBraces: "Stroustrup"
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+ColumnLimit: 0
+PointerAlignment: "Left"
\ No newline at end of file
diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj
index 8ca3a14..afb441c 100644
--- a/GlosSIConfig/GlosSIConfig.vcxproj
+++ b/GlosSIConfig/GlosSIConfig.vcxproj
@@ -123,8 +123,10 @@
+
+
@@ -136,6 +138,7 @@
+
diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters
index 78d2624..8162392 100644
--- a/GlosSIConfig/GlosSIConfig.vcxproj.filters
+++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters
@@ -51,12 +51,16 @@
qml
-
- Source Files
-
qml
+
+ qml
+
+
+ qml
+
+
@@ -70,6 +74,9 @@
Header Files
+
+ Header Files
+
diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp
index 7188cfb..0e111aa 100644
--- a/GlosSIConfig/UIModel.cpp
+++ b/GlosSIConfig/UIModel.cpp
@@ -16,35 +16,21 @@ limitations under the License.
#include "UIModel.h"
#include
-#include
-
-#ifdef _WIN32
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#pragma comment(lib, "Shlwapi.lib")
-using namespace Windows::Management::Deployment;
-using namespace Windows::Foundation::Collections;
-
#include
+#include
-#ifdef _WIN32
#include
-#endif
+#ifdef _WIN32
+#include "UWPFetch.h"
#endif
UIModel::UIModel() : QObject(nullptr)
{
auto path = std::filesystem::temp_directory_path()
- .parent_path()
- .parent_path()
- .parent_path();
+ .parent_path()
+ .parent_path()
+ .parent_path();
path /= "Roaming";
path /= "GlosSI";
@@ -59,7 +45,6 @@ UIModel::UIModel() : QObject(nullptr)
parseShortcutVDF();
readConfigs();
-
}
void UIModel::readConfigs()
@@ -68,41 +53,38 @@ void UIModel::readConfigs()
auto entries = dir.entryList(QDir::Files, QDir::SortFlag::Name);
entries.removeIf([](const auto& entry) {
return !entry.endsWith(".json");
- });
-
- std::for_each(entries.begin(), entries.end(), [this](const auto& name)
- {
- auto path = config_path_;
- path /= config_dir_name_.toStdString();
- path /= name.toStdString();
- QFile file(path);
- if (!file.open(QIODevice::Text | QIODevice::ReadOnly))
- {
- // meh
- return;
- }
- const auto data = file.readAll();
- file.close();
- const auto jsondoc = QJsonDocument::fromJson(data);
- const auto filejson = jsondoc.object();
-
- QJsonObject json;
- json["version"] = filejson["version"];
- json["icon"] = filejson["icon"];
- json["launch"] = filejson["launch"]["launch"];
- json["launchPath"] = filejson["launch"]["launchPath"];
- json["launchAppArgs"] = filejson["launch"]["launchAppArgs"];
- json["closeOnExit"] = filejson["launch"]["closeOnExit"];
- json["hideDevices"] = filejson["devices"]["hideDevices"];
- json["windowMode"] = filejson["window"]["windowMode"];
- json["maxFps"] = filejson["window"]["maxFps"];
- json["scale"] = filejson["window"]["scale"];
-
- json["name"] = QString(name).replace(QRegularExpression("\.json"), "");
-
- targets_.append(json.toVariantMap());
- });
-
+ });
+
+ std::for_each(entries.begin(), entries.end(), [this](const auto& name) {
+ auto path = config_path_;
+ path /= config_dir_name_.toStdString();
+ path /= name.toStdString();
+ QFile file(path);
+ if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) {
+ // meh
+ return;
+ }
+ const auto data = file.readAll();
+ file.close();
+ const auto jsondoc = QJsonDocument::fromJson(data);
+ const auto filejson = jsondoc.object();
+
+ QJsonObject json;
+ json["version"] = filejson["version"];
+ json["icon"] = filejson["icon"];
+ json["launch"] = filejson["launch"]["launch"];
+ json["launchPath"] = filejson["launch"]["launchPath"];
+ json["launchAppArgs"] = filejson["launch"]["launchAppArgs"];
+ json["closeOnExit"] = filejson["launch"]["closeOnExit"];
+ json["hideDevices"] = filejson["devices"]["hideDevices"];
+ json["windowMode"] = filejson["window"]["windowMode"];
+ json["maxFps"] = filejson["window"]["maxFps"];
+ json["scale"] = filejson["window"]["scale"];
+
+ json["name"] = QString(name).replace(QRegularExpression("\.json"), "");
+
+ targets_.append(json.toVariantMap());
+ });
emit targetListChanged();
}
@@ -152,12 +134,9 @@ void UIModel::deleteTarget(int index)
bool UIModel::isInSteam(QVariant shortcut)
{
const auto map = shortcut.toMap();
- for (auto& steam_shortcut : shortcuts_vdf_.shortcuts)
- {
- if (map["name"].toString() == QString::fromStdString(steam_shortcut.appName.value))
- {
- if (QString::fromStdString(steam_shortcut.exe.value).toLower().contains("glossitarget.exe"))
- {
+ for (auto& steam_shortcut : shortcuts_vdf_.shortcuts) {
+ if (map["name"].toString() == QString::fromStdString(steam_shortcut.appName.value)) {
+ if (QString::fromStdString(steam_shortcut.exe.value).toLower().contains("glossitarget.exe")) {
return true;
}
}
@@ -178,11 +157,9 @@ bool UIModel::addToSteam(QVariant shortcut)
vdfshortcut.idx = shortcuts_vdf_.shortcuts.size();
vdfshortcut.appName.value = name.toStdString();
vdfshortcut.exe.value = ("\"" + appDir.absolutePath() + "/GlosSITarget.exe" + "\"").toStdString();
- vdfshortcut.StartDir.value = (
- launch && !maybeLaunchPath.isEmpty()
- ? (std::string("\"") + std::filesystem::path(maybeLaunchPath.toStdString()).parent_path().string() + "\"")
- : ("\"" + appDir.absolutePath() + "\"").toStdString()
- );
+ vdfshortcut.StartDir.value = (launch && !maybeLaunchPath.isEmpty()
+ ? (std::string("\"") + std::filesystem::path(maybeLaunchPath.toStdString()).parent_path().string() + "\"")
+ : ("\"" + appDir.absolutePath() + "\"").toStdString());
vdfshortcut.appId.value = VDFParser::Parser::calculateAppId(vdfshortcut);
// ShortcutPath; default
vdfshortcut.LaunchOptions.value = (name + ".json").toStdString();
@@ -195,11 +172,11 @@ bool UIModel::addToSteam(QVariant shortcut)
// DevkitOverrideAppID; default
// LastPlayTime; default
auto maybeIcon = map["icon"].toString();
- if (maybeIcon.isEmpty())
- {
+ if (maybeIcon.isEmpty()) {
if (launch && !maybeLaunchPath.isEmpty())
vdfshortcut.icon.value = maybeLaunchPath.toStdString();
- } else {
+ }
+ else {
vdfshortcut.icon.value = maybeIcon.toStdString();
}
// Add installed locally and GlosSI tag
@@ -217,19 +194,16 @@ bool UIModel::addToSteam(QVariant shortcut)
const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + shortcutsfile_.toStdWString();
return VDFParser::Parser::writeShortcuts(config_path, shortcuts_vdf_);
-
}
bool UIModel::removeFromSteam(const QString& name)
{
auto& scuts = shortcuts_vdf_.shortcuts;
- scuts.erase(std::remove_if(scuts.begin(), scuts.end(), [&name](const auto& shortcut)
- {
- return shortcut.appName.value == name.toStdString();
- }), scuts.end());
- for (int i = 0; i < scuts.size(); i++)
- {
- if (scuts[i].idx != i)
- {
+ scuts.erase(std::remove_if(scuts.begin(), scuts.end(), [&name](const auto& shortcut) {
+ return shortcut.appName.value == name.toStdString();
+ }),
+ scuts.end());
+ for (int i = 0; i < scuts.size(); i++) {
+ if (scuts[i].idx != i) {
scuts[i].idx = i;
}
}
@@ -240,232 +214,7 @@ bool UIModel::removeFromSteam(const QString& name)
#ifdef _WIN32
QVariantList UIModel::uwpApps()
{
- // TODO really should do this async, and notify gui when complete...
- if (!IsWindows10OrGreater())
- {
- return QVariantList();
- }
-
- std::vector logoNames{
- L"Square150x150Logo",
- L"Square310x310Logo",
- L"Square44x44Logo",
- L"Square71x71Logo",
- L"Square70x70Logo",
- L"Logo",
- L"SmallLogo",
- L"Square30x30Logo",
- };
-
- QVariantList pairs;
- // is it considered stealing when you take code that was pull-requested by someone else into your own repo?
- // Anyway... Stolen from: https://github.com/Thracky/GloSC/commit/3cd92e058498e3ab9d73ced140bbd7e490f639a7
- // https://github.com/Alia5/GloSC/commit/3cd92e058498e3ab9d73ced140bbd7e490f639a7
-
-
- // TODO: only return apps for current user.
- // TODO: I have no clue how this WinRT shit works; HELP MEH!
-
- PackageManager^ packageManager = ref new PackageManager();
- IIterable^ packages = packageManager->FindPackages();
-
- int packageCount = 0;
- // Only way to get the count of packages is to iterate through the whole collection first
- std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
- [&](Windows::ApplicationModel::Package^ package)
- {
- packageCount += 1;
- });
-
- int currPackage = 0;
- // Iterate through all the packages
- std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
- [&](Windows::ApplicationModel::Package^ package)
- {
- QGuiApplication::processEvents();
- HRESULT hr = S_OK;
- IStream* inputStream = NULL;
- UINT32 pathLen = 0;
- IAppxManifestReader* manifestReader = NULL;
- IAppxFactory* appxFactory = NULL;
- LPWSTR appId = NULL;
- LPWSTR manifestAppName = NULL;
- LPWSTR iconName = NULL;
-
- // Get the package path on disk so we can load the manifest XML and get the PRAID
- GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, NULL);
-
- if (pathLen > 0) {
-
- // Length of the path + "\\AppxManifest.xml" that we'll be appending
- UINT32 manifestLen = pathLen + 20;
- PWSTR pathBuf = (PWSTR)malloc(manifestLen * sizeof(wchar_t));
-
- GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, pathBuf);
- PWSTR manifest_xml = L"\\AppxManifest.xml";
-
- hr = StringCchCatW(pathBuf, manifestLen, manifest_xml);
-
- // Let's ignore a bunch of built in apps and such
- if (wcsstr(pathBuf, L"SystemApps")) {
- hr = E_FAIL;
- }
- else if (wcsstr(pathBuf, L".NET.Native."))
- hr = E_FAIL;
- else if (wcsstr(pathBuf, L".VCLibs."))
- hr = E_FAIL;
- else if (wcsstr(pathBuf, L"Microsoft.UI"))
- hr = E_FAIL;
- else if (wcsstr(pathBuf, L"Microsoft.Advertising"))
- hr = E_FAIL;
- else if (wcsstr(pathBuf, L"Microsoft.Services.Store"))
- hr = E_FAIL;
-
- BOOL hasCurrent = FALSE;
-
- // Open the manifest XML
- if (SUCCEEDED(hr)) {
-
- hr = SHCreateStreamOnFileEx(
- pathBuf,
- STGM_READ | STGM_SHARE_EXCLUSIVE,
- 0, // default file attributes
- FALSE, // do not create new file
- NULL, // no template
- &inputStream);
- }
- if (SUCCEEDED(hr)) {
-
- hr = CoCreateInstance(
- __uuidof(AppxFactory),
- NULL,
- CLSCTX_INPROC_SERVER,
- __uuidof(IAppxFactory),
- (LPVOID*)(&appxFactory));
- }
- if (SUCCEEDED(hr)) {
- hr = appxFactory->CreateManifestReader(inputStream, &manifestReader);
- }
-
- // Grab application ID (PRAID) and DisplayName from the XML
- if (SUCCEEDED(hr)) {
- IAppxManifestApplicationsEnumerator* applications = NULL;
- manifestReader->GetApplications(&applications);
- if (SUCCEEDED(hr)) {
- hr = applications->GetHasCurrent(&hasCurrent);
- if (hasCurrent) {
- IAppxManifestApplication* application = NULL;
- hr = applications->GetCurrent(&application);
- if (SUCCEEDED(hr)) {
- application->GetStringValue(L"Id", &appId);
- application->GetStringValue(L"DisplayName", &manifestAppName);
- for (auto& logoNameStr : logoNames)
- {
- application->GetStringValue(logoNameStr.c_str(), &iconName);
- if (!std::wstring(iconName).empty())
- {
- break;
- }
- }
- application->Release();
- }
- }
- else {
- hr = S_FALSE;
- }
- applications->Release();
- }
- manifestReader->Release();
- inputStream->Release();
-
- }
-
- if (SUCCEEDED(hr)) {
- PWSTR appNameBuf;
- QString AppUMId = QString::fromWCharArray(package->Id->FamilyName->Data());
- QString AppName;
- QString Path = QString::fromWCharArray(package->EffectivePath->Data());
- // QString thumbToken = QString::fromWCharArray(package->GetThumbnailToken()->Data());
- if (manifestAppName != NULL)
- {
- // If the display name is an indirect string, we'll try and load it using SHLoadIndirectString
- if (wcsstr(manifestAppName, L"ms-resource:"))
- {
- PWSTR res_name = wcsdup(&manifestAppName[12]);
- appNameBuf = (PWSTR)malloc(1026);
- LPCWSTR resource_str = L"@{";
- std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/resources/" + res_name + L"}";
- PCWSTR res_str = reslookup.c_str();
- hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
- // Try several resource paths
- if (!SUCCEEDED(hr)) {
- std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/Resources/" + res_name + L"}";
- PCWSTR res_str = reslookup.c_str();
- hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
- // If the third one doesn't work, we give up and use the package name from PackageManager
- if (!SUCCEEDED(hr)) {
- std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/" + res_name + L"}";
- PCWSTR res_str = reslookup.c_str();
- hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
- }
- }
-
- if (!SUCCEEDED(hr))
- AppName = QString::fromWCharArray(package->DisplayName->Data());
- else
- AppName = QString::fromWCharArray(appNameBuf);
- free(appNameBuf);
- }
- else
- {
- appNameBuf = manifestAppName;
- AppName = QString::fromWCharArray(appNameBuf);
- }
-
- }
- else {
- AppName = QString::fromWCharArray(package->DisplayName->Data());
- }
-
- QString PRAID = QString::fromWCharArray(appId);
- CoTaskMemFree(appId);
- if (!PRAID.isEmpty()) {
- AppUMId = AppUMId.append("!");
- AppUMId = AppUMId.append(PRAID);
- }
- QVariantMap uwpPair;
- uwpPair.insert("AppName", AppName);
- uwpPair.insert("AppUMId", AppUMId);
- uwpPair.insert("Path", Path);
-
- QString icoFName = Path + "/" + QString::fromWCharArray(iconName);
- std::filesystem::path icoPath(icoFName.toStdString());
-
- std::vector possibleextensions = { ".scale-100", ".scale-125", ".scale-150", ".scale-200" };
- if (!std::filesystem::exists(icoPath))
- {
- for (const auto& ext : possibleextensions)
- {
- QString maybeFname = QString(icoFName).replace(".png", ext + ".png");
- std::filesystem::path maybePath(maybeFname.toStdString());
- if (std::filesystem::exists(maybePath))
- {
- icoPath = maybePath;
- break;
- }
- }
- }
-
- uwpPair.insert("IconPath", QString::fromStdString(icoPath.string()));
-
- free(pathBuf);
-
- pairs.push_back(uwpPair);
- }
- }
- currPackage += 1;
- });
- return pairs;
+ return UWPFetch::UWPAppList();
}
#endif
@@ -491,8 +240,7 @@ void UIModel::writeTarget(const QJsonObject& json, const QString& name)
path /= config_dir_name_.toStdString();
path /= (name + ".json").toStdString();
QFile file(path);
- if (!file.open(QIODevice::Text | QIODevice::ReadWrite))
- {
+ if (!file.open(QIODevice::Text | QIODevice::ReadWrite)) {
// meh
return;
}
@@ -527,7 +275,7 @@ std::filesystem::path UIModel::getSteamPath() const
#ifdef _WIN32
// TODO: check if keys/value exist
// steam should always be open and have written reg values...
- winreg::RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam" };
+ winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"};
const auto res = key.GetStringValue(L"SteamPath");
return res;
#else
@@ -540,7 +288,7 @@ std::wstring UIModel::getSteamUserId() const
#ifdef _WIN32
// TODO: check if keys/value exist
// steam should always be open and have written reg values...
- winreg::RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess" };
+ winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"};
const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser"));
return res;
#else
diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h
index 19d09db..f706d45 100644
--- a/GlosSIConfig/UIModel.h
+++ b/GlosSIConfig/UIModel.h
@@ -14,23 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
-#include
+#include "VDFParser.h"
+#include
#include
#include
-#include
-#include "VDFParser.h"
-
+#include
-class UIModel : public QObject
-{
+class UIModel : public QObject {
Q_OBJECT
- Q_PROPERTY(bool isWindows READ getIsWindows CONSTANT)
- Q_PROPERTY(bool hasAcrlyicEffect READ hasAcrylicEffect NOTIFY acrylicChanged)
- Q_PROPERTY(QVariantList targetList READ getTargetList NOTIFY targetListChanged)
- Q_PROPERTY(QVariantList uwpList READ uwpApps CONSTANT)
+ Q_PROPERTY(bool isWindows READ getIsWindows CONSTANT)
+ Q_PROPERTY(bool hasAcrlyicEffect READ hasAcrylicEffect NOTIFY acrylicChanged)
+ Q_PROPERTY(QVariantList targetList READ getTargetList NOTIFY targetListChanged)
+ Q_PROPERTY(QVariantList uwpList READ uwpApps CONSTANT)
-public:
+ public:
UIModel();
Q_INVOKABLE void readConfigs();
@@ -49,17 +47,16 @@ public:
[[nodiscard]] bool hasAcrylicEffect() const;
void setAcrylicEffect(bool has_acrylic_affect);
-signals:
+ signals:
void acrylicChanged();
void targetListChanged();
-private:
+ private:
std::filesystem::path config_path_;
QString config_dir_name_;
void writeTarget(const QJsonObject& json, const QString& name);
-
std::filesystem::path getSteamPath() const;
std::wstring getSteamUserId() const;
void parseShortcutVDF();
diff --git a/GlosSIConfig/UWPFetch.h b/GlosSIConfig/UWPFetch.h
new file mode 100644
index 0000000..330948a
--- /dev/null
+++ b/GlosSIConfig/UWPFetch.h
@@ -0,0 +1,237 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#pragma comment(lib, "Shlwapi.lib")
+using namespace Windows::Management::Deployment;
+using namespace Windows::Foundation::Collections;
+
+namespace UWPFetch {
+
+QVariantList UWPAppList()
+{
+ // TODO really should do this async, and notify gui when complete...
+ if (!IsWindows10OrGreater()) {
+ return QVariantList();
+ }
+
+ std::vector logoNames{
+ L"Square150x150Logo",
+ L"Square310x310Logo",
+ L"Square44x44Logo",
+ L"Square71x71Logo",
+ L"Square70x70Logo",
+ L"Logo",
+ L"SmallLogo",
+ L"Square30x30Logo",
+ };
+
+ QVariantList pairs;
+ // is it considered stealing when you take code that was pull-requested by someone else into your own repo?
+ // Anyway... Stolen from: https://github.com/Thracky/GloSC/commit/3cd92e058498e3ab9d73ced140bbd7e490f639a7
+ // https://github.com/Alia5/GloSC/commit/3cd92e058498e3ab9d73ced140bbd7e490f639a7
+
+ // TODO: only return apps for current user.
+ // TODO: I have no clue how this WinRT shit works; HELP MEH!
+
+ // BTW: This config app needs to run as admin, in order to modify steams shortcuts.vdf
+ // This won't hopefully be a problem fetching UWP apps for a specific user?
+
+ PackageManager ^ packageManager = ref new PackageManager();
+ IIterable ^ packages = packageManager->FindPackages();
+
+ int packageCount = 0;
+ // Only way to get the count of packages is to iterate through the whole collection first
+ std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
+ [&](Windows::ApplicationModel::Package ^ package) {
+ packageCount += 1;
+ });
+
+ int currPackage = 0;
+ // Iterate through all the packages
+ std::for_each(Windows::Foundation::Collections::begin(packages), Windows::Foundation::Collections::end(packages),
+ [&](Windows::ApplicationModel::Package ^ package) {
+ QGuiApplication::processEvents();
+ HRESULT hr = S_OK;
+ IStream* inputStream = NULL;
+ UINT32 pathLen = 0;
+ IAppxManifestReader* manifestReader = NULL;
+ IAppxFactory* appxFactory = NULL;
+ LPWSTR appId = NULL;
+ LPWSTR manifestAppName = NULL;
+ LPWSTR iconName = NULL;
+
+ // Get the package path on disk so we can load the manifest XML and get the PRAID
+ GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, NULL);
+
+ if (pathLen > 0) {
+
+ // Length of the path + "\\AppxManifest.xml" that we'll be appending
+ UINT32 manifestLen = pathLen + 20;
+ PWSTR pathBuf = (PWSTR)malloc(manifestLen * sizeof(wchar_t));
+
+ GetPackagePathByFullName(package->Id->FullName->Data(), &pathLen, pathBuf);
+ PWSTR manifest_xml = L"\\AppxManifest.xml";
+
+ hr = StringCchCatW(pathBuf, manifestLen, manifest_xml);
+
+ // Let's ignore a bunch of built in apps and such
+ if (wcsstr(pathBuf, L"SystemApps")) {
+ hr = E_FAIL;
+ }
+ else if (wcsstr(pathBuf, L".NET.Native."))
+ hr = E_FAIL;
+ else if (wcsstr(pathBuf, L".VCLibs."))
+ hr = E_FAIL;
+ else if (wcsstr(pathBuf, L"Microsoft.UI"))
+ hr = E_FAIL;
+ else if (wcsstr(pathBuf, L"Microsoft.Advertising"))
+ hr = E_FAIL;
+ else if (wcsstr(pathBuf, L"Microsoft.Services.Store"))
+ hr = E_FAIL;
+
+ BOOL hasCurrent = FALSE;
+
+ // Open the manifest XML
+ if (SUCCEEDED(hr)) {
+
+ hr = SHCreateStreamOnFileEx(
+ pathBuf,
+ STGM_READ | STGM_SHARE_EXCLUSIVE,
+ 0, // default file attributes
+ FALSE, // do not create new file
+ NULL, // no template
+ &inputStream);
+ }
+ if (SUCCEEDED(hr)) {
+
+ hr = CoCreateInstance(
+ __uuidof(AppxFactory),
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(IAppxFactory),
+ (LPVOID*)(&appxFactory));
+ }
+ if (SUCCEEDED(hr)) {
+ hr = appxFactory->CreateManifestReader(inputStream, &manifestReader);
+ }
+
+ // Grab application ID (PRAID) and DisplayName from the XML
+ if (SUCCEEDED(hr)) {
+ IAppxManifestApplicationsEnumerator* applications = NULL;
+ manifestReader->GetApplications(&applications);
+ if (SUCCEEDED(hr)) {
+ hr = applications->GetHasCurrent(&hasCurrent);
+ if (hasCurrent) {
+ IAppxManifestApplication* application = NULL;
+ hr = applications->GetCurrent(&application);
+ if (SUCCEEDED(hr)) {
+ application->GetStringValue(L"Id", &appId);
+ application->GetStringValue(L"DisplayName", &manifestAppName);
+ for (auto& logoNameStr : logoNames) {
+ application->GetStringValue(logoNameStr.c_str(), &iconName);
+ if (!std::wstring(iconName).empty()) {
+ break;
+ }
+ }
+ application->Release();
+ }
+ }
+ else {
+ hr = S_FALSE;
+ }
+ applications->Release();
+ }
+ manifestReader->Release();
+ inputStream->Release();
+ }
+
+ if (SUCCEEDED(hr)) {
+ PWSTR appNameBuf;
+ QString AppUMId = QString::fromWCharArray(package->Id->FamilyName->Data());
+ QString AppName;
+ QString Path = QString::fromWCharArray(package->EffectivePath->Data());
+ // QString thumbToken = QString::fromWCharArray(package->GetThumbnailToken()->Data());
+ if (manifestAppName != NULL) {
+ // If the display name is an indirect string, we'll try and load it using SHLoadIndirectString
+ if (wcsstr(manifestAppName, L"ms-resource:")) {
+ PWSTR res_name = wcsdup(&manifestAppName[12]);
+ appNameBuf = (PWSTR)malloc(1026);
+ LPCWSTR resource_str = L"@{";
+ std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/resources/" + res_name + L"}";
+ PCWSTR res_str = reslookup.c_str();
+ hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
+ // Try several resource paths
+ if (!SUCCEEDED(hr)) {
+ std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/Resources/" + res_name + L"}";
+ PCWSTR res_str = reslookup.c_str();
+ hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
+ // If the third one doesn't work, we give up and use the package name from PackageManager
+ if (!SUCCEEDED(hr)) {
+ std::wstring reslookup = std::wstring(resource_str) + package->Id->FullName->Data() + L"?ms-resource://" + package->Id->Name->Data() + L"/" + res_name + L"}";
+ PCWSTR res_str = reslookup.c_str();
+ hr = SHLoadIndirectString(res_str, appNameBuf, 512, NULL);
+ }
+ }
+
+ if (!SUCCEEDED(hr))
+ AppName = QString::fromWCharArray(package->DisplayName->Data());
+ else
+ AppName = QString::fromWCharArray(appNameBuf);
+ free(appNameBuf);
+ }
+ else {
+ appNameBuf = manifestAppName;
+ AppName = QString::fromWCharArray(appNameBuf);
+ }
+ }
+ else {
+ AppName = QString::fromWCharArray(package->DisplayName->Data());
+ }
+
+ QString PRAID = QString::fromWCharArray(appId);
+ CoTaskMemFree(appId);
+ if (!PRAID.isEmpty()) {
+ AppUMId = AppUMId.append("!");
+ AppUMId = AppUMId.append(PRAID);
+ }
+ QVariantMap uwpPair;
+ uwpPair.insert("AppName", AppName);
+ uwpPair.insert("AppUMId", AppUMId);
+ uwpPair.insert("Path", Path);
+
+ QString icoFName = Path + "/" + QString::fromWCharArray(iconName);
+ std::filesystem::path icoPath(icoFName.toStdString());
+
+ std::vector possibleextensions = {".scale-100", ".scale-125", ".scale-150", ".scale-200"};
+ if (!std::filesystem::exists(icoPath)) {
+ for (const auto& ext : possibleextensions) {
+ QString maybeFname = QString(icoFName).replace(".png", ext + ".png");
+ std::filesystem::path maybePath(maybeFname.toStdString());
+ if (std::filesystem::exists(maybePath)) {
+ icoPath = maybePath;
+ break;
+ }
+ }
+ }
+
+ uwpPair.insert("IconPath", QString::fromStdString(icoPath.string()));
+
+ free(pathBuf);
+
+ pairs.push_back(uwpPair);
+ }
+ }
+ currPackage += 1;
+ });
+ return pairs;
+}
+
+} // namespace UWPFetch
\ No newline at end of file
diff --git a/GlosSIConfig/VDFParser.h b/GlosSIConfig/VDFParser.h
index 4300611..ec16169 100644
--- a/GlosSIConfig/VDFParser.h
+++ b/GlosSIConfig/VDFParser.h
@@ -17,593 +17,545 @@ limitations under the License.
// "Shitty shortcuts.vdf Parser"�
#pragma once
+#include
#include
+#include
+#include
#include
#include
-#include
-#include
-#include
-namespace VDFParser
+namespace VDFParser {
+namespace crc {
+template
+uint32_t calculate_crc(CONT container)
{
- namespace crc
- {
- template
- uint32_t calculate_crc(CONT container)
- {
- uint32_t crc32_table[256];
- for (uint32_t i = 0; i < 256; i++) {
- uint32_t ch = i;
- uint32_t crc = 0;
- for (size_t j = 0; j < 8; j++) {
- uint32_t b = (ch ^ crc) & 1;
- crc >>= 1;
- if (b) crc = crc ^ 0xEDB88320;
- ch >>= 1;
- }
- crc32_table[i] = crc;
- }
- uint32_t crc = 0xFFFFFFFF;
- for (size_t i = 0; i < container.size(); i++) {
- char ch = container.data()[i];
- uint32_t t = (ch ^ crc) & 0xFF;
- crc = (crc >> 8) ^ crc32_table[t];
- }
- return ~crc;
+ uint32_t crc32_table[256];
+ for (uint32_t i = 0; i < 256; i++) {
+ uint32_t ch = i;
+ uint32_t crc = 0;
+ for (size_t j = 0; j < 8; j++) {
+ uint32_t b = (ch ^ crc) & 1;
+ crc >>= 1;
+ if (b)
+ crc = crc ^ 0xEDB88320;
+ ch >>= 1;
}
+ crc32_table[i] = crc;
}
-
- static constexpr const char k_appid[] = { "appid" };
- static constexpr const char k_appname[] = { "appname" };
- static constexpr const char k_exe[] = { "exe" };
- static constexpr const char k_StartDir[] = { "StartDir" };
- static constexpr const char k_icon[] = { "icon" };
- static constexpr const char k_ShortcutPath[] = { "ShortcutPath" };
- static constexpr const char k_LaunchOptions[] = { "LaunchOptions" };
- static constexpr const char k_IsHidden[] = { "IsHidden" };
- static constexpr const char k_AllowDesktopConfig[] = { "AllowDesktopConfig" };
- static constexpr const char k_AllowOverlay[] = { "AllowOverlay" };
- static constexpr const char k_openvr[] = { "openvr" };
- static constexpr const char k_Devkit[] = { "Devkit" };
- static constexpr const char k_DevkitGameID[] = { "DevkitGameID" };
- static constexpr const char k_DevkitOverrideAppID[] = { "DevkitOverrideAppID" };
- static constexpr const char k_LastPlayTime[] = { "LastPlayTime" };
- static constexpr const char k_tags[] = { "tags" };
-
- enum VDFTypeId
+ uint32_t crc = 0xFFFFFFFF;
+ for (size_t i = 0; i < container.size(); i++) {
+ char ch = container.data()[i];
+ uint32_t t = (ch ^ crc) & 0xFF;
+ crc = (crc >> 8) ^ crc32_table[t];
+ }
+ return ~crc;
+}
+} // namespace crc
+
+static constexpr const char k_appid[] = {"appid"};
+static constexpr const char k_appname[] = {"appname"};
+static constexpr const char k_exe[] = {"exe"};
+static constexpr const char k_StartDir[] = {"StartDir"};
+static constexpr const char k_icon[] = {"icon"};
+static constexpr const char k_ShortcutPath[] = {"ShortcutPath"};
+static constexpr const char k_LaunchOptions[] = {"LaunchOptions"};
+static constexpr const char k_IsHidden[] = {"IsHidden"};
+static constexpr const char k_AllowDesktopConfig[] = {"AllowDesktopConfig"};
+static constexpr const char k_AllowOverlay[] = {"AllowOverlay"};
+static constexpr const char k_openvr[] = {"openvr"};
+static constexpr const char k_Devkit[] = {"Devkit"};
+static constexpr const char k_DevkitGameID[] = {"DevkitGameID"};
+static constexpr const char k_DevkitOverrideAppID[] = {"DevkitOverrideAppID"};
+static constexpr const char k_LastPlayTime[] = {"LastPlayTime"};
+static constexpr const char k_tags[] = {"tags"};
+
+enum VDFTypeId {
+ StringList = 0,
+ String,
+ Number,
+};
+
+template
+struct VDFKeyPair {
+ VDFKeyPair() {}
+ explicit VDFKeyPair(type _value) : value(_value) {}
+ static constexpr uint8_t _TID = _type_id;
+ static constexpr const char* const _KEY = keyname;
+ const uint8_t type_id = _TID;
+ const char* const key = _KEY;
+ type value;
+ VDFKeyPair(const VDFKeyPair& other)
{
- StringList = 0,
- String,
- Number,
+ value = other.value;
};
-
- template
- struct VDFKeyPair
+ VDFKeyPair(VDFKeyPair&& other)
{
- VDFKeyPair() {}
- explicit VDFKeyPair(type _value) : value(_value) {}
- static constexpr uint8_t _TID = _type_id;
- static constexpr const char* const _KEY = keyname;
- const uint8_t type_id = _TID;
- const char* const key = _KEY;
- type value;
- VDFKeyPair(const VDFKeyPair& other)
- {
- value = other.value;
- };
- VDFKeyPair(VDFKeyPair&& other)
- {
- value = std::move(other.value);
- };
- VDFKeyPair& operator=(const VDFKeyPair& other)
- {
- value = other.value;
- return *this;
- }
- VDFKeyPair& operator=(VDFKeyPair&& other)
- {
- value = std::move(other.value);
- return *this;
- }
+ value = std::move(other.value);
};
+ VDFKeyPair& operator=(const VDFKeyPair& other)
+ {
+ value = other.value;
+ return *this;
+ }
+ VDFKeyPair& operator=(VDFKeyPair&& other)
+ {
+ value = std::move(other.value);
+ return *this;
+ }
+};
- template
- struct VDFIdx
+template
+struct VDFIdx {
+ VDFIdx(){};
+ VDFIdx(const VDFIdx& other)
{
- VDFIdx() {};
- VDFIdx(const VDFIdx& other)
- {
- data[0] = other.data[0];
- data[1] = other.data[1];
- };
- VDFIdx(VDFIdx&& other)
- {
- data[0] = std::move(other.data[0]);
- data[1] = std::move(other.data[1]);
- };
- VDFIdx(int idx)
- {
- if (idx > 99)
- {
- data[0] = initialByte;
- data[1] = 0;
- }
- else if (idx < 10)
- {
- data[1] = std::to_string(idx).c_str()[0];
- }
- else
- {
- auto meh = std::to_string(idx).c_str();
- data[0] = meh[0] + initialByte;
- data[1] = meh[1];
- }
+ data[0] = other.data[0];
+ data[1] = other.data[1];
+ };
+ VDFIdx(VDFIdx&& other)
+ {
+ data[0] = std::move(other.data[0]);
+ data[1] = std::move(other.data[1]);
+ };
+ VDFIdx(int idx)
+ {
+ if (idx > 99) {
+ data[0] = initialByte;
+ data[1] = 0;
}
- char data[2] = { initialByte, 0x0 };
- operator int() const {
- if (data[0] == initialByte)
- {
- int res = 0;
- std::from_chars(&data[1], &data[1], res);
- return res;
- }
+ else if (idx < 10) {
+ data[1] = std::to_string(idx).c_str()[0];
+ }
+ else {
+ auto meh = std::to_string(idx).c_str();
+ data[0] = meh[0] + initialByte;
+ data[1] = meh[1];
+ }
+ }
+ char data[2] = {initialByte, 0x0};
+ operator int() const
+ {
+ if (data[0] == initialByte) {
int res = 0;
- char copy[2] = { data[0] - initialByte, data[1]};
- std::from_chars(©[0], ©[1], res);
+ std::from_chars(&data[1], &data[1], res);
return res;
}
+ int res = 0;
+ char copy[2] = {data[0] - initialByte, data[1]};
+ std::from_chars(©[0], ©[1], res);
+ return res;
+ }
- VDFIdx& operator=(const VDFIdx& other)
- {
- data[0] = other.data[0];
- data[1] = other.data[1];
- return *this;
- }
- VDFIdx& operator=(VDFIdx&& other)
- {
- data[0] = std::move(other.data[0]);
- data[1] = std::move(other.data[1]);
- return *this;
- }
- };
+ VDFIdx& operator=(const VDFIdx& other)
+ {
+ data[0] = other.data[0];
+ data[1] = other.data[1];
+ return *this;
+ }
+ VDFIdx& operator=(VDFIdx&& other)
+ {
+ data[0] = std::move(other.data[0]);
+ data[1] = std::move(other.data[1]);
+ return *this;
+ }
+};
- struct ShortcutTag
+struct ShortcutTag {
+ ShortcutTag(){};
+ ShortcutTag(const ShortcutTag& other)
{
- ShortcutTag() {};
- ShortcutTag(const ShortcutTag& other)
- {
- value = other.value;
- };
- ShortcutTag(ShortcutTag&& other)
- {
- value = std::move(other.value);
- };
- VDFIdx<0x01> idx; // I Hope this is how it works... See VDFIdx
- std::string value;
- const uint16_t end_marker = 0x0808;
-
- ShortcutTag& operator=(const ShortcutTag& other)
- {
- value = other.value;
- return *this;
- }
- ShortcutTag& operator=(ShortcutTag&& other)
- {
- value = std::move(other.value);
- return *this;
- }
+ value = other.value;
+ };
+ ShortcutTag(ShortcutTag&& other)
+ {
+ value = std::move(other.value);
};
+ VDFIdx<0x01> idx; // I Hope this is how it works... See VDFIdx
+ std::string value;
+ const uint16_t end_marker = 0x0808;
- struct Shortcut
+ ShortcutTag& operator=(const ShortcutTag& other)
{
- VDFIdx<0x00> idx;
- VDFKeyPair appId{ 0x000000 };
- VDFKeyPair appName{ "" };
- VDFKeyPair exe{ "\"\"" }; // Qouted
- VDFKeyPair StartDir{ "\"\"" }; // Qouted
- VDFKeyPair icon{ "" }; // Qouted or empty
- VDFKeyPair ShortcutPath{ "" }; // Qouted or empty?
- VDFKeyPair LaunchOptions{ "" }; // UNQOUTED or empty
- VDFKeyPair IsHidden{ 0 };
- VDFKeyPair AllowDesktopConfig{ 1 };
- VDFKeyPair AllowOverlay{ 1 };
- VDFKeyPair openvr{ 0 };
- VDFKeyPair Devkit{ 0 };
- VDFKeyPair DevkitGameID{ "" };
- VDFKeyPair DevkitOverrideAppID{ 0 }; //
- VDFKeyPair LastPlayTime{ 0 }; //
- VDFKeyPair, VDFTypeId::StringList> tags{ };
- Shortcut& operator=(const Shortcut& other)
- {
- idx = other.idx;
- appId = other.appId;
- appName = other.appName;
- exe = other.exe;
- StartDir = other.StartDir;
- icon = other.icon;
- ShortcutPath = other.ShortcutPath;
- LaunchOptions = other.LaunchOptions;
- LaunchOptions = other.LaunchOptions;
- IsHidden = other.IsHidden;
- AllowDesktopConfig = other.AllowDesktopConfig;
- AllowOverlay = other.AllowOverlay;
- openvr = other.openvr;
- Devkit = other.Devkit;
- DevkitGameID = other.DevkitGameID;
- DevkitOverrideAppID = other.DevkitOverrideAppID;
- LastPlayTime = other.LastPlayTime;
- tags = other.tags;
- return *this;
- }
+ value = other.value;
+ return *this;
+ }
+ ShortcutTag& operator=(ShortcutTag&& other)
+ {
+ value = std::move(other.value);
+ return *this;
+ }
+};
+
+struct Shortcut {
+ VDFIdx<0x00> idx;
+ VDFKeyPair appId{0x000000};
+ VDFKeyPair appName{""};
+ VDFKeyPair exe{"\"\""}; // Qouted
+ VDFKeyPair StartDir{"\"\""}; // Qouted
+ VDFKeyPair icon{""}; // Qouted or empty
+ VDFKeyPair ShortcutPath{""}; // Qouted or empty?
+ VDFKeyPair LaunchOptions{""}; // UNQOUTED or empty
+ VDFKeyPair IsHidden{0};
+ VDFKeyPair AllowDesktopConfig{1};
+ VDFKeyPair AllowOverlay{1};
+ VDFKeyPair openvr{0};
+ VDFKeyPair Devkit{0};
+ VDFKeyPair DevkitGameID{""};
+ VDFKeyPair DevkitOverrideAppID{0}; //
+ VDFKeyPair LastPlayTime{0}; //
+ VDFKeyPair, VDFTypeId::StringList> tags{};
+ Shortcut& operator=(const Shortcut& other)
+ {
+ idx = other.idx;
+ appId = other.appId;
+ appName = other.appName;
+ exe = other.exe;
+ StartDir = other.StartDir;
+ icon = other.icon;
+ ShortcutPath = other.ShortcutPath;
+ LaunchOptions = other.LaunchOptions;
+ LaunchOptions = other.LaunchOptions;
+ IsHidden = other.IsHidden;
+ AllowDesktopConfig = other.AllowDesktopConfig;
+ AllowOverlay = other.AllowOverlay;
+ openvr = other.openvr;
+ Devkit = other.Devkit;
+ DevkitGameID = other.DevkitGameID;
+ DevkitOverrideAppID = other.DevkitOverrideAppID;
+ LastPlayTime = other.LastPlayTime;
+ tags = other.tags;
+ return *this;
+ }
+};
+
+struct VDFFile {
+ VDFFile(){};
+ VDFFile(const VDFFile& other)
+ {
+ shortcuts = other.shortcuts;
+ };
+ VDFFile(VDFFile&& other)
+ {
+ shortcuts = std::move(other.shortcuts);
};
+ const uint8_t first_byte = 0x00;
+ const std::string identifier = "shortcuts";
+ std::vector shortcuts;
+ const uint16_t end_marker = 0x0808;
+ VDFFile& operator=(const VDFFile& other)
+ {
+ shortcuts = other.shortcuts;
+ return *this;
+ }
+ VDFFile& operator=(VDFFile&& other)
+ {
+ shortcuts = std::move(other.shortcuts);
+ return *this;
+ }
+};
+
+class Parser {
+ private:
+ static inline std::ifstream ifile;
+ static inline std::ofstream ofile;
- struct VDFFile
+ template
+ static inline auto readVDFBuffer(typ& buff, size sz)
{
- VDFFile(){};
- VDFFile(const VDFFile& other)
- {
- shortcuts = other.shortcuts;
- };
- VDFFile(VDFFile&& other)
- {
- shortcuts = std::move(other.shortcuts);
- };
- const uint8_t first_byte = 0x00;
- const std::string identifier = "shortcuts";
- std::vector shortcuts;
- const uint16_t end_marker = 0x0808;
- VDFFile& operator=(const VDFFile& other)
- {
- shortcuts = other.shortcuts;
- return *this;
- }
- VDFFile& operator=(VDFFile&& other)
- {
- shortcuts = std::move(other.shortcuts);
- return *this;
+ if (ifile.eof()) {
+
+ return;
}
- };
+ ifile.read((char*)buff, sz);
+ }
- class Parser
+ template
+ static inline auto readVDFValue()
{
- private:
- static inline std::ifstream ifile;
- static inline std::ofstream ofile;
-
- template
- static inline auto readVDFBuffer(typ& buff,size sz)
- {
- if (ifile.eof())
- {
+ uint8_t buff[sizeof(typ)];
+ ifile.read((char*)buff, sizeof(typ));
+ return *reinterpret_cast(buff);
+ }
- return;
+ static inline std::string readVDFString()
+ {
+ std::string str;
+ char ch = '\x0';
+ do {
+ if (ifile.eof()) {
+ return str;
}
- ifile.read((char*)buff, sz);
- }
+ ifile.read(&ch, sizeof(char));
+ if (ch != '\x0')
+ str.push_back(ch);
+ } while (ch != '\x0');
+ return str;
+ }
- template
- static inline auto readVDFValue()
- {
- uint8_t buff[sizeof(typ)];
- ifile.read((char*)buff, sizeof(typ));
- return *reinterpret_cast(buff);
- }
+ public:
+ static inline uint32_t calculateAppId(const Shortcut& shortcut)
+ {
+ std::string buff = shortcut.exe.value + shortcut.appName.value;
+ auto checksum = crc::calculate_crc(buff);
+ return checksum | 0x80000000;
+ }
- static inline std::string readVDFString()
- {
- std::string str;
- char ch = '\x0';
- do
- {
- if (ifile.eof())
- {
- return str;
- }
- ifile.read(&ch, sizeof(char));
- if (ch != '\x0')
- str.push_back(ch);
- } while (ch != '\x0');
- return str;
- }
+ static inline VDFFile parseShortcuts(std::filesystem::path path)
+ {
+ VDFFile vdffile;
- public:
- static inline uint32_t calculateAppId(const Shortcut& shortcut)
- {
- std::string buff = shortcut.exe.value + shortcut.appName.value;
- auto checksum = crc::calculate_crc(buff);
- return checksum | 0x80000000;
+ ifile.open(path.string(), std::ios::binary | std::ios::in);
+ if (!ifile.is_open()) {
+ return {};
}
- static inline VDFFile parseShortcuts(std::filesystem::path path)
- {
- VDFFile vdffile;
+ auto firsty = readVDFValue();
+ if (vdffile.first_byte != firsty) {
+ // TODO: invalid
+ ifile.close();
+ return vdffile;
+ }
- ifile.open(path.string(), std::ios::binary | std::ios::in);
- if (!ifile.is_open())
- {
- return {};
- }
+ auto headername = readVDFString();
+ if (vdffile.identifier != headername) {
+ // TODO: invalid
+ ifile.close();
+ return vdffile;
+ }
- auto firsty = readVDFValue();
- if (vdffile.first_byte != firsty)
- {
- // TODO: invalid
- ifile.close();
- return vdffile;
+ char buff[3];
+ while (true) {
+ if (ifile.eof()) {
+ break;
}
-
- auto headername = readVDFString();
- if (vdffile.identifier != headername)
- {
- // TODO: invalid
- ifile.close();
- return vdffile;
+ readVDFBuffer(buff, 3); // 2 bytes idx, 0x00 delmiter
+ if (buff[0] == 0x08 && buff[1] == 0x08) {
+ break;
}
-
-
- char buff[3];
- while(true)
+ Shortcut shortcut;
+ shortcut.idx.data[0] = buff[0];
+ shortcut.idx.data[1] = buff[1];
+ while (true) // TODO;
{
- if (ifile.eof())
- {
- break;
- }
- readVDFBuffer(buff, 3); // 2 bytes idx, 0x00 delmiter
- if (buff[0] == 0x08 && buff[1] == 0x08)
- {
+ if (ifile.eof()) {
break;
}
- Shortcut shortcut;
- shortcut.idx.data[0] = buff[0]; shortcut.idx.data[1] = buff[1];
- while (true) // TODO;
- {
- if (ifile.eof())
- {
+ VDFTypeId tid = static_cast(readVDFValue());
+ if (tid == 0x08) {
+ auto nextbyte = readVDFValue();
+ if (nextbyte == 0x08) {
break;
}
- VDFTypeId tid = static_cast(readVDFValue());
- if (tid == 0x08)
- {
- auto nextbyte = readVDFValue();
- if (nextbyte == 0x08)
- {
+ else {
+ // WTF?!
+ // TODO:
+ throw std::exception("WTF");
+ }
+ }
+ auto key = readVDFString();
+ if ((tid == 0x08 && key[0] == 0x08) || key == "\x08\x08") {
+ break;
+ }
+ if (key == shortcut.appId.key) {
+ shortcut.appId.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.appName.key) {
+ shortcut.appName.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.exe.key) {
+ shortcut.exe.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.StartDir.key) {
+ shortcut.StartDir.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.icon.key) {
+ shortcut.icon.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.ShortcutPath.key) {
+ shortcut.ShortcutPath.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.LaunchOptions.key) {
+ shortcut.LaunchOptions.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.IsHidden.key) {
+ shortcut.IsHidden.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.AllowDesktopConfig.key) {
+ shortcut.AllowDesktopConfig.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.AllowOverlay.key) {
+ shortcut.AllowOverlay.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.openvr.key) {
+ shortcut.openvr.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.Devkit.key) {
+ shortcut.Devkit.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.DevkitGameID.key) {
+ shortcut.DevkitGameID.value = readVDFString();
+ continue;
+ }
+ if (key == shortcut.DevkitOverrideAppID.key) {
+ shortcut.DevkitOverrideAppID.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.LastPlayTime.key) {
+ shortcut.LastPlayTime.value = readVDFValue();
+ continue;
+ }
+ if (key == shortcut.tags.key) {
+ // TODO: read tags
+ ShortcutTag tag;
+ while (true) {
+ if (ifile.eof()) {
break;
- } else {
- // WTF?!
- // TODO:
- throw std::exception("WTF");
}
- }
- auto key = readVDFString();
- if ((tid == 0x08 && key[0] == 0x08) || key == "\x08\x08")
- {
- break;
- }
- if (key == shortcut.appId.key)
- {
- shortcut.appId.value = readVDFValue();
- continue;
- }
- if (key == shortcut.appName.key)
- {
- shortcut.appName.value = readVDFString();
- continue;
- }
- if (key == shortcut.exe.key)
- {
- shortcut.exe.value = readVDFString();
- continue;
- }
- if (key == shortcut.StartDir.key)
- {
- shortcut.StartDir.value = readVDFString();
- continue;
- }
- if (key == shortcut.icon.key)
- {
- shortcut.icon.value = readVDFString();
- continue;
- }
- if (key == shortcut.ShortcutPath.key)
- {
- shortcut.ShortcutPath.value = readVDFString();
- continue;
- }
- if (key == shortcut.LaunchOptions.key)
- {
- shortcut.LaunchOptions.value = readVDFString();
- continue;
- }
- if (key == shortcut.IsHidden.key)
- {
- shortcut.IsHidden.value = readVDFValue();
- continue;
- }
- if (key == shortcut.AllowDesktopConfig.key)
- {
- shortcut.AllowDesktopConfig.value = readVDFValue();
- continue;
- }
- if (key == shortcut.AllowOverlay.key)
- {
- shortcut.AllowOverlay.value = readVDFValue();
- continue;
- }
- if (key == shortcut.openvr.key)
- {
- shortcut.openvr.value = readVDFValue();
- continue;
- }
- if (key == shortcut.Devkit.key)
- {
- shortcut.Devkit.value = readVDFValue();
- continue;
- }
- if (key == shortcut.DevkitGameID.key)
- {
- shortcut.DevkitGameID.value = readVDFString();
- continue;
- }
- if (key == shortcut.DevkitOverrideAppID.key)
- {
- shortcut.DevkitOverrideAppID.value = readVDFValue();
- continue;
- }
- if (key == shortcut.LastPlayTime.key)
- {
- shortcut.LastPlayTime.value = readVDFValue();
- continue;
- }
- if (key == shortcut.tags.key)
- {
- // TODO: read tags
- ShortcutTag tag;
- while (true)
- {
- if (ifile.eof())
- {
- break;
- }
- char tbuff[2];
- readVDFBuffer(tbuff, 2); // 2 bytes idx
- if (tbuff[0] == 0x08 && tbuff[1] == 0x08)
- {
- ifile.seekg(-2, std::ios_base::cur);
- break;
- }
- tag.idx.data[0] = tbuff[0]; tag.idx.data[1] = tbuff[1];
- ifile.seekg(1, std::ios_base::cur);
- tag.value = readVDFString();
- shortcut.tags.value.push_back(tag);
+ char tbuff[2];
+ readVDFBuffer(tbuff, 2); // 2 bytes idx
+ if (tbuff[0] == 0x08 && tbuff[1] == 0x08) {
+ ifile.seekg(-2, std::ios_base::cur);
+ break;
}
- continue;
+ tag.idx.data[0] = tbuff[0];
+ tag.idx.data[1] = tbuff[1];
+ ifile.seekg(1, std::ios_base::cur);
+ tag.value = readVDFString();
+ shortcut.tags.value.push_back(tag);
}
-
- }
- if (!(shortcut.idx.data[0] == 0x0 && shortcut.idx.data[1] == 0x0))
- {
- vdffile.shortcuts.push_back(shortcut);
+ continue;
}
}
+ if (!(shortcut.idx.data[0] == 0x0 && shortcut.idx.data[1] == 0x0)) {
+ vdffile.shortcuts.push_back(shortcut);
+ }
+ }
- ifile.close();
+ ifile.close();
- return vdffile;
+ return vdffile;
+ }
+
+ static inline bool writeShortcuts(std::filesystem::path path, const VDFFile& vdffile)
+ {
+ ofile.open(path.string(), std::ios::binary | std::ios::out);
+ if (!ofile.is_open()) {
+ return false;
}
+ ofile.write((char*)&vdffile.first_byte, 1);
+ ofile.write(vdffile.identifier.data(), vdffile.identifier.length());
+ ofile.write("\x00", 1);
+ for (auto& shortcut : vdffile.shortcuts) {
+ ofile.write(shortcut.idx.data, 2);
+ ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.appId.type_id, 1);
+ ofile.write(shortcut.appId.key, 6);
+ ofile.write((char*)&shortcut.appId.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.appName.type_id, 1);
+ ofile.write(shortcut.appName.key, 8);
+ ofile.write(shortcut.appName.value.data(), shortcut.appName.value.length());
+ ofile.write("\x00", 1);
- static inline bool writeShortcuts(std::filesystem::path path, const VDFFile& vdffile)
- {
- ofile.open(path.string(), std::ios::binary | std::ios::out);
- if (!ofile.is_open())
- {
- return false;
- }
- ofile.write((char*)&vdffile.first_byte, 1);
- ofile.write(vdffile.identifier.data(), vdffile.identifier.length());
+ //
+ ofile.write((char*)&shortcut.exe.type_id, 1);
+ ofile.write(shortcut.exe.key, 4);
+ ofile.write(shortcut.exe.value.data(), shortcut.exe.value.length());
ofile.write("\x00", 1);
- for (auto& shortcut : vdffile.shortcuts)
- {
- ofile.write(shortcut.idx.data, 2);
- ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.appId.type_id, 1);
- ofile.write(shortcut.appId.key, 6);
- ofile.write((char*)&shortcut.appId.value, 4);
-
- //
- ofile.write((char*)&shortcut.appName.type_id, 1);
- ofile.write(shortcut.appName.key, 8);
- ofile.write(shortcut.appName.value.data(), shortcut.appName.value.length());
- ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.exe.type_id, 1);
- ofile.write(shortcut.exe.key, 4);
- ofile.write(shortcut.exe.value.data(), shortcut.exe.value.length());
- ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.StartDir.type_id, 1);
+ ofile.write(shortcut.StartDir.key, 9);
+ ofile.write(shortcut.StartDir.value.data(), shortcut.StartDir.value.length());
+ ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.StartDir.type_id, 1);
- ofile.write(shortcut.StartDir.key, 9);
- ofile.write(shortcut.StartDir.value.data(), shortcut.StartDir.value.length());
- ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.icon.type_id, 1);
+ ofile.write(shortcut.icon.key, 5);
+ ofile.write(shortcut.icon.value.data(), shortcut.icon.value.length());
+ ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.icon.type_id, 1);
- ofile.write(shortcut.icon.key, 5);
- ofile.write(shortcut.icon.value.data(), shortcut.icon.value.length());
- ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.ShortcutPath.type_id, 1);
+ ofile.write(shortcut.ShortcutPath.key, 13);
+ ofile.write(shortcut.ShortcutPath.value.data(), shortcut.ShortcutPath.value.length());
+ ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.ShortcutPath.type_id, 1);
- ofile.write(shortcut.ShortcutPath.key, 13);
- ofile.write(shortcut.ShortcutPath.value.data(), shortcut.ShortcutPath.value.length());
- ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.LaunchOptions.type_id, 1);
+ ofile.write(shortcut.LaunchOptions.key, 14);
+ ofile.write(shortcut.LaunchOptions.value.data(), shortcut.LaunchOptions.value.length());
+ ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.LaunchOptions.type_id, 1);
- ofile.write(shortcut.LaunchOptions.key, 14);
- ofile.write(shortcut.LaunchOptions.value.data(), shortcut.LaunchOptions.value.length());
- ofile.write("\x00", 1);
+ //
+ ofile.write((char*)&shortcut.IsHidden.type_id, 1);
+ ofile.write(shortcut.IsHidden.key, 9);
+ ofile.write((char*)&shortcut.IsHidden.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.AllowDesktopConfig.type_id, 1);
+ ofile.write(shortcut.AllowDesktopConfig.key, 19);
+ ofile.write((char*)&shortcut.AllowDesktopConfig.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.AllowOverlay.type_id, 1);
+ ofile.write(shortcut.AllowOverlay.key, 13);
+ ofile.write((char*)&shortcut.AllowOverlay.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.openvr.type_id, 1);
+ ofile.write(shortcut.openvr.key, 7);
+ ofile.write((char*)&shortcut.openvr.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.Devkit.type_id, 1);
+ ofile.write(shortcut.Devkit.key, 7);
+ ofile.write((char*)&shortcut.Devkit.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.DevkitGameID.type_id, 1);
+ ofile.write(shortcut.DevkitGameID.key, 13);
+ ofile.write(shortcut.DevkitGameID.value.data(), shortcut.DevkitGameID.value.length());
+ ofile.write("\x00", 1);
- //
- ofile.write((char*)&shortcut.IsHidden.type_id, 1);
- ofile.write(shortcut.IsHidden.key, 9);
- ofile.write((char*)&shortcut.IsHidden.value, 4);
-
- //
- ofile.write((char*)&shortcut.AllowDesktopConfig.type_id, 1);
- ofile.write(shortcut.AllowDesktopConfig.key, 19);
- ofile.write((char*)&shortcut.AllowDesktopConfig.value, 4);
-
- //
- ofile.write((char*)&shortcut.AllowOverlay.type_id, 1);
- ofile.write(shortcut.AllowOverlay.key, 13);
- ofile.write((char*)&shortcut.AllowOverlay.value, 4);
-
- //
- ofile.write((char*)&shortcut.openvr.type_id, 1);
- ofile.write(shortcut.openvr.key, 7);
- ofile.write((char*)&shortcut.openvr.value, 4);
-
- //
- ofile.write((char*)&shortcut.Devkit.type_id, 1);
- ofile.write(shortcut.Devkit.key, 7);
- ofile.write((char*)&shortcut.Devkit.value, 4);
-
- //
- ofile.write((char*)&shortcut.DevkitGameID.type_id, 1);
- ofile.write(shortcut.DevkitGameID.key, 13);
- ofile.write(shortcut.DevkitGameID.value.data(), shortcut.DevkitGameID.value.length());
+ //
+ ofile.write((char*)&shortcut.DevkitOverrideAppID.type_id, 1);
+ ofile.write(shortcut.DevkitOverrideAppID.key, 20);
+ ofile.write((char*)&shortcut.DevkitOverrideAppID.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.LastPlayTime.type_id, 1);
+ ofile.write(shortcut.LastPlayTime.key, 13);
+ ofile.write((char*)&shortcut.LastPlayTime.value, 4);
+
+ //
+ ofile.write((char*)&shortcut.tags.type_id, 1);
+ ofile.write(shortcut.tags.key, 5);
+ for (auto& tag : shortcut.tags.value) {
+ ofile.write(tag.idx.data, 2);
+ ofile.write("\x00", 1);
+ ofile.write(tag.value.data(), tag.value.length());
ofile.write("\x00", 1);
-
- //
- ofile.write((char*)&shortcut.DevkitOverrideAppID.type_id, 1);
- ofile.write(shortcut.DevkitOverrideAppID.key, 20);
- ofile.write((char*)&shortcut.DevkitOverrideAppID.value, 4);
-
- //
- ofile.write((char*)&shortcut.LastPlayTime.type_id, 1);
- ofile.write(shortcut.LastPlayTime.key, 13);
- ofile.write((char*)&shortcut.LastPlayTime.value, 4);
-
-
- //
- ofile.write((char*)&shortcut.tags.type_id, 1);
- ofile.write(shortcut.tags.key, 5);
- for (auto& tag : shortcut.tags.value)
- {
- ofile.write(tag.idx.data, 2);
- ofile.write("\x00", 1);
- ofile.write(tag.value.data(), tag.value.length());
- ofile.write("\x00", 1);
- }
- ofile.write("\x08\x08", 2);
}
ofile.write("\x08\x08", 2);
- ofile.close();
- return true;
}
-
- };
-}
+ ofile.write("\x08\x08", 2);
+ ofile.close();
+ return true;
+ }
+};
+} // namespace VDFParser
diff --git a/GlosSIConfig/WinEventFilter.h b/GlosSIConfig/WinEventFilter.h
index d5ddf44..ccd39c2 100644
--- a/GlosSIConfig/WinEventFilter.h
+++ b/GlosSIConfig/WinEventFilter.h
@@ -19,9 +19,8 @@ limitations under the License.
#define NOMINMAX
#include
-class WinEventFilter : public QAbstractNativeEventFilter
-{
-public:
+class WinEventFilter : public QAbstractNativeEventFilter {
+ public:
WinEventFilter() = default;
/*
@@ -37,8 +36,7 @@ public:
auto msg = static_cast(message)->message;
auto lParam = static_cast(message)->lParam;
auto hwnd = static_cast(message)->hwnd;
- if (msg == WM_NCCALCSIZE)
- {
+ if (msg == WM_NCCALCSIZE) {
auto sz = reinterpret_cast(lParam);
sz->rgrc[0].top -= 6;
}
diff --git a/GlosSIConfig/main.cpp b/GlosSIConfig/main.cpp
index 4f5bcb6..63ba47b 100644
--- a/GlosSIConfig/main.cpp
+++ b/GlosSIConfig/main.cpp
@@ -19,9 +19,9 @@ limitations under the License.
#include
#ifdef _WIN32
+#include
#include
#include
-#include
#pragma comment(lib, "Dwmapi.lib")
#endif
@@ -30,8 +30,7 @@ limitations under the License.
#ifdef _WIN32
// Some undocument stuff to enable aero on win10 or higher...
-enum AccentState
-{
+enum AccentState {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
@@ -40,8 +39,7 @@ enum AccentState
ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809
ACCENT_INVALID_STATE = 6
};
-struct AccentPolicy
-{
+struct AccentPolicy {
AccentState AccentState;
int AccentFlags;
@@ -49,14 +47,12 @@ struct AccentPolicy
int AnimationId;
};
-enum WindowCompositionAttribute
-{
+enum WindowCompositionAttribute {
// ...
WCA_ACCENT_POLICY = 19
// ...
};
-struct WindowCompositionAttributeData
-{
+struct WindowCompositionAttributeData {
WindowCompositionAttribute Attribute;
void* Data;
int SizeOfData;
@@ -66,7 +62,6 @@ typedef HRESULT(__stdcall* PSetWindowCompositionAttribute)(HWND hwnd, WindowComp
#endif
-
int main(int argc, char* argv[])
{
#if defined(Q_OS_WIN)
@@ -98,31 +93,29 @@ int main(int argc, char* argv[])
// Enable blurbehind (not needed?) anyway gives nice background on win7 and 8
DWM_BLURBEHIND bb{};
- bb.dwFlags = DWM_BB_ENABLE; bb.fEnable = true; bb.hRgnBlur = nullptr;
+ bb.dwFlags = DWM_BB_ENABLE;
+ bb.fEnable = true;
+ bb.hRgnBlur = nullptr;
DwmEnableBlurBehindWindow(hwnd, &bb);
- if (IsWindows10OrGreater())
- {
+ if (IsWindows10OrGreater()) {
// undoc stuff for aero >= Win10
int color = (0 << 24) + (0x21 << 16) + (0x11 << 8) + (0x11);
AccentPolicy accPol{};
accPol.AccentState = ACCENT_ENABLE_ACRYLICBLURBEHIND;
- accPol.AccentFlags = 2; accPol.GradientColor = color;
+ accPol.AccentFlags = 2;
+ accPol.GradientColor = color;
accPol.AnimationId = 0;
WindowCompositionAttributeData data{};
data.Attribute = WindowCompositionAttribute::WCA_ACCENT_POLICY;
- data.Data = &accPol;
- data.SizeOfData = sizeof(accPol);
+ data.Data = &accPol;
+ data.SizeOfData = sizeof(accPol);
auto user32dll = GetModuleHandle(L"user32.dll");
if (user32dll) {
- PSetWindowCompositionAttribute SetWindowCompositionAttribute = (
- reinterpret_cast(GetProcAddress(user32dll, "SetWindowCompositionAttribute"))
- );
- if (SetWindowCompositionAttribute)
- {
+ PSetWindowCompositionAttribute SetWindowCompositionAttribute = (reinterpret_cast(GetProcAddress(user32dll, "SetWindowCompositionAttribute")));
+ if (SetWindowCompositionAttribute) {
auto res = SetWindowCompositionAttribute(hwnd, &data);
- if (SUCCEEDED(res))
- {
+ if (SUCCEEDED(res)) {
uimodel.setAcrylicEffect(true);
}
}
@@ -130,7 +123,7 @@ int main(int argc, char* argv[])
}
// extend the frame fully into the client area => draw all outside the window frame.
- MARGINS margins = { -1 };
+ MARGINS margins = {-1};
DwmExtendFrameIntoClientArea(hwnd, &margins);
// To Fix top window frame, install native event filter
@@ -144,10 +137,10 @@ int main(int argc, char* argv[])
// Inform the application of the frame change.
SetWindowPos(hwnd,
- NULL,
- rcClient.left, rcClient.top,
- rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
- SWP_FRAMECHANGED);
+ NULL,
+ rcClient.left, rcClient.top,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+ SWP_FRAMECHANGED);
#endif
diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc
index 3f7fdba..d0b1c8d 100644
--- a/GlosSIConfig/qml.qrc
+++ b/GlosSIConfig/qml.qrc
@@ -10,5 +10,6 @@
svg/edit_white_24dp.svg
svg/steam.svg
qml/UWPSelectDialog.qml
+ qml/InfoDialog.qml
diff --git a/GlosSIConfig/qml/InfoDialog.qml b/GlosSIConfig/qml/InfoDialog.qml
new file mode 100644
index 0000000..efd7a7a
--- /dev/null
+++ b/GlosSIConfig/qml/InfoDialog.qml
@@ -0,0 +1,98 @@
+/*
+Copyright 2021 Peter Repukat - FlatspotSoftware
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+import QtQuick 6.2
+import QtQuick.Controls 6.2
+Dialog {
+ id: dlg
+ anchors.centerIn: parent
+
+ property var confirmedParam: null
+ signal confirmed(var param)
+
+ visible: false
+ modal: true
+ dim: true
+ parent: Overlay.overlay
+ Overlay.modal: Rectangle {
+ color: Qt.rgba(0,0,0,0.4)
+ opacity: backdropOpacity
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 300
+ }
+ }
+ }
+ property real backdropOpacity: 1.0
+
+ property alias titleText: title.text
+ property alias text: text.text
+
+ enter: Transition {
+ NumberAnimation{target: content; property: "y"; from: parent.height; to: 16; duration: 300; easing.type: Easing.OutQuad }
+ NumberAnimation{target: background; property: "y"; from: parent.height; to: 0; duration: 300; easing.type: Easing.OutQuad }
+ NumberAnimation{target: dlg; property: "backdropOpacity"; from: 0; to: 1; duration: 300; easing.type: Easing.OutQuad }
+ }
+
+ exit: Transition {
+ NumberAnimation{target: content; property: "y"; from: 16; to: parent.height; duration: 300; easing.type: Easing.InQuad }
+ NumberAnimation{target: background; property: "y"; from: 0; to: parent.height; duration: 300; easing.type: Easing.InQuad }
+ NumberAnimation{target: dlg; property: "backdropOpacity"; from: 1; to: 0; duration: 300; easing.type: Easing.InQuad }
+ }
+
+ background: RPane {
+ id: background
+ radius: 4
+ Material.elevation: 64
+ bgOpacity: 0.97
+ }
+ contentItem: Item {
+ id: content
+ readonly property real spacing: 16
+ implicitWidth: Math.max(row.width, col.width)
+ implicitHeight: title.height + row.height + spacing + col.height
+ Label {
+ id: title
+ anchors.top: parent.top
+ anchors.left: parent.left
+ text: dlg.title
+ font.bold: true
+ }
+ Column {
+ id: col
+ anchors.top: title.bottom
+ anchors.topMargin: parent.spacing
+ spacing: 16
+ Label {
+ id: text
+ }
+ }
+ Row {
+ id: row
+ anchors.top: col.bottom
+ anchors.topMargin: parent.spacing
+ spacing: 16
+ Button {
+ text: qsTr("OK")
+ onClicked: function(){
+ close()
+ confirmed(confirmedParam)
+ }
+ }
+ anchors.right: parent.right
+ }
+ }
+
+}
diff --git a/GlosSIConfig/qml/ShortcutCards.qml b/GlosSIConfig/qml/ShortcutCards.qml
index 7bf4662..cefac18 100644
--- a/GlosSIConfig/qml/ShortcutCards.qml
+++ b/GlosSIConfig/qml/ShortcutCards.qml
@@ -17,6 +17,7 @@ import QtQuick 6.2
import QtQuick.Layouts 6.2
import QtQuick.Controls 6.2
import QtQuick.Controls.Material 6.2
+import QtQuick.Dialogs 6.2
import Qt5Compat.GraphicalEffects
GridView {
@@ -64,6 +65,12 @@ GridView {
NumberAnimation { properties: "x,y"; duration: 300; easing.type: Easing.InQuad }
}
+ InfoDialog {
+ id: writeErrorDialog
+ titleText: qsTr("Error")
+ text: qsTr("Error writing shortcuts.vdf...")
+ }
+
delegate: RPane {
id: delegateRoot
color: Qt.lighter(Material.background, 1.6)
@@ -90,7 +97,7 @@ GridView {
anchors.left: parent.left
anchors.bottom: buttonrow.top
anchors.margins: 12
- spacing: 4
+ spacing: 8
Row {
spacing: 8
visible: modelData.launchPath && modelData.launchPath.length > 0
@@ -112,6 +119,37 @@ GridView {
elide: Text.ElideRight
}
}
+ Row {
+ visible: false // TODO: dunno about this...
+ spacing: 4
+ Label {
+ text: qsTr("Is in")
+ font.bold: true
+ }
+ Image {
+ anchors.verticalCenter: parent.verticalCenter
+ source: "qrc:/svg/steam.svg"
+ width: 16
+ height: 16
+ smooth: true
+ mipmap: true
+ ColorOverlay {
+ anchors.fill: parent
+ source: parent
+ color: "white"
+ }
+ }
+ Item {
+ width: 4
+ height: 1
+ }
+ Label {
+ anchors.verticalCenter: parent.verticalCenter
+ text: delegateRoot.isInSteam ? qsTr("Yes") : qsTr("No")
+ width: 292 - typeLabel.width - 72
+ elide: Text.ElideRight
+ }
+ }
}
Image {
@@ -134,19 +172,20 @@ GridView {
onClicked: function(){
if (delegateRoot.isInSteam) {
if (!uiModel.removeFromSteam(modelData.name)) {
- // TODO: show error
+ writeErrorDialog.open();
return;
}
} else {
if (!uiModel.addToSteam(modelData)) {
- // TODO: show error
+ writeErrorDialog.open();
return;
}
}
delegateRoot.isInSteam = uiModel.isInSteam(modelData)
+ steamShortcutsChanged = true
}
highlighted: delegateRoot.isInSteam
- Material.accent: Material.color(Material.Red, Material.Shade400)
+ Material.accent: Material.color(Material.Red, Material.Shade800)
Row {
anchors.centerIn: parent
spacing: 8
diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml
index bc71fb1..6346df8 100644
--- a/GlosSIConfig/qml/main.qml
+++ b/GlosSIConfig/qml/main.qml
@@ -43,6 +43,17 @@ Window {
return Qt.rgba(color.r, color.g, color.b, alpha);
}
+ property bool steamShortcutsChanged: false
+
+ InfoDialog {
+ id: steamChangedDialog
+ titleText: qsTr("Attention!")
+ text: qsTr("Please restart Steam to reload your changes!")
+ onConfirmed: function (callback) {
+ callback();
+ }
+ }
+
Rectangle {
id: titleBar
visible: uiModel.isWindows
@@ -83,7 +94,14 @@ Window {
ToolButton {
id: closbtn
text: "🗙"
- onClicked: window.close()
+ onClicked: steamShortcutsChanged
+ ? (function(){
+ steamChangedDialog.confirmedParam = () => {
+ window.close()
+ }
+ steamChangedDialog.open()
+ })()
+ : window.close()
background: Rectangle {
implicitWidth: 32
implicitHeight: 32
@@ -99,7 +117,6 @@ Window {
}
}
}
-
}
Item {
@@ -229,6 +246,5 @@ Window {
}
}
}
-
}
}
diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp
index 73e104c..be693a3 100644
--- a/GlosSITarget/main.cpp
+++ b/GlosSITarget/main.cpp
@@ -20,12 +20,11 @@ limitations under the License.
#include "SteamTarget.h"
+#include "OverlayLogSink.h"
+#include "Settings.h"
#include
#include
#include
-#include "OverlayLogSink.h"
-#include "Settings.h"
-
#ifdef _WIN32
#ifdef CONSOLE