diff --git a/GlosSIConfig/GlosSIConfig.vcxproj b/GlosSIConfig/GlosSIConfig.vcxproj index c573119..816dbf2 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj +++ b/GlosSIConfig/GlosSIConfig.vcxproj @@ -137,6 +137,7 @@ + diff --git a/GlosSIConfig/GlosSIConfig.vcxproj.filters b/GlosSIConfig/GlosSIConfig.vcxproj.filters index b9af58c..757008d 100644 --- a/GlosSIConfig/GlosSIConfig.vcxproj.filters +++ b/GlosSIConfig/GlosSIConfig.vcxproj.filters @@ -68,6 +68,9 @@ qml + + qml + diff --git a/GlosSIConfig/Resource.rc b/GlosSIConfig/Resource.rc index 9b95676..0c465db 100644 --- a/GlosSIConfig/Resource.rc +++ b/GlosSIConfig/Resource.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,8,102000500230 - PRODUCTVERSION 0,0,8,102000500230 + FILEVERSION 0,0,8,105004039005 + PRODUCTVERSION 0,0,8,105004039005 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "FileDescription", "GlosSI - Config" - VALUE "FileVersion", "0.0.8.1-2-gc5fc23d" + VALUE "FileVersion", "0.0.8.1-5-g40390b5" VALUE "InternalName", "GlosSIConfig" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "ProductName", "GlosSI" - VALUE "ProductVersion", "0.0.8.1-2-gc5fc23d" + VALUE "ProductVersion", "0.0.8.1-5-g40390b5" END END BLOCK "VarFileInfo" @@ -800,6 +800,78 @@ IDI_ICON1 ICON "..\GloSC_Icon.ico" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index bda74a0..b0bce26 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -237,6 +237,46 @@ QVariantMap UIModel::manualProps(QVariant shortcut) return res; } +void UIModel::enableSteamInputXboxSupport() +{ + if (foundSteam()) { + const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + user_config_file_.toStdWString(); + if (!std::filesystem::exists(config_path)) { + qDebug() << "localconfig.vdf does not exist."; + } + QFile file(config_path); + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { + QTextStream in(&file); + QStringList lines; + QString line = in.readLine(); + // simple approach is enough... + while (!in.atEnd()) { + if (line.contains("SteamController_XBoxSupport")) { + if (line.contains("1")) { + qDebug() << "\"SteamController_XBoxSupport\" is already enabled! aborting write..."; + file.close(); + return; + } + qDebug() << "found \"SteamController_XBoxSupport\" line, replacing value..."; + line.replace("0", "1"); + } + lines.push_back(line); + line = in.readLine(); + } + file.close(); + QFile updatedFile(config_path); + if (updatedFile.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { + qDebug() << "writing localconfig.vdf..."; + QTextStream out(&updatedFile); + for (const auto& l : lines) { + out << l << "\n"; + } + } + updatedFile.close(); + } + } +} + #ifdef _WIN32 QVariantList UIModel::uwpApps() { @@ -436,3 +476,39 @@ void UIModel::parseShortcutVDF() qDebug() << "Error parsing VDF: " << e.what(); } } + +bool UIModel::isSteamInputXboxSupportEnabled() const +{ + // return true as default to not bug the user in error cases. + if (foundSteam()) { + const std::filesystem::path config_path = std::wstring(getSteamPath()) + user_data_path_.toStdWString() + getSteamUserId() + user_config_file_.toStdWString(); + if (!std::filesystem::exists(config_path)) { + qDebug() << "localconfig.vdf does not exist."; + return true; + } + QFile file(config_path); + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) { + QTextStream in(&file); + QString line = in.readLine(); + // simple, regex approach should be enough... + while (!in.atEnd()) { + if (line.contains("SteamController_XBoxSupport")) { + file.close(); + if (line.contains("1")) { + qDebug() << "\"SteamController_XBoxSupport\" is enabled!"; + return true; + } + qDebug() << "\"SteamController_XBoxSupport\" is disabled!"; + return false; + } + line = in.readLine(); + } + qDebug() << "couldn't find \"SteamController_XBoxSupport\" in localconfig.vdf"; + file.close(); + } + else { + qDebug() << "could not open localconfig.vdf"; + } + } + return true; +} diff --git a/GlosSIConfig/UIModel.h b/GlosSIConfig/UIModel.h index d17e231..38b6007 100644 --- a/GlosSIConfig/UIModel.h +++ b/GlosSIConfig/UIModel.h @@ -28,6 +28,7 @@ class UIModel : public QObject { Q_PROPERTY(QVariantList targetList READ getTargetList NOTIFY targetListChanged) Q_PROPERTY(QVariantList uwpList READ uwpApps CONSTANT) Q_PROPERTY(bool foundSteam READ foundSteam CONSTANT) + Q_PROPERTY(bool steamInputXboxSupportEnabled READ isSteamInputXboxSupportEnabled CONSTANT) public: UIModel(); @@ -42,6 +43,7 @@ class UIModel : public QObject { bool addToSteam(const QString& name, const QString& shortcutspath, bool from_cmd = false); Q_INVOKABLE bool removeFromSteam(const QString& name, const QString& shortcutspath, bool from_cmd = false); Q_INVOKABLE QVariantMap manualProps(QVariant shortcut); + Q_INVOKABLE void enableSteamInputXboxSupport(); #ifdef _WIN32 Q_INVOKABLE QVariantList uwpApps(); #endif @@ -71,7 +73,11 @@ class UIModel : public QObject { std::wstring getSteamUserId() const; bool foundSteam() const; void parseShortcutVDF(); + + bool isSteamInputXboxSupportEnabled() const; + QString shortcutsfile_ = "/config/shortcuts.vdf"; + QString user_config_file_ = "/config/localconfig.vdf"; QString user_data_path_ = "/userdata/"; QVariantList targets_; diff --git a/GlosSIConfig/qml.qrc b/GlosSIConfig/qml.qrc index 28a36de..b626964 100644 --- a/GlosSIConfig/qml.qrc +++ b/GlosSIConfig/qml.qrc @@ -16,5 +16,6 @@ GloSC_Icon_small.png svg/help_outline_white_24dp.svg qml/SteamNotFoundDialog.qml + qml/SteamInputXboxDisabledDialog.qml diff --git a/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml new file mode 100644 index 0000000..7c4e9f0 --- /dev/null +++ b/GlosSIConfig/qml/SteamInputXboxDisabledDialog.qml @@ -0,0 +1,111 @@ +/* +Copyright 2021-2022 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 +import QtQuick.Layouts 6.2 +import QtQuick.Controls.Material 6.2 + +Dialog { + id: dlg + anchors.centerIn: parent + + 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 + + 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 + clip: true + Column { + spacing: 4 + bottomPadding: 96 + Label { + id: titlelabel + text: qsTr("Steam Input Xbox support disabled") + font.pixelSize: 24 + font.bold: true + } + Item { + height: 32 + } + Label { + text: qsTr("Please enable \"Xbox configuration support\" in Steams controller settings.\n\nGlosSI cannot function properly with this setting disabled\n\nEnable now?") + wrapMode: Text.WordWrap + width: parent.width + } + Row { + anchors.right: parent.right + anchors.topMargin: 16 + anchors.rightMargin: 2 + spacing: 8 + Button { + id: noBtn + text: qsTr("No") + onClicked: dlg.close() + } + Button { + id: yesBtn + text: qsTr("Yes") + onClicked: function() { + uiModel.enableSteamInputXboxSupport(); + dlg.close(); + steamChangedDialog2.open(); + } + } + } + } + InfoDialog { + id: steamChangedDialog2 + titleText: qsTr("Attention!") + text: qsTr("Please restart Steam to reload your changes!") + onConfirmed: function (callback) { + callback(); + } + } + } +} \ No newline at end of file diff --git a/GlosSIConfig/qml/main.qml b/GlosSIConfig/qml/main.qml index fb22b24..9b141e0 100644 --- a/GlosSIConfig/qml/main.qml +++ b/GlosSIConfig/qml/main.qml @@ -48,6 +48,10 @@ Window { Component.onCompleted: function() { if (!uiModel.foundSteam) { steamNotFoundDialog.open(); + return; + } + if (!uiModel.steamInputXboxSupportEnabled) { + steamXboxDisabledDialog.open(); } } @@ -64,6 +68,10 @@ Window { SteamNotFoundDialog { id: steamNotFoundDialog } + SteamInputXboxDisabledDialog { + id: steamXboxDisabledDialog + } + InfoDialog { id: steamChangedDialog