diff --git a/pupgui2/pupgui2ctinfodialog.py b/pupgui2/pupgui2ctinfodialog.py
index 9c631c18..aa430e61 100644
--- a/pupgui2/pupgui2ctinfodialog.py
+++ b/pupgui2/pupgui2ctinfodialog.py
@@ -6,7 +6,7 @@
from pupgui2.lutrisutil import get_lutris_game_list, is_lutris_game_using_wine
from pupgui2.pupgui2ctbatchupdatedialog import PupguiCtBatchUpdateDialog
from pupgui2.steamutil import get_steam_game_list
-from pupgui2.util import open_webbrowser_thread, get_random_game_name
+from pupgui2.util import open_webbrowser_thread, get_random_game_name, is_mark_global_available, set_launcher_global_tool
from pupgui2.heroicutil import get_heroic_game_list, is_heroic_launcher
from PySide6.QtCore import QObject, Signal, QDataStream, QByteArray
@@ -29,6 +29,7 @@ def __init__(self, parent=None, ctool: BasicCompatTool = None, install_loc=None)
self.games: List[Union[SteamApp, LutrisGame, HeroicGame]] = []
self.install_loc = install_loc
self.is_batch_update_available = False
+ self.is_mark_global_available = False
self.load_ui()
self.setup_ui()
@@ -41,13 +42,14 @@ def load_ui(self):
self.ui = loader.load(ui_file.device())
def setup_ui(self):
+ self.update_game_list()
+
self.ui.txtToolName.setText(self.ctool.displayname)
self.ui.txtLauncherName.setText(self.install_loc.get('display_name'))
self.ui.txtInstallDirectory.setText(self.ctool.get_install_dir())
self.ui.btnBatchUpdate.setVisible(False)
self.ui.searchBox.setVisible(False)
-
- self.update_game_list()
+ self.ui.btnMarkGlobal.setVisible(self.is_mark_global_available) # Gets updated in update_game_list
self.ui.btnSearch.clicked.connect(self.btn_search_clicked)
self.ui.btnRefreshGames.clicked.connect(self.btn_refresh_games_clicked)
@@ -118,6 +120,8 @@ def setup_game_list(self, row_count: int, header_labels: List[str]):
self.ui.txtNumGamesUsingTool.setText(str(row_count))
def update_game_list_ui(self):
+ self.is_mark_global_available = is_mark_global_available(self.install_loc, self.ctool)
+
# switch between showing the QTableWidget (listGames) or the QLabel (lblGamesList)
self.ui.stackTableOrText.setCurrentIndex(0 if len(self.games) > 0 and not self.ctool.is_global else 1)
self.ui.btnBatchUpdate.setEnabled(len(self.games) > 0 and not self.ctool.is_global)
@@ -126,6 +130,10 @@ def update_game_list_ui(self):
if self.ctool.is_global:
self.ui.lblGamesList.setText(self.tr('Tool is Global'))
+ self.ui.btnMarkGlobal.setVisible(self.is_mark_global_available)
+ if self.is_mark_global_available:
+ self.ui.btnMarkGlobal.clicked.connect(self.btn_mark_global_clicked)
+
if len(self.games) < 0 or self.ctool.is_global:
self.ui.btnClose.setFocus()
@@ -161,3 +169,7 @@ def search_ctinfo_games(self, text):
for row in range(self.ui.listGames.rowCount()):
should_hide: bool = not text.lower() in self.ui.listGames.item(row, 1).text().lower()
self.ui.listGames.setRowHidden(row, should_hide)
+
+ def btn_mark_global_clicked(self):
+ self.is_mark_global_available = not set_launcher_global_tool(self.install_loc, self.ctool)
+ self.btn_refresh_games_clicked()
diff --git a/pupgui2/resources/ui/pupgui2_ctinfodialog.ui b/pupgui2/resources/ui/pupgui2_ctinfodialog.ui
index 4f731e8d..50b85839 100644
--- a/pupgui2/resources/ui/pupgui2_ctinfodialog.ui
+++ b/pupgui2/resources/ui/pupgui2_ctinfodialog.ui
@@ -14,8 +14,7 @@
About compatibility tool
-
- ..
+
-
@@ -33,7 +32,7 @@
- Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+ Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse
@@ -50,7 +49,7 @@
- Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+ Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse
@@ -67,7 +66,7 @@
- Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+ Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse
@@ -76,7 +75,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -99,7 +98,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -118,8 +117,7 @@
-
- ..
+
@@ -132,8 +130,7 @@
-
- ..
+
@@ -170,13 +167,13 @@
- Qt::ClickFocus
+ Qt::FocusPolicy::ClickFocus
- QAbstractItemView::NoEditTriggers
+ QAbstractItemView::EditTrigger::NoEditTriggers
- QAbstractItemView::SelectRows
+ QAbstractItemView::SelectionBehavior::SelectRows
true
@@ -248,7 +245,7 @@
No games
- Qt::AlignCenter
+ Qt::AlignmentFlag::AlignCenter
@@ -275,10 +272,17 @@
+ -
+
+
+ Set as Global
+
+
+
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -291,7 +295,7 @@
-
- Qt::StrongFocus
+ Qt::FocusPolicy::StrongFocus
Close
@@ -304,10 +308,12 @@
btnClose
+ btnMarkGlobal
+ searchBox
btnBatchUpdate
btnSearch
- searchBox
btnRefreshGames
+ lblGamesUsingTool
diff --git a/pupgui2/steamutil.py b/pupgui2/steamutil.py
index 8914f561..8758c20d 100644
--- a/pupgui2/steamutil.py
+++ b/pupgui2/steamutil.py
@@ -636,6 +636,8 @@ def install_steam_library_shortcut(steam_config_folder: str, remove_shortcut=Fal
except Exception as e:
print(f'Error: Could not add {APP_NAME} as Steam shortcut:', e)
+ return 1
+
return 0
@@ -794,6 +796,35 @@ def determine_most_recent_steam_user(steam_users: List[SteamUser]) -> SteamUser:
return None
+def set_steam_global_compat_tool(steam_config_folder: str, ctool: BasicCompatTool):
+ """ Update the global compatibility tool to the ctool parameter defined in config.vdf CompatToolMapping (AppID '0') """
+
+ if ctool.ct_type != CTType.CUSTOM:
+ return False
+
+ config_vdf_file = os.path.join(os.path.expanduser(steam_config_folder), 'config.vdf')
+ if not os.path.exists(config_vdf_file):
+ return False
+
+ try:
+ d = vdf.load(open(config_vdf_file))
+ c = get_steam_vdf_compat_tool_mapping(d)
+
+ # Create or update the '0' CompatToolMapping entry
+ if not c.get('0', {}):
+ c['0'] = { 'name': ctool.get_internal_name(), 'config': '', 'priority': '75' }
+ else:
+ c['0']['name'] = ctool.get_internal_name()
+
+ vdf.dump(d, open(config_vdf_file, 'w'), pretty=True)
+ except Exception as e:
+ print(f'Error, could not update Global Steam compatibility tool to {ctool.displayname}: {e}, vdf: {config_vdf_file}')
+ return False
+
+ return True
+
+
+
def is_valid_steam_install(steam_path) -> bool:
"""
diff --git a/pupgui2/util.py b/pupgui2/util.py
index e91991fa..3f11b280 100644
--- a/pupgui2/util.py
+++ b/pupgui2/util.py
@@ -23,7 +23,7 @@
from pupgui2.constants import AWACY_GAME_LIST_URL, LOCAL_AWACY_GAME_LIST
from pupgui2.constants import GITHUB_API, GITLAB_API, GITLAB_API_RATELIMIT_TEXT
from pupgui2.datastructures import BasicCompatTool, CTType, Launcher, SteamApp, LutrisGame, HeroicGame
-from pupgui2.steamutil import remove_steamtinkerlaunch, is_valid_steam_install
+from pupgui2.steamutil import remove_steamtinkerlaunch, is_valid_steam_install, set_steam_global_compat_tool
def create_msgbox(
@@ -892,3 +892,62 @@ def get_random_game_name(games: List[Union[SteamApp, LutrisGame, HeroicGame]]) -
tooltip_game_name = random_game.title
return tooltip_game_name
+
+
+def is_mark_global_available(install_loc, ctool: BasicCompatTool) -> bool:
+
+ """
+ Check if marking a tool is "global" is supported by the current launcher,
+ and if the given ctool can be marked as global for this launcher.
+
+ For example, runtimes are not valid to be marked as Global.
+
+ Return Type: bool
+ """
+
+ allowed_launchers = [ 'steam', 'lutris' ] # Only allow marking global for these launchers
+
+ # Only allow marking global for compatibility tools and not runtimes etc
+ if ctool.ct_type != CTType.CUSTOM:
+ return False
+
+ # Don't allow marking global compat tools as global
+ if ctool.is_global:
+ return False
+
+ # Exit early if launcher is not on our list of compatible/allowed launchers
+ if install_loc.get('launcher') not in allowed_launchers:
+ return False
+
+ # Only allow marking global for Steam if we have the VDF directory path
+ if install_loc.get('launcher') == 'steam' and 'vdf_dir' not in install_loc:
+ return False
+
+ # Could put other conditions for other launchers in an elif here, i.e. check for Lutris and ensure a specific path exists
+ # Nothing here yet...
+
+ return True # All other checks passed so default to true
+
+
+def set_launcher_global_tool(install_loc, compat_tool: BasicCompatTool) -> bool:
+
+ """
+ Set a given compat_tool as global for a given launcher by calling the
+ relevant util function for that launcher.
+ """
+
+ launcher = install_loc.get('launcher', '').lower()
+
+ # Skip empty launcher
+ if not launcher:
+ return False
+
+ if not is_mark_global_available(install_loc, compat_tool):
+ return False
+
+ if launcher == 'steam':
+ steam_config_folder = install_loc.get('vdf_dir', '')
+
+ return set_steam_global_compat_tool(steam_config_folder, compat_tool)
+
+ return False