🚧 WIP new location system
TODO - Locations contain the schema key - Schema key overriden at location resolve - No need for callable candidates, but need to represent "this location's key"
This commit is contained in:
@@ -24,15 +24,14 @@ from shutil import rmtree
|
||||
|
||||
from gi.repository import Adw, Gio, GLib, Gtk
|
||||
|
||||
# pylint: disable=unused-import
|
||||
from src import shared
|
||||
|
||||
# TODO use the new sources
|
||||
from src.importers.bottles_importer import bottles_installed
|
||||
from src.importers.heroic_importer import heroic_installed
|
||||
from src.importers.itch_importer import itch_installed
|
||||
from src.importers.lutris_importer import lutris_cache_exists, lutris_installed
|
||||
from src.importers.steam_importer import steam_installed
|
||||
from src.importer.sources.bottles_source import BottlesSource
|
||||
from src.importer.sources.heroic_source import HeroicSource
|
||||
from src.importer.sources.itch_source import ItchSource
|
||||
from src.importer.sources.legendary_source import LegendarySource
|
||||
from src.importer.sources.lutris_source import LutrisSource
|
||||
from src.importer.sources.source import Source
|
||||
from src.importer.sources.steam_source import SteamSource
|
||||
from src.utils.create_dialog import create_dialog
|
||||
|
||||
|
||||
@@ -49,37 +48,36 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
exit_after_launch_switch = Gtk.Template.Child()
|
||||
cover_launches_game_switch = Gtk.Template.Child()
|
||||
high_quality_images_switch = Gtk.Template.Child()
|
||||
remove_all_games_button = Gtk.Template.Child()
|
||||
|
||||
steam_expander_row = Gtk.Template.Child()
|
||||
steam_action_row = Gtk.Template.Child()
|
||||
steam_file_chooser_button = Gtk.Template.Child()
|
||||
steam_data_action_row = Gtk.Template.Child()
|
||||
steam_data_file_chooser_button = Gtk.Template.Child()
|
||||
|
||||
lutris_expander_row = Gtk.Template.Child()
|
||||
lutris_action_row = Gtk.Template.Child()
|
||||
lutris_file_chooser_button = Gtk.Template.Child()
|
||||
lutris_data_action_row = Gtk.Template.Child()
|
||||
lutris_data_file_chooser_button = Gtk.Template.Child()
|
||||
lutris_cache_action_row = Gtk.Template.Child()
|
||||
lutris_cache_file_chooser_button = Gtk.Template.Child()
|
||||
lutris_import_steam_switch = Gtk.Template.Child()
|
||||
|
||||
heroic_expander_row = Gtk.Template.Child()
|
||||
heroic_action_row = Gtk.Template.Child()
|
||||
heroic_file_chooser_button = Gtk.Template.Child()
|
||||
heroic_config_action_row = Gtk.Template.Child()
|
||||
heroic_config_file_chooser_button = Gtk.Template.Child()
|
||||
heroic_import_epic_switch = Gtk.Template.Child()
|
||||
heroic_import_gog_switch = Gtk.Template.Child()
|
||||
heroic_import_sideload_switch = Gtk.Template.Child()
|
||||
|
||||
bottles_expander_row = Gtk.Template.Child()
|
||||
bottles_action_row = Gtk.Template.Child()
|
||||
bottles_file_chooser_button = Gtk.Template.Child()
|
||||
bottles_data_action_row = Gtk.Template.Child()
|
||||
bottles_data_file_chooser_button = Gtk.Template.Child()
|
||||
|
||||
itch_expander_row = Gtk.Template.Child()
|
||||
itch_action_row = Gtk.Template.Child()
|
||||
itch_file_chooser_button = Gtk.Template.Child()
|
||||
itch_config_action_row = Gtk.Template.Child()
|
||||
itch_config_file_chooser_button = Gtk.Template.Child()
|
||||
|
||||
legendary_expander_row = Gtk.Template.Child()
|
||||
legendary_action_row = Gtk.Template.Child()
|
||||
legendary_file_chooser_button = Gtk.Template.Child()
|
||||
legendary_config_action_row = Gtk.Template.Child()
|
||||
legendary_config_file_chooser_button = Gtk.Template.Child()
|
||||
|
||||
sgdb_key_group = Gtk.Template.Child()
|
||||
sgdb_key_entry_row = Gtk.Template.Child()
|
||||
@@ -89,6 +87,9 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
sgdb_animated_switch = Gtk.Template.Child()
|
||||
|
||||
danger_zone_group = Gtk.Template.Child()
|
||||
reset_action_row = Gtk.Template.Child()
|
||||
reset_button = Gtk.Template.Child()
|
||||
remove_all_games_button = Gtk.Template.Child()
|
||||
|
||||
removed_games = set()
|
||||
|
||||
@@ -116,87 +117,25 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
|
||||
# Debug
|
||||
if shared.PROFILE == "development":
|
||||
|
||||
def reset_app(*_args):
|
||||
rmtree(shared.data_dir / "cartridges", True)
|
||||
rmtree(shared.config_dir / "cartridges", True)
|
||||
rmtree(shared.cache_dir / "cartridges", True)
|
||||
|
||||
for key in (
|
||||
(settings_schema_source := Gio.SettingsSchemaSource.get_default())
|
||||
.lookup(shared.APP_ID, True)
|
||||
.list_keys()
|
||||
):
|
||||
shared.schema.reset(key)
|
||||
for key in settings_schema_source.lookup(
|
||||
shared.APP_ID + ".State", True
|
||||
).list_keys():
|
||||
shared.state_schema.reset(key)
|
||||
|
||||
shared.win.get_application().quit()
|
||||
|
||||
reset_button = Gtk.Button.new_with_label("Reset")
|
||||
reset_button.set_valign(Gtk.Align.CENTER)
|
||||
reset_button.add_css_class("destructive-action")
|
||||
reset_button.connect("clicked", reset_app)
|
||||
|
||||
self.danger_zone_group.add(
|
||||
(
|
||||
reset_action_row := Adw.ActionRow(
|
||||
title="Reset App",
|
||||
subtitle="Completely resets and quits Cartridges",
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
reset_action_row.add_suffix(reset_button)
|
||||
self.reset_action_row.set_visible(True)
|
||||
self.reset_button.connect("clicked", self.reset_app)
|
||||
self.set_default_size(-1, 560)
|
||||
|
||||
# Steam
|
||||
self.create_preferences(self, "steam", "Steam")
|
||||
|
||||
# Lutris
|
||||
self.create_preferences(self, "lutris", "Lutris")
|
||||
|
||||
def set_cache_dir(_source, result, *_args):
|
||||
try:
|
||||
path = Path(self.file_chooser.select_folder_finish(result).get_path())
|
||||
except GLib.GError:
|
||||
return
|
||||
|
||||
def response(widget, response):
|
||||
if response == "choose_folder":
|
||||
self.choose_folder(widget, set_cache_dir)
|
||||
|
||||
if lutris_cache_exists(path):
|
||||
self.set_subtitle(self, "lutris-cache")
|
||||
|
||||
# Sources settings
|
||||
for source_class in (
|
||||
BottlesSource,
|
||||
HeroicSource,
|
||||
ItchSource,
|
||||
LegendarySource,
|
||||
LutrisSource,
|
||||
SteamSource,
|
||||
):
|
||||
source = source_class()
|
||||
if not source.is_available:
|
||||
expander_row = getattr(self, f"{source.id}_expander_row")
|
||||
expander_row.remove()
|
||||
else:
|
||||
create_dialog(
|
||||
self.win,
|
||||
_("Cache Not Found"),
|
||||
_("Select the Lutris cache directory."),
|
||||
"choose_folder",
|
||||
_("Set Location"),
|
||||
).connect("response", response)
|
||||
|
||||
self.set_subtitle(self, "lutris-cache")
|
||||
|
||||
self.lutris_cache_file_chooser_button.connect(
|
||||
"clicked", self.choose_folder, set_cache_dir
|
||||
)
|
||||
|
||||
# Heroic
|
||||
self.create_preferences(self, "heroic", "Heroic", True)
|
||||
|
||||
# Bottles
|
||||
self.create_preferences(self, "bottles", "Bottles")
|
||||
|
||||
# itch
|
||||
self.create_preferences(self, "itch", "itch", True)
|
||||
|
||||
# Legendary
|
||||
self.create_preferences(self, "legendary", "Legendary", True)
|
||||
self.init_source_row(source)
|
||||
|
||||
# SteamGridDB
|
||||
def sgdb_key_changed(*_args):
|
||||
@@ -238,11 +177,6 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
)
|
||||
)
|
||||
|
||||
# Windows
|
||||
if os.name == "nt":
|
||||
self.sources_group.remove(self.lutris_expander_row)
|
||||
self.sources_group.remove(self.bottles_expander_row)
|
||||
|
||||
def get_switch(self, setting):
|
||||
return getattr(self, f'{setting.replace("-", "_")}_switch')
|
||||
|
||||
@@ -255,8 +189,8 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
Gio.SettingsBindFlags.DEFAULT,
|
||||
)
|
||||
|
||||
def choose_folder(self, _widget, function):
|
||||
self.file_chooser.select_folder(self.win, None, function, None)
|
||||
def choose_folder(self, _widget, callback, callback_data=None):
|
||||
self.file_chooser.select_folder(self.win, None, callback, callback_data)
|
||||
|
||||
def undo_remove_all(self, *_args):
|
||||
for game in self.removed_games:
|
||||
@@ -281,53 +215,98 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
||||
|
||||
self.add_toast(self.toast)
|
||||
|
||||
def set_subtitle(self, win, source_id):
|
||||
getattr(win, f'{source_id.replace("-", "_")}_action_row').set_subtitle(
|
||||
# Remove the path if the dir is picked via the Flatpak portal
|
||||
re.sub(
|
||||
"/run/user/\\d*/doc/.*/",
|
||||
"",
|
||||
str(
|
||||
Path(shared.schema.get_string(f"{source_id}-location")).expanduser()
|
||||
),
|
||||
)
|
||||
)
|
||||
def reset_app(*_args):
|
||||
rmtree(shared.data_dir / "cartridges", True)
|
||||
rmtree(shared.config_dir / "cartridges", True)
|
||||
rmtree(shared.cache_dir / "cartridges", True)
|
||||
|
||||
for key in (
|
||||
(settings_schema_source := Gio.SettingsSchemaSource.get_default())
|
||||
.lookup(shared.APP_ID, True)
|
||||
.list_keys()
|
||||
):
|
||||
shared.schema.reset(key)
|
||||
for key in settings_schema_source.lookup(
|
||||
shared.APP_ID + ".State", True
|
||||
).list_keys():
|
||||
shared.state_schema.reset(key)
|
||||
|
||||
shared.win.get_application().quit()
|
||||
|
||||
def update_source_action_row_paths(self, source):
|
||||
"""Set the dir subtitle for a source's action rows"""
|
||||
for location in ("data", "config", "cache"):
|
||||
# Get the action row to subtitle
|
||||
action_row = getattr(self, f"{source.id}_{location}_action_row", None)
|
||||
if not action_row:
|
||||
continue
|
||||
|
||||
# Historically "location" meant data or config, so the key stays shared
|
||||
infix = "-cache" if location == "cache" else ""
|
||||
key = f"{source.id}{infix}-location"
|
||||
path = Path(shared.schema.get_string(key)).expanduser()
|
||||
|
||||
# Remove the path if the dir is picked via the Flatpak portal
|
||||
subtitle = re.sub("/run/user/\\d*/doc/.*/", "", str(path))
|
||||
action_row.set_subtitle(subtitle)
|
||||
|
||||
def init_source_row(self, source: Source):
|
||||
"""Initialize a preference row for a source class"""
|
||||
|
||||
def set_dir(_widget, result, location_name):
|
||||
"""Callback called when a dir picker button is clicked"""
|
||||
|
||||
def create_preferences(self, win, source_id, name, config=False):
|
||||
def set_dir(_source, result, *_args):
|
||||
try:
|
||||
path = Path(win.file_chooser.select_folder_finish(result).get_path())
|
||||
path = Path(self.file_chooser.select_folder_finish(result).get_path())
|
||||
except GLib.GError:
|
||||
return
|
||||
|
||||
def response(widget, response):
|
||||
if response == "choose_folder":
|
||||
win.choose_folder(widget, set_dir)
|
||||
|
||||
if globals()[f"{source_id}_installed"](path):
|
||||
self.set_subtitle(win, source_id)
|
||||
# Good picked location
|
||||
location = getattr(source, f"{location_name}_location")
|
||||
if location.check_candidate(path):
|
||||
# Set the schema
|
||||
infix = "-cache" if location == "cache" else ""
|
||||
key = f"{source.id}{infix}-location"
|
||||
shared.schema.set_string(key, str(path))
|
||||
# Update the row
|
||||
self.update_source_action_row_paths(source)
|
||||
|
||||
# Bad picked location, inform user
|
||||
else:
|
||||
create_dialog(
|
||||
win,
|
||||
_("Installation Not Found"),
|
||||
# The variable is the name of the game launcher
|
||||
_("Select the {} configuration directory.").format(name) if config
|
||||
# The variable is the name of the game launcher
|
||||
else _("Select the {} data directory.").format(name),
|
||||
if location_name == "cache":
|
||||
title = "Cache not found"
|
||||
subtitle_format = "Select the {} cache directory."
|
||||
else:
|
||||
title = "Installation not found"
|
||||
subtitle_format = "Select the {} installation directory."
|
||||
dialog = create_dialog(
|
||||
self,
|
||||
_(title),
|
||||
_(subtitle_format).format(source.name),
|
||||
"choose_folder",
|
||||
_("Set Location"),
|
||||
).connect("response", response)
|
||||
)
|
||||
|
||||
self.set_subtitle(win, source_id)
|
||||
def on_response(widget, response):
|
||||
if response == "choose_folder":
|
||||
self.choose_folder(widget, set_dir, location_name)
|
||||
|
||||
dialog.connect("response", on_response)
|
||||
|
||||
# Bind expander row activation to source being enabled
|
||||
expander_row = getattr(self, f"{source.id}_expander_row")
|
||||
shared.schema.bind(
|
||||
source_id,
|
||||
getattr(win, f"{source_id}_expander_row"),
|
||||
source.id,
|
||||
expander_row,
|
||||
"enable-expansion",
|
||||
Gio.SettingsBindFlags.DEFAULT,
|
||||
)
|
||||
|
||||
getattr(win, f"{source_id}_file_chooser_button").connect(
|
||||
"clicked", win.choose_folder, set_dir
|
||||
)
|
||||
# Connect dir picker buttons
|
||||
for location in ("data", "config", "cache"):
|
||||
button = getattr(self, f"{source.id}_{location}_file_chooser_button", None)
|
||||
if button is not None:
|
||||
button.connect("clicked", self.choose_folder, set_dir, location)
|
||||
|
||||
# Set the source row subtitles
|
||||
self.update_source_action_row_paths(source)
|
||||
|
||||
Reference in New Issue
Block a user