1
0
Fork 0
mirror of synced 2024-09-29 08:51:43 +13:00

Implement env_vars

This commit is contained in:
aznd 2022-03-01 22:36:16 +01:00
parent 324530171e
commit 0f03c06dab
4 changed files with 357 additions and 0 deletions

View file

@ -0,0 +1,219 @@
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QGroupBox, QTableWidgetItem, QMessageBox
import qtawesome
from rare.ui.components.tabs.games.env_vars import Ui_EnvVars
from rare.utils import config_helper
from rare.shared import LegendaryCoreSingleton
from PyQt5 import QtCore
class EnvVars(QGroupBox, Ui_EnvVars):
def __init__(self, parent):
super(EnvVars, self).__init__(parent=parent)
self.setupUi(self)
self.app_name = None
self.core = LegendaryCoreSingleton()
self.latest_item = None
self.list_of_readonly = ["STEAM_COMPAT_DATA_PATH", "DXVK_HUD", "WINEPREFIX"]
self.warn_msg = "Readonly, please edit this via the relative setting."
def compare_config_and_table(self):
list_of_keys_in_table = []
row_count = self.env_vars_table.rowCount()
for i in range(row_count):
item = self.env_vars_table.item(i, 0)
try:
list_of_keys_in_table.append(item.text())
except AttributeError:
pass
list_of_keys_in_config = []
try:
for key in self.core.lgd.config[f"{self.app_name}.env"]:
list_of_keys_in_config.append(key)
except KeyError:
pass
def import_env_vars(self):
self.env_vars_table.disconnect()
self.env_vars_table.clearContents()
list_of_keys = []
list_of_values = []
# First, we try to get all keys and values from the config
try:
for key in self.core.lgd.config[f"{self.app_name}.env"]:
list_of_keys.append(key)
for i in list_of_keys:
list_of_values.append(self.core.lgd.config[f"{self.app_name}.env"][i])
except KeyError:
pass
# We count how many keys we have and insert new lines
# (as many as we need).
# Each iteration we have to create a new QTableWidgetItem object,
# else we segfault. (For using the same object in multiple references.)
count = len(list_of_keys)
for i in range(count):
self.env_vars_table.insertRow(i)
trash_icon = QTableWidgetItem()
trash_icon.setIcon(qtawesome.icon("mdi.delete"))
self.env_vars_table.setVerticalHeaderItem(i, trash_icon)
# We set the row count to the length of the list_of_keys
if len(list_of_keys) == 0:
self.env_vars_table.setRowCount(1)
else:
self.env_vars_table.setRowCount(len(list_of_keys))
for index, val in enumerate(list_of_keys):
new_item = QTableWidgetItem()
new_item.setText(val)
if new_item.text() in self.list_of_readonly:
new_item.setFlags(new_item.flags() ^ QtCore.Qt.ItemIsEnabled)
new_item.setToolTip(self.warn_msg)
self.env_vars_table.setItem(index, 0, new_item)
for index, val in enumerate(list_of_values):
new_item = QTableWidgetItem()
new_item.setText(val)
# We need to check if the first_item is in the list of readonly vars.
# If yes, we also need to disable column 1.
first_item = self.env_vars_table.item(index, 0)
if first_item.text() in self.list_of_readonly:
new_item.setFlags(new_item.flags() ^ QtCore.Qt.ItemIsEnabled)
new_item.setToolTip(self.warn_msg)
self.env_vars_table.setItem(index, 1, new_item)
row_count = self.env_vars_table.rowCount()
last_item = self.env_vars_table.item(row_count - 1, 0)
if last_item is not None:
self.env_vars_table.insertRow(row_count)
trash_icon = QTableWidgetItem()
trash_icon.setIcon(qtawesome.icon("mdi.delete"))
self.env_vars_table.setVerticalHeaderItem(row_count, trash_icon)
new_thing = QTableWidgetItem()
new_thing.setIcon(qtawesome.icon("mdi.delete"))
self.env_vars_table.setVerticalHeaderItem(0, new_thing)
self.compare_config_and_table()
# We need to call this at the end, since at startup we import the
# config and update the table. Thus, the cellChanged signal reacts, but
# we don't want that. Maybe we should only call this once, at startup?
# Like this we always connect at every update_game.
self.env_vars_table.cellChanged.connect(self.update_env_vars)
self.env_vars_table.verticalHeader().sectionClicked.connect(self.remove_row)
def update_env_vars(self, row):
row_count = self.env_vars_table.rowCount()
first_item = self.env_vars_table.item(row, 0)
second_item = self.env_vars_table.item(row, 1)
list_of_keys = []
try:
for key in self.core.lgd.config[f"{self.app_name}.env"]:
list_of_keys.append(key)
except KeyError:
pass
list_of_keys_in_table = []
for i in range(row_count):
item = self.env_vars_table.item(i, 0)
try:
list_of_keys_in_table.append(item.text())
except AttributeError:
pass
missing_item = list(set(list_of_keys) - set(list_of_keys_in_table))
if len(missing_item) != 0:
config_helper.remove_option(f"{self.app_name}.env", missing_item[0])
# A env var always needs to have a key.
# If it's none, we return.
if first_item is None:
return
if first_item.text() in self.list_of_readonly:
error_dialog = QMessageBox()
error_dialog.setText("Please don't manually add this environment variable. Use the appropriate game setting above.")
error_dialog.exec()
first_item.setText("")
return
if first_item.text():
# When the second_item is None, we just use an empty string for the value.
if second_item is None:
if self.latest_item in list_of_keys:
config_helper.remove_option(f"{self.app_name}.env", self.latest_item)
config_helper.save_config()
config_helper.add_option(f"{self.app_name}.env", first_item.text(), "")
config_helper.save_config()
else:
if self.latest_item in list_of_keys:
config_helper.remove_option(f"{self.app_name}.env", self.latest_item)
config_helper.save_config()
config_helper.add_option(
f"{self.app_name}.env",
first_item.text(),
second_item.text()
)
config_helper.save_config()
row_count = self.env_vars_table.rowCount()
last_item = self.env_vars_table.item(row_count - 1, 0)
if last_item is not None:
if last_item.text():
self.env_vars_table.insertRow(row_count)
trash_icon = QTableWidgetItem()
trash_icon.setIcon(qtawesome.icon("mdi.delete"))
self.env_vars_table.setVerticalHeaderItem(row_count, trash_icon)
def remove_row(self, index):
# The user also should be able to delete the row,
# even if rowCount() is lower than 1, but then the row
# should be just cleared. (And not deleted)
first_item = self.env_vars_table.item(index, 0)
# The first item needs to have some text, else we don't delete it.
if first_item is None:
return
# If the user tries to delete one of the readonly vars, we show a message and return.
if first_item.text() in self.list_of_readonly:
error_dialog = QMessageBox()
error_dialog.setText("Please use the appropriate setting above to remove this key.")
error_dialog.exec()
return
if first_item is not None:
self.env_vars_table.removeRow(index)
try:
list_of_keys = []
for key in self.core.lgd.config[f"{self.app_name}.env"]:
list_of_keys.append(key)
config_helper.remove_option(f"{self.app_name}.env", list_of_keys[index])
except (KeyError, IndexError):
pass
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Delete or e.key() == QtCore.Qt.Key_Backspace:
selected_items = self.env_vars_table.selectedItems()
for i in selected_items:
config_helper.remove_option(f"{self.app_name}.env", i.text())
self.env_vars_table.removeRow(i.row())
def update_game(self, app_name):
self.app_name = app_name
self.import_env_vars()

View file

@ -5,6 +5,7 @@ from pathlib import Path
from typing import Tuple from typing import Tuple
from PyQt5.QtCore import QSettings, QThreadPool, Qt from PyQt5.QtCore import QSettings, QThreadPool, Qt
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QWidget,
QFileDialog, QFileDialog,
@ -19,6 +20,7 @@ from legendary.models.game import InstalledGame, Game
from rare.components.tabs.settings.linux import LinuxSettings from rare.components.tabs.settings.linux import LinuxSettings
from rare.components.tabs.settings.widgets.wrapper import WrapperSettings from rare.components.tabs.settings.widgets.wrapper import WrapperSettings
from rare.ui.components.tabs.games.game_info.game_settings import Ui_GameSettings from rare.ui.components.tabs.games.game_info.game_settings import Ui_GameSettings
from rare.components.tabs.games.env_vars import EnvVars
from rare.utils import config_helper from rare.utils import config_helper
from rare.utils.extra_widgets import PathEdit from rare.utils.extra_widgets import PathEdit
from rare.utils.utils import WineResolver, get_raw_save_path from rare.utils.utils import WineResolver, get_raw_save_path
@ -141,6 +143,8 @@ class GameSettings(QWidget, Ui_GameSettings):
self.linux_settings.mangohud.set_wrapper_activated.connect( self.linux_settings.mangohud.set_wrapper_activated.connect(
lambda active: self.wrapper_settings.add_wrapper("mangohud") lambda active: self.wrapper_settings.add_wrapper("mangohud")
if active else self.wrapper_settings.delete_wrapper("mangohud")) if active else self.wrapper_settings.delete_wrapper("mangohud"))
self.env_vars = EnvVars(self)
self.game_settings_contents_layout.addWidget(self.env_vars)
def compute_save_path(self): def compute_save_path(self):
if ( if (
@ -359,6 +363,9 @@ class GameSettings(QWidget, Ui_GameSettings):
self.core.lgd.config.get(self.game.app_name, "override_exe", fallback="") self.core.lgd.config.get(self.game.app_name, "override_exe", fallback="")
) )
self.change = True self.change = True
self.env_vars.update_game(app_name)
class LinuxAppSettings(LinuxSettings): class LinuxAppSettings(LinuxSettings):

View file

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/env_vars.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_EnvVars(object):
def setupUi(self, EnvVars):
EnvVars.setObjectName("EnvVars")
EnvVars.resize(720, 561)
EnvVars.setMinimumSize(QtCore.QSize(0, 200))
self.verticalLayout = QtWidgets.QVBoxLayout(EnvVars)
self.verticalLayout.setObjectName("verticalLayout")
self.env_vars_table = QtWidgets.QTableWidget(EnvVars)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.env_vars_table.sizePolicy().hasHeightForWidth())
self.env_vars_table.setSizePolicy(sizePolicy)
self.env_vars_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.env_vars_table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
self.env_vars_table.setObjectName("env_vars_table")
self.env_vars_table.setColumnCount(2)
self.env_vars_table.setRowCount(1)
item = QtWidgets.QTableWidgetItem()
self.env_vars_table.setVerticalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.env_vars_table.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.env_vars_table.setHorizontalHeaderItem(1, item)
self.env_vars_table.horizontalHeader().setStretchLastSection(True)
self.env_vars_table.verticalHeader().setStretchLastSection(False)
self.verticalLayout.addWidget(self.env_vars_table)
self.retranslateUi(EnvVars)
QtCore.QMetaObject.connectSlotsByName(EnvVars)
def retranslateUi(self, EnvVars):
_translate = QtCore.QCoreApplication.translate
EnvVars.setWindowTitle(_translate("EnvVars", "GroupBox"))
EnvVars.setTitle(_translate("EnvVars", "Environment variables"))
item = self.env_vars_table.verticalHeaderItem(0)
item.setText(_translate("EnvVars", "-"))
item = self.env_vars_table.horizontalHeaderItem(0)
item.setText(_translate("EnvVars", "Key"))
item = self.env_vars_table.horizontalHeaderItem(1)
item.setText(_translate("EnvVars", "Value"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
EnvVars = QtWidgets.QGroupBox()
ui = Ui_EnvVars()
ui.setupUi(EnvVars)
EnvVars.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EnvVars</class>
<widget class="QGroupBox" name="EnvVars">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>720</width>
<height>561</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>GroupBox</string>
</property>
<property name="title">
<string>Environment variables</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableWidget" name="env_vars_table">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<row>
<property name="text">
<string>-</string>
</property>
</row>
<column>
<property name="text">
<string>Key</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>