mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
2025.01.16 04:25:45
This commit is contained in:
parent
39e9201539
commit
391b42f3bb
@ -16,8 +16,7 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import gi
|
from . import _import_gtk
|
||||||
gi.require_version('Gtk','4.0')
|
|
||||||
|
|
||||||
__version__ = "0.0.1"
|
__version__ = "0.0.1"
|
||||||
from .settings import settings
|
from .settings import settings
|
||||||
|
|||||||
23
sgbackup/_import_gtk.py
Normal file
23
sgbackup/_import_gtk.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
###############################################################################
|
||||||
|
# sgbackup - The SaveGame Backup tool #
|
||||||
|
# Copyright (C) 2024 Christian Moser #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
_GTK_IMPORTED_ = False
|
||||||
|
|
||||||
|
if not _GTK_IMPORTED_:
|
||||||
|
import gi; gi.require_version("Gtk","4.0")
|
||||||
|
_GTK_IMPORTED_ = True
|
||||||
@ -16,6 +16,8 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
from . import _import_gtk
|
||||||
|
|
||||||
from gi.repository.GObject import Property,GObject,Signal,SignalFlags
|
from gi.repository.GObject import Property,GObject,Signal,SignalFlags
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
@ -281,19 +283,12 @@ class GameData(GObject):
|
|||||||
self.__savegame_root = savegame_root
|
self.__savegame_root = savegame_root
|
||||||
self.__savegame_dir = savegame_dir
|
self.__savegame_dir = savegame_dir
|
||||||
self.__variables = {}
|
self.__variables = {}
|
||||||
self.__filematchers = []
|
self.file_matchers = file_match
|
||||||
self.__ignorematchers = []
|
self.ignore_matchers = ignore_match
|
||||||
|
|
||||||
if variables is not None:
|
if variables is not None:
|
||||||
variables.update(variables)
|
variables.update(variables)
|
||||||
|
|
||||||
if file_match is not None:
|
|
||||||
for fm in file_match:
|
|
||||||
self.add_file_match(fm)
|
|
||||||
|
|
||||||
if ignore_match is not None:
|
|
||||||
for fm in ignore_match:
|
|
||||||
self.add_ignore_match(fm)
|
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def savegame_type(self)->SavegameType:
|
def savegame_type(self)->SavegameType:
|
||||||
@ -346,9 +341,8 @@ class GameData(GObject):
|
|||||||
|
|
||||||
@file_matchers.setter
|
@file_matchers.setter
|
||||||
def file_matchers(self,fm:list[GameFileMatcher]|None):
|
def file_matchers(self,fm:list[GameFileMatcher]|None):
|
||||||
if not fm:
|
self.__filematchers = []
|
||||||
self.__filematchers = []
|
if fm:
|
||||||
else:
|
|
||||||
for matcher in fm:
|
for matcher in fm:
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("\"file_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
raise TypeError("\"file_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
||||||
@ -363,9 +357,8 @@ class GameData(GObject):
|
|||||||
return self.__ignorematchers
|
return self.__ignorematchers
|
||||||
@ignore_matchers.setter
|
@ignore_matchers.setter
|
||||||
def ignore_matchers(self,im:list[GameFileMatcher]|None):
|
def ignore_matchers(self,im:list[GameFileMatcher]|None):
|
||||||
if not im:
|
self.__ignorematchers = []
|
||||||
self.__ignorematchers = []
|
if im:
|
||||||
else:
|
|
||||||
for matcher in im:
|
for matcher in im:
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("\"ignore_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
raise TypeError("\"ignore_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
||||||
@ -426,7 +419,7 @@ class GameData(GObject):
|
|||||||
:return: The variables as a dict.
|
:return: The variables as a dict.
|
||||||
:rtype: dict[str:str]
|
:rtype: dict[str:str]
|
||||||
"""
|
"""
|
||||||
return self.variables
|
return dict(self.variables)
|
||||||
|
|
||||||
def match_file(self,rel_filename:str)->bool:
|
def match_file(self,rel_filename:str)->bool:
|
||||||
"""
|
"""
|
||||||
@ -791,6 +784,9 @@ class SteamGame(GameData):
|
|||||||
vars["INSTALLDIR"] = self.installdir if self.installdir else ""
|
vars["INSTALLDIR"] = self.installdir if self.installdir else ""
|
||||||
vars["STEAM_APPID"] = str(self.appid)
|
vars["STEAM_APPID"] = str(self.appid)
|
||||||
vars["STEAM_LIBDIR"] = self.librarydir if self.librarydir else ""
|
vars["STEAM_LIBDIR"] = self.librarydir if self.librarydir else ""
|
||||||
|
vars["STEAM_LIBRARY_DIR"] = self.librarydir if self.librarydir else ""
|
||||||
|
vars["STEAM_COMPATDATA"] = self.compatdata if self.compatdata else ""
|
||||||
|
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
@Property(type=int)
|
@Property(type=int)
|
||||||
@ -810,8 +806,9 @@ class SteamGame(GameData):
|
|||||||
@Property
|
@Property
|
||||||
def librarydir(self)->str|None:
|
def librarydir(self)->str|None:
|
||||||
if not self.__librarydir and self.installdir:
|
if not self.__librarydir and self.installdir:
|
||||||
return pathlib.Path(self.installdir).resolve().parent.parent.parent
|
return str(pathlib.Path(self.installdir).resolve().parent.parent.parent)
|
||||||
return self.__librarydir
|
return self.__librarydir
|
||||||
|
|
||||||
@librarydir.setter
|
@librarydir.setter
|
||||||
def librarydir(self,directory):
|
def librarydir(self,directory):
|
||||||
if not directory:
|
if not directory:
|
||||||
@ -820,13 +817,20 @@ class SteamGame(GameData):
|
|||||||
raise ValueError("Steam librarydir is not a valid directory!")
|
raise ValueError("Steam librarydir is not a valid directory!")
|
||||||
self.__librarydir = directory
|
self.__librarydir = directory
|
||||||
|
|
||||||
|
@Property
|
||||||
|
def compatdata(self)->str|None:
|
||||||
|
libdir = self.librarydir
|
||||||
|
if libdir:
|
||||||
|
return str(pathlib.Path(libdir).resolve() / 'steamapps' / 'compatdata')
|
||||||
|
return None
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
ret = super().serialize()
|
ret = super().serialize()
|
||||||
ret['appid'] = self.appid
|
ret['appid'] = self.appid
|
||||||
|
|
||||||
if self.installdir:
|
if self.installdir:
|
||||||
ret['installdir'] = self.installdir if self.installdir else ""
|
ret['installdir'] = str(self.installdir) if self.installdir else ""
|
||||||
ret['librarydir'] = self.librarydir if self.librarydir else ""
|
ret['librarydir'] = str(self.librarydir) if self.librarydir else ""
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -893,7 +897,7 @@ class Game(GObject):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new_from_dict(config:str):
|
def new_from_dict(config:str):
|
||||||
logger = logger.getChild("Game.new_from_dict()")
|
_logger = logger.getChild("Game.new_from_dict()")
|
||||||
|
|
||||||
def get_file_match(conf:dict):
|
def get_file_match(conf:dict):
|
||||||
conf_fm = conf['file_match'] if 'file_match' in conf else None
|
conf_fm = conf['file_match'] if 'file_match' in conf else None
|
||||||
@ -904,11 +908,11 @@ class Game(GObject):
|
|||||||
for cfm in conf_fm:
|
for cfm in conf_fm:
|
||||||
if ('type' in cfm and 'match' in cfm):
|
if ('type' in cfm and 'match' in cfm):
|
||||||
try:
|
try:
|
||||||
file_match.append(GameFileMatcher(GameFileType.from_string(cfm['type'],cfm['match'])))
|
file_match.append(GameFileMatcher(GameFileType.from_string(cfm['type']),cfm['match']))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error("Adding GameFileMatcher to file_match failed! ({})!".format(ex))
|
_logger.error("Adding GameFileMatcher to file_match failed! ({})!".format(ex))
|
||||||
else:
|
else:
|
||||||
logger.error("Illegal file_match settings! (\"type\" or \"match\" missing!)")
|
_logger.error("Illegal file_match settings! (\"type\" or \"match\" missing!)")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
file_match = None
|
file_match = None
|
||||||
@ -918,11 +922,11 @@ class Game(GObject):
|
|||||||
for cim in conf_im:
|
for cim in conf_im:
|
||||||
if ('type' in cim and 'match' in cim):
|
if ('type' in cim and 'match' in cim):
|
||||||
try:
|
try:
|
||||||
file_match.append(GameFileMatcher(GameFileType.from_string(cim['type'],cim['match'])))
|
ignore_match.append(GameFileMatcher(GameFileType.from_string(cim['type']),cim['match']))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error("Adding GameFileMatcher to ignore_match failed! ({})!".format(ex))
|
_logger.error("Adding GameFileMatcher to ignore_match failed! ({})!".format(ex))
|
||||||
else:
|
else:
|
||||||
logger.error("Illegal ignore_match settings! (\"type\" or \"match\" missing!)")
|
_logger.error("Illegal ignore_match settings! (\"type\" or \"match\" missing!)")
|
||||||
else:
|
else:
|
||||||
ignore_match = None
|
ignore_match = None
|
||||||
|
|
||||||
@ -938,18 +942,22 @@ class Game(GObject):
|
|||||||
|
|
||||||
if appid is not None and sgroot and sgdir:
|
if appid is not None and sgroot and sgdir:
|
||||||
cls(appid,sgroot,sgdir,vars,installdir,file_match,ignore_match)
|
cls(appid,sgroot,sgdir,vars,installdir,file_match,ignore_match)
|
||||||
return None
|
return cls(appid,sgroot,sgdir,vars,installdir,file_match,ignore_match)
|
||||||
# new_steam_game()
|
# new_steam_game()
|
||||||
|
|
||||||
if not 'id' in config or not 'name' in config:
|
if not 'key' in config or not 'name' in config:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
id = config['id']
|
dbid = config['dbid'] if 'dbid' in config else None
|
||||||
|
key = config['key']
|
||||||
name = config['name']
|
name = config['name']
|
||||||
sgname = config['savegame_name'] if 'savegame_name' in config else id
|
sgname = config['savegame_name'] if 'savegame_name' in config else key
|
||||||
sgtype = config['savegame_type'] if 'savegame_type' in config else SavegameType.UNSET
|
sgtype = SavegameType.from_string(config['savegame_type']) if 'savegame_type' in config else SavegameType.UNSET
|
||||||
|
|
||||||
|
game = Game(key,name,sgname)
|
||||||
|
if dbid:
|
||||||
|
game.dbid = dbid
|
||||||
|
|
||||||
game = Game(id,name,sgname)
|
|
||||||
game.savegame_type = sgtype
|
game.savegame_type = sgtype
|
||||||
game.is_active = config['is_active'] if 'is_active' in config else False
|
game.is_active = config['is_active'] if 'is_active' in config else False
|
||||||
game.is_live = config['is_live'] if 'is_live' in config else True
|
game.is_live = config['is_live'] if 'is_live' in config else True
|
||||||
@ -1007,7 +1015,12 @@ class Game(GObject):
|
|||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
raise FileNotFoundError("Filename \"{filename}\" not found!".format(filename=filename))
|
raise FileNotFoundError("Filename \"{filename}\" not found!".format(filename=filename))
|
||||||
with open(filename,'rt',encoding="UTF-8") as ifile:
|
with open(filename,'rt',encoding="UTF-8") as ifile:
|
||||||
return Game.new_from_dict(json.loads(ifile.read()))
|
x=json.loads(ifile.read())
|
||||||
|
game = Game.new_from_dict(x)
|
||||||
|
|
||||||
|
if game is not None:
|
||||||
|
game.filename = filename
|
||||||
|
return game
|
||||||
|
|
||||||
def __init__(self,key:str,name:str,savegame_name:str):
|
def __init__(self,key:str,name:str,savegame_name:str):
|
||||||
GObject.__init__(self)
|
GObject.__init__(self)
|
||||||
@ -1098,7 +1111,7 @@ class Game(GObject):
|
|||||||
self.__old_filename = self.__filename
|
self.__old_filename = self.__filename
|
||||||
|
|
||||||
if not os.path.isabs(fn):
|
if not os.path.isabs(fn):
|
||||||
self.__filename = GLib.build_filename(settings.gameconf_dir,fn)
|
self.__filename = os.path.join(settings.gameconf_dir,fn)
|
||||||
else:
|
else:
|
||||||
self.__filename = fn
|
self.__filename = fn
|
||||||
|
|
||||||
@ -1246,13 +1259,15 @@ class Game(GObject):
|
|||||||
|
|
||||||
def serialize(self)->dict:
|
def serialize(self)->dict:
|
||||||
ret = {
|
ret = {
|
||||||
'id': self.id,
|
'key': self.key,
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'savegame_name': self.savegame_name,
|
'savegame_name': self.savegame_name,
|
||||||
'savegame_type': self.savegame_type.value,
|
'savegame_type': self.savegame_type.value,
|
||||||
'is_active': self.is_active,
|
'is_active': self.is_active,
|
||||||
'is_live': self.is_live,
|
'is_live': self.is_live,
|
||||||
}
|
}
|
||||||
|
if self.dbid:
|
||||||
|
ret['dbid'] = self.dbid
|
||||||
|
|
||||||
if (self.windows):
|
if (self.windows):
|
||||||
ret['windows'] = self.windows.serialize()
|
ret['windows'] = self.windows.serialize()
|
||||||
@ -1357,6 +1372,7 @@ class Game(GObject):
|
|||||||
|
|
||||||
class GameManager(GObject):
|
class GameManager(GObject):
|
||||||
__global_gamemanager = None
|
__global_gamemanager = None
|
||||||
|
logger = logger.getChild('GameManager')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_global():
|
def get_global():
|
||||||
@ -1410,9 +1426,12 @@ class GameManager(GObject):
|
|||||||
try:
|
try:
|
||||||
game = Game.new_from_json_file(gcf)
|
game = Game.new_from_json_file(gcf)
|
||||||
if not game:
|
if not game:
|
||||||
|
self.logger.warn("Not loaded game \"{game}\"!".format(
|
||||||
|
game=(game.name if game is not None else "UNKNOWN GAME")))
|
||||||
|
print(game.serialize())
|
||||||
continue
|
continue
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error("Unable to load gameconf {gameconf}! ({what})".format(
|
self.logger.error("Unable to load gameconf {gameconf}! ({what})".format(
|
||||||
gameconf = os.path.basename(gcf),
|
gameconf = os.path.basename(gcf),
|
||||||
what = str(ex)))
|
what = str(ex)))
|
||||||
continue
|
continue
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from gi.repository import Gtk,Gio,Gdk
|
from gi.repository import Gtk,Gio,Gdk
|
||||||
from gi.repository.GObject import GObject,Signal,Property,SignalFlags
|
from gi.repository.GObject import GObject,Signal,Property,SignalFlags,BindingFlags
|
||||||
|
|
||||||
import logging; logger=logging.getLogger(__name__)
|
import logging; logger=logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
self.columnview.set_single_click_activate(True)
|
self.columnview.set_single_click_activate(True)
|
||||||
|
|
||||||
self.set_child(self.columnview)
|
self.set_child(self.columnview)
|
||||||
|
self.refresh()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _liststore(self)->Gio.ListStore:
|
def _liststore(self)->Gio.ListStore:
|
||||||
@ -120,7 +121,7 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
def _on_key_column_bind(self,factory,item):
|
def _on_key_column_bind(self,factory,item):
|
||||||
label = item.get_child()
|
label = item.get_child()
|
||||||
game = item.get_item()
|
game = item.get_item()
|
||||||
label.bind_property(game,'key','label',GObject.BindingFlags.DEFAULT)
|
game.bind_property('key',label,'label',BindingFlags.SYNC_CREATE)
|
||||||
|
|
||||||
def _on_name_column_setup(self,factory,item):
|
def _on_name_column_setup(self,factory,item):
|
||||||
item.set_child(Gtk.Label())
|
item.set_child(Gtk.Label())
|
||||||
@ -128,14 +129,14 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
def _on_name_column_bind(self,factory,item):
|
def _on_name_column_bind(self,factory,item):
|
||||||
label = item.get_child()
|
label = item.get_child()
|
||||||
game = item.get_item()
|
game = item.get_item()
|
||||||
label.bind_proprety(game,'name','label',GObject.BindingFlags.DEFAULT)
|
game.bind_property('name',label,'label',BindingFlags.SYNC_CREATE)
|
||||||
|
|
||||||
def _on_active_column_setup(self,factory,item):
|
def _on_active_column_setup(self,factory,item):
|
||||||
item.set_child(Gtk.Switch())
|
item.set_child(Gtk.Switch())
|
||||||
|
|
||||||
def _on_active_column_bind(self,factory,item):
|
def _on_active_column_bind(self,factory,item):
|
||||||
switch = item.get_child()
|
switch = item.get_child()
|
||||||
game = item.get_data()
|
game = item.get_item()
|
||||||
switch.set_active(game.is_active)
|
switch.set_active(game.is_active)
|
||||||
item._signal_active_state_set = switch.connect('state-set',self._on_active_state_set,game)
|
item._signal_active_state_set = switch.connect('state-set',self._on_active_state_set,game)
|
||||||
|
|
||||||
@ -153,8 +154,8 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
def _on_live_column_bind(self,factory,item):
|
def _on_live_column_bind(self,factory,item):
|
||||||
switch = item.get_child()
|
switch = item.get_child()
|
||||||
game = item.get_data()
|
game = item.get_item()
|
||||||
switch.set_active(game.is_active)
|
switch.set_active(game.is_live)
|
||||||
item._signal_live_state_set = switch.connect('state-set',self._on_live_state_set,game)
|
item._signal_live_state_set = switch.connect('state-set',self._on_live_state_set,game)
|
||||||
|
|
||||||
def _on_live_column_unbind(self,factory,item):
|
def _on_live_column_unbind(self,factory,item):
|
||||||
@ -174,7 +175,7 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
game.save()
|
game.save()
|
||||||
if not state:
|
if not state:
|
||||||
dialog = Gtk.MessageDialog()
|
dialog = Gtk.MessageDialog()
|
||||||
dialog.set_transient_for(self.get_toplevel())
|
dialog.set_transient_for(self.get_root())
|
||||||
dialog.props.buttons = Gtk.ButtonsType.YES_NO
|
dialog.props.buttons = Gtk.ButtonsType.YES_NO
|
||||||
dialog.props.text = "Do you want to create a new savegame for <i>{game}</i>?".format(game=game.name)
|
dialog.props.text = "Do you want to create a new savegame for <i>{game}</i>?".format(game=game.name)
|
||||||
dialog.props.use_markup = True
|
dialog.props.use_markup = True
|
||||||
|
|||||||
@ -16,10 +16,14 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
from .. import _import_gtk
|
||||||
|
|
||||||
from gi.repository import Gio,GLib,Gtk,Pango
|
from gi.repository import Gio,GLib,Gtk,Pango
|
||||||
from gi.repository.GObject import Property,Signal,GObject,BindingFlags
|
from gi.repository.GObject import Property,Signal,GObject,BindingFlags
|
||||||
|
|
||||||
from ..game import (
|
from ..game import (
|
||||||
Game,
|
Game,
|
||||||
|
GameData,
|
||||||
GameFileMatcher,
|
GameFileMatcher,
|
||||||
GameFileType,
|
GameFileType,
|
||||||
SavegameType,
|
SavegameType,
|
||||||
@ -793,201 +797,104 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
|
@Property(type=bool,default=False)
|
||||||
|
def has_game(self)->bool:
|
||||||
|
return (self.__game is not None)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
reset Resets the dialog to the Game set on init or clears the dialog if no Game was set.
|
reset Resets the dialog to the Game set on init or clears the dialog if no Game was set.
|
||||||
"""
|
"""
|
||||||
self.__active_switch.set_active(True)
|
def set_variables(var_widget,vars:dict[str:str]|None):
|
||||||
self.__live_switch.set_active(True)
|
model = var_widget.columnview.get_model().get_model()
|
||||||
self.__name_entry.set_text("")
|
model.remove_all()
|
||||||
self.__sgname_entry.set_text("")
|
if vars:
|
||||||
self.__game_variables.columnview.get_model().get_model().remove_all()
|
for k,v in vars.items():
|
||||||
|
model.append(GameVariableData(str(k),str(v)))
|
||||||
|
|
||||||
#windows
|
def set_game_widget_data(widget,data:GameData|None):
|
||||||
self.__windows.sgroot_entry.set_text("")
|
def set_filematch(fm_widget,filematchers:list[GameFileMatcher]):
|
||||||
self.__windows.sgdir_entry.set_text("")
|
model = fm_widget.columnview.get_model().get_model()
|
||||||
self.__windows.variables.columnview.get_model().get_model().remove_all()
|
model.remove_all()
|
||||||
self.__windows.filematch.columnview.get_model().get_model().remove_all()
|
if filematchers:
|
||||||
self.__windows.ignorematch.columnview.get_model().get_model().remove_all()
|
for fm in filematchers:
|
||||||
self.__windows.lookup_regkeys.listview.get_model().get_model().remove_all()
|
model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
||||||
self.__windows.installdir_regkeys.listview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
#linux
|
|
||||||
self.__linux.sgroot_entry.set_text("")
|
|
||||||
self.__linux.sgdir_entry.set_text("")
|
|
||||||
self.__linux.binary_entry.set_text("")
|
|
||||||
self.__linux.filematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__linux.ignorematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__linux.variables.columnview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
#linux
|
|
||||||
self.__macos.sgroot_entry.set_text("")
|
|
||||||
self.__macos.sgdir_entry.set_text("")
|
|
||||||
self.__macos.binary_entry.set_text("")
|
|
||||||
self.__macos.filematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__macos.ignorematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__macos.variables.columnview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
#steam windows
|
widget.sgroot_entry.set_text(data.savegame_root if data else "")
|
||||||
self.__steam_windows.sgroot_entry.set_text("")
|
widget.sgdir_entry.set_text(data.savegame_dir if data else "")
|
||||||
self.__steam_windows.sgdir_entry.set_text("")
|
set_variables(widget.variables,data.variables if data else None)
|
||||||
self.__steam_windows.appid_entry.set_text("")
|
set_filematch(widget.filematch,data.file_matchers if data else None)
|
||||||
self.__steam_windows.installdir_entry.set_text("")
|
set_filematch(widget.ignorematch,data.ignore_matchers if data else None)
|
||||||
self.__steam_windows.filematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_windows.ignorematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_windows.variables.columnview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
#steam linux
|
self.__active_switch.set_active(self.__game.is_active if self.has_game else True)
|
||||||
self.__steam_linux.sgroot_entry.set_text("")
|
self.__live_switch.set_active(self.__game.is_live if self.has_game else True)
|
||||||
self.__steam_linux.sgdir_entry.set_text("")
|
self.__name_entry.set_text(self.__game.name if self.has_game else "")
|
||||||
self.__steam_linux.appid_entry.set_text("")
|
self.__sgname_entry.set_text(self.__game.savegame_name if self.has_game else "")
|
||||||
self.__steam_linux.installdir_entry.set_text("")
|
set_variables(self.__game_variables,self.__game.variables if self.has_game else None)
|
||||||
self.__steam_linux.filematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_linux.ignorematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_linux.variables.columnview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
#steam macos
|
if self.has_game:
|
||||||
self.__steam_macos.sgroot_entry.set_text("")
|
|
||||||
self.__steam_macos.sgdir_entry.set_text("")
|
|
||||||
self.__steam_macos.appid_entry.set_text("")
|
|
||||||
self.__steam_macos.installdir_entry.set_text("")
|
|
||||||
self.__steam_macos.filematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_macos.ignorematch.columnview.get_model().get_model().remove_all()
|
|
||||||
self.__steam_macos.variables.columnview.get_model().get_model().remove_all()
|
|
||||||
|
|
||||||
if self.__game is not None:
|
|
||||||
self.__active_switch.set_active(self.__game.is_active)
|
|
||||||
self.__live_switch.set_active(self.__game.is_live)
|
|
||||||
self.__name_entry.set_text(self.__game.name)
|
|
||||||
self.__sgname_entry.set_text(self.__game.savegame_name)
|
|
||||||
model = self.__savegame_type_dropdown.get_model()
|
model = self.__savegame_type_dropdown.get_model()
|
||||||
|
sgtype = self.__game.savegame_type
|
||||||
for i in range(model.get_n_items()):
|
for i in range(model.get_n_items()):
|
||||||
if model.get_item(i).savegame_type == self.__game.savegame_type:
|
item = model.get_item(i)
|
||||||
|
if sgtype == item.savegame_type:
|
||||||
self.__savegame_type_dropdown.set_selected(i)
|
self.__savegame_type_dropdown.set_selected(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
for name,value in self.__game.variables.items():
|
#windows
|
||||||
self.__game_variables.get_model().get_model().append(GameVariableData(name,value))
|
set_game_widget_data(self.__windows,self.__game.windows if self.has_game else None)
|
||||||
|
self.__windows.lookup_regkeys.listview.get_model().get_model().remove_all()
|
||||||
|
self.__windows.installdir_regkeys.listview.get_model().get_model().remove_all()
|
||||||
|
if self.has_game and self.__game.windows:
|
||||||
|
grk_model = self.__windows.lookup_regkeys.listview.get_model().get_model()
|
||||||
|
irk_model = self.__windows.installdir_regkeys.listview.get_model().get_model()
|
||||||
|
for rk in self.__game.windows.game_registry_keys:
|
||||||
|
grk_model.append(RegistryKeyData(rk))
|
||||||
|
|
||||||
if self.__game.windows:
|
#set installdir regkeys
|
||||||
self.__windows.sgroot_entry.set_text(self.__game.windows.savegame_root)
|
for rk in self.__game.windows.installdir_registry_keys:
|
||||||
self.__windows.sgdir_entry.set_text(self.__game.windows.savegame_dir)
|
irk_model.append(RegistryKeyData(rk))
|
||||||
self.__windows.installdir_entry.set_text(self.__game.windows.installdir)
|
|
||||||
|
|
||||||
#filematch
|
#linux
|
||||||
fm_model = self.__windows.filematch.columnview.get_model().get_model()
|
set_game_widget_data(self.__linux,self.__game.linux if self.has_game else None)
|
||||||
for fm in self.__game.windows.file_matchers:
|
self.__linux.binary_entry.set_text(self.__game.linux.binary if self.has_game and self.__game.linux else "")
|
||||||
fm_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
im_model = self.__windows.ignorematch.columnview.get_model().get_model()
|
#macos
|
||||||
for im in self.__game.windows.ignore_matchers:
|
set_game_widget_data(self.__macos,self.__game.macos if self.__game else None)
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
self.__macos.binary_entry.set_text(self.__game.macos.binary if self.has_game and self.__game.macos else "")
|
||||||
|
|
||||||
# set lookup regkeys
|
#steam windows
|
||||||
var_model = self.__windows.variables.columnview.get_model().get_model()
|
set_game_widget_data(self.__steam_windows,self.__game.steam_windows if self.has_game else None)
|
||||||
grk_model = self.__windows.lookup_regkeys.listview.get_model().get_model()
|
self.__steam_windows.appid_entry.set_text(str(self.__game.steam_windows.appid)
|
||||||
irk_model = self.__windows.installdir_regkeys.listview.get_model().get_model()
|
if self.has_game and self.__game.steam_windows else "")
|
||||||
for rk in self.__game.windows.game_registry_keys:
|
self.__steam_windows.installdir_entry.set_text(self.__game.steam_windows.installdir
|
||||||
grk_model.append(RegistryKeyData(rk))
|
if self.has_game
|
||||||
|
and self.__game.steam_windows
|
||||||
|
and self.__game.steam_windows.installdir
|
||||||
|
else "")
|
||||||
|
|
||||||
#set installdir regkeys
|
#steam linux
|
||||||
for rk in self.__game.windows.installdir_registry_keys:
|
set_game_widget_data(self.__steam_linux,self.__game.steam_linux if self.has_game else None)
|
||||||
irk_model.append(RegistryKeyData(rk))
|
self.__steam_linux.appid_entry.set_text(str(self.__game.steam_linux.appid)
|
||||||
|
if self.has_game and self.__game.steam_linux else "")
|
||||||
|
self.__steam_linux.installdir_entry.set_text(self.__game.steam_linux.installdir
|
||||||
|
if self.has_game
|
||||||
|
and self.__game.steam_linux
|
||||||
|
and self.__game.steam_linux.installdir
|
||||||
|
else "")
|
||||||
|
|
||||||
#set variables
|
#steam macos
|
||||||
for name,value in self.__game.windows.variables.items():
|
set_game_widget_data(self.__steam_macos,self.__game.steam_macos if self.has_game else None)
|
||||||
var_model.append(GameVariableData(name,value))
|
self.__steam_macos.appid_entry.set_text(str(self.__game.steam_macos.appid)
|
||||||
|
if self.has_game and self.__game.steam_macos else "")
|
||||||
|
self.__steam_macos.installdir_entry.set_text(self.__game.steam_macos.installdir
|
||||||
|
if self.has_game
|
||||||
|
and self.__game.steam_macos
|
||||||
|
and self.__game.steam_macos.installdir
|
||||||
|
else "")
|
||||||
|
|
||||||
if self.__game.linux:
|
|
||||||
self.__linux.sgroot_entry.set_text(self.__game.linux.savegame_root)
|
|
||||||
self.__linux.sgdir_entry.set_text(self.__game.linux.savegame_dir)
|
|
||||||
self.__linux.binary_entry.set_text(self.__game.linux.binary)
|
|
||||||
|
|
||||||
#filematch
|
|
||||||
fm_model = self.__linux.filematch.columnview.get_model().get_model()
|
|
||||||
for fm in self.__game.linux.file_matchers:
|
|
||||||
fm_model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
|
||||||
|
|
||||||
im_model = self.__linux.ignorematch.columnview.get_model().get_model()
|
|
||||||
for im in self.__game.linux.ignore_matchers:
|
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
var_model = self.__linux.variables.columnview.get_model().get_model()
|
|
||||||
for name,value in self.__game.linux.variables.items():
|
|
||||||
var_model.append(GameVariableData(name,value))
|
|
||||||
|
|
||||||
if self.__game.macos:
|
|
||||||
self.__macos.sgroot_entry.set_text(self.__game.macos.savegame_root)
|
|
||||||
self.__macos.sgdir_entry.set_text(self.__game.macos.savegame_dir)
|
|
||||||
self.__macos.binary_entry.set_text(self.__game.macos.binary)
|
|
||||||
|
|
||||||
#filematch
|
|
||||||
fm_model = self.__macos.filematch.columnview.get_model().get_model()
|
|
||||||
for fm in self.__game.macos.file_matchers:
|
|
||||||
fm_model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
|
||||||
|
|
||||||
im_model = self.__macos.ignorematch.columnview.get_model().get_model()
|
|
||||||
for im in self.__game.macos.ignore_matchers:
|
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
var_model = self.__macos.variables.columnview.get_model().get_model()
|
|
||||||
for name,value in self.__game.linux.variables.items():
|
|
||||||
var_model.append(GameVariableData(name,value))
|
|
||||||
|
|
||||||
if self.__game.steam_windows:
|
|
||||||
self.__steam_windows.sgroot_entry.set_text(self.__game.steam_windows.savegame_root)
|
|
||||||
self.__steam_windows.sgdir_entry.set_text(self.__game.steam_windows.savegame_dir)
|
|
||||||
self.__steam_windows.appid_entry.set_text(str(self.__game.steam_windows.appid))
|
|
||||||
self.__steam_windows.installdir_entry.set_text(self.__game.steam_windows.installdir if self.__game.steam_windows.installdir else "")
|
|
||||||
|
|
||||||
#filematch
|
|
||||||
fm_model = self.__steam_windows.filematch.columnview.get_model().get_model()
|
|
||||||
for fm in self.__game.steam_windows.file_matchers:
|
|
||||||
fm_model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
|
||||||
|
|
||||||
im_model = self.__steam_windows.ignorematch.columnview.get_model().get_model()
|
|
||||||
for im in self.__game.steam_windows.ignore_matchers:
|
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
var_model = self.__steam_windows.variables.columnview.get_model().get_model()
|
|
||||||
for name,value in self.__game.steam_windows.variables.items():
|
|
||||||
var_model.append(GameVariableData(name,value))
|
|
||||||
|
|
||||||
if self.__game.steam_linux:
|
|
||||||
self.__steam_linux.sgroot_entry.set_text(self.__game.steam_linux.savegame_root)
|
|
||||||
self.__steam_linux.sgdir_entry.set_text(self.__game.steam_linux.savegame_dir)
|
|
||||||
self.__steam_linux.appid_entry.set_text(str(self.__game.steam_linux.appid))
|
|
||||||
self.__steam_linux.installdir_entry.set_text(self.__game.steam_linux.installdir if self.__game.steam_linux.installdir else "")
|
|
||||||
|
|
||||||
fm_model = self.__steam_linux.filematch.columnview.get_model().get_model()
|
|
||||||
for fm in self.__game.steam_linux.file_matchers:
|
|
||||||
fm_model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
|
||||||
|
|
||||||
im_model = self.__steam_linux.ignorematch.columnview.get_model().get_model()
|
|
||||||
for im in self.__game.steam_linux.ignore_matchers:
|
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
var_model = self.__steam_linux.variables.columnview.get_model().get_model()
|
|
||||||
for name,value in self.__game.steam_linux.variables.items():
|
|
||||||
var_model.append(GameVariableData(name,value))
|
|
||||||
|
|
||||||
if self.__game.steam_macos:
|
|
||||||
self.__steam_macos.sgroot_entry.set_text(self.__game.steam_macos.savegame_root)
|
|
||||||
self.__steam_macos.sgdir_entry.set_text(self.__game.steam_macos.savegame_dir)
|
|
||||||
self.__steam_macos.appid_entry.set_text(str(self.__game.steam_macos.appid))
|
|
||||||
self.__steam_macos.installdir_entry.set_text(self.__game.steam_macos.installdir if self.__game.steam_macos.installdir else "")
|
|
||||||
|
|
||||||
fm_model = self.__steam_macos.filematch.columnview.get_model().get_model()
|
|
||||||
for fm in self.__game.steam_macos.file_matchers:
|
|
||||||
fm_model.append(GameFileMatcher(fm.match_type,fm.match_file))
|
|
||||||
|
|
||||||
im_model = self.__steam_macos.ignorematch.columnview.get_model().get_model()
|
|
||||||
for im in self.__game.steam_macos.ignore_matchers:
|
|
||||||
im_model.append(GameFileMatcher(im.match_type,im.match_file))
|
|
||||||
|
|
||||||
var_model = self.__steam_macos.variables.columnview.get_model().get_model()
|
|
||||||
for name,value in self.__game.steam_macos.variables.items():
|
|
||||||
var_model.append(GameVariableData(name,value))
|
|
||||||
# reset()
|
# reset()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -1005,11 +912,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
for i in range(fm_model.get_n_items()):
|
for i in range(fm_model.get_n_items()):
|
||||||
fm_data = fm_model.get_item(i)
|
fm_data = fm_model.get_item(i)
|
||||||
filematch.append(GameFileMatcher(fm_data.match_type,fm_data.match_value))
|
filematch.append(fm_data)
|
||||||
|
|
||||||
for i in range(im_model.get_n_items()):
|
for i in range(im_model.get_n_items()):
|
||||||
im_data = im_model.get_item(i)
|
im_data = im_model.get_item(i)
|
||||||
ignorematch.append(GameFileMatcher(im_data.match_type,im_data.match_value))
|
ignorematch.append(im_data)
|
||||||
|
|
||||||
for i in range(var_model.get_n_items()):
|
for i in range(var_model.get_n_items()):
|
||||||
var = var_model.get_item(i)
|
var = var_model.get_item(i)
|
||||||
@ -1043,13 +950,13 @@ class GameDialog(Gtk.Dialog):
|
|||||||
name = self.__name_entry.get_text()
|
name = self.__name_entry.get_text()
|
||||||
savegame_name = self.__sgname_entry.get_text()
|
savegame_name = self.__sgname_entry.get_text()
|
||||||
savegame_type = self.__savegame_type_dropdown.get_selected_item().savegame_type
|
savegame_type = self.__savegame_type_dropdown.get_selected_item().savegame_type
|
||||||
if self.__game:
|
if self.has_game:
|
||||||
self.__game.key = key
|
self.__game.key = key
|
||||||
self.__game.name = name
|
self.__game.name = name
|
||||||
self.__game.savegame_type = savegame_type
|
self.__game.savegame_type = savegame_type
|
||||||
self.__game.savegame_name = savegame_name
|
self.__game.savegame_name = savegame_name
|
||||||
self.__game.variables = variables
|
self.__game.variables = variables
|
||||||
self.__game.filename = '.'.join((self.__game.key(),'gameconf'))
|
self.__game.filename = '.'.join((self.__game.key,'gameconf'))
|
||||||
else:
|
else:
|
||||||
self.__game = Game(key,name,savegame_name)
|
self.__game = Game(key,name,savegame_name)
|
||||||
self.__game.savegame_type = savegame_type
|
self.__game.savegame_type = savegame_type
|
||||||
@ -1279,7 +1186,7 @@ class GameDialog(Gtk.Dialog):
|
|||||||
def _on_variable_name_bind(self,factory,item):
|
def _on_variable_name_bind(self,factory,item):
|
||||||
label = item.get_child()
|
label = item.get_child()
|
||||||
data = item.get_item()
|
data = item.get_item()
|
||||||
data.bind_property('name',label,'label',GObject.BindingFlags.SYNC_CREATE)
|
data.bind_property('name',label,'label',BindingFlags.SYNC_CREATE)
|
||||||
|
|
||||||
def _on_variable_value_setup(self,factory,item):
|
def _on_variable_value_setup(self,factory,item):
|
||||||
label = Gtk.Label()
|
label = Gtk.Label()
|
||||||
@ -1288,7 +1195,7 @@ class GameDialog(Gtk.Dialog):
|
|||||||
def _on_variable_value_bind(self,factory,item):
|
def _on_variable_value_bind(self,factory,item):
|
||||||
label = item.get_child()
|
label = item.get_child()
|
||||||
data = item.get_item()
|
data = item.get_item()
|
||||||
data.bind_property('value',label,'label',GObject.BindingFlags.SYNC_CREATE)
|
data.bind_property('value',label,'label',BindingFlags.SYNC_CREATE)
|
||||||
|
|
||||||
def _on_filematch_dropdown_selection_changed(self,dropdown,data,item):
|
def _on_filematch_dropdown_selection_changed(self,dropdown,data,item):
|
||||||
data = item.get_item()
|
data = item.get_item()
|
||||||
@ -1322,13 +1229,19 @@ class GameDialog(Gtk.Dialog):
|
|||||||
def _on_filematch_value_bind(self,factory,item,widget):
|
def _on_filematch_value_bind(self,factory,item,widget):
|
||||||
label = item.get_child()
|
label = item.get_child()
|
||||||
data = item.get_item()
|
data = item.get_item()
|
||||||
if (data.match_value):
|
if (data.match_file):
|
||||||
label.set_text(data.match_value)
|
label.set_text(data.match_file)
|
||||||
|
label.bind_property('text',data,'match_file',BindingFlags.DEFAULT)
|
||||||
|
#label.connect('changed',self._on_filematch_value_label_changed,widget)
|
||||||
|
label.connect('notify::editing',self._on_filematch_value_notify_editing,widget)
|
||||||
else:
|
else:
|
||||||
label.start_editing()
|
label.bind_property('text',data,'match_file',BindingFlags.DEFAULT)
|
||||||
|
#label.connect('changed',self._on_filematch_value_label_changed,widget)
|
||||||
|
label.connect('notify::editing',self._on_filematch_value_notify_editing,widget)
|
||||||
label.grab_focus()
|
label.grab_focus()
|
||||||
label.bind_property('text',data,'match_value',BindingFlags.DEFAULT)
|
label.start_editing()
|
||||||
label.connect('changed',self._on_filematch_value_label_changed,widget)
|
|
||||||
|
|
||||||
|
|
||||||
def _on_windows_regkey_setup(self,factory,item):
|
def _on_windows_regkey_setup(self,factory,item):
|
||||||
label = Gtk.EditableLabel()
|
label = Gtk.EditableLabel()
|
||||||
@ -1378,15 +1291,26 @@ class GameDialog(Gtk.Dialog):
|
|||||||
widget.columnview.get_model().get_model().append(GameFileMatcher(GameFileType.GLOB,""))
|
widget.columnview.get_model().get_model().append(GameFileMatcher(GameFileType.GLOB,""))
|
||||||
|
|
||||||
def _on_filematch_value_label_changed(self,label,widget):
|
def _on_filematch_value_label_changed(self,label,widget):
|
||||||
if not label.get_text():
|
if not label.get_text().strip():
|
||||||
model = widget.columnview.get_model().get_model()
|
model = widget.columnview.get_model().get_model()
|
||||||
i = 0
|
i = 0
|
||||||
while i < model.get_n_items():
|
while i < model.get_n_items():
|
||||||
item = model.get_item(i)
|
item = model.get_item(i)
|
||||||
if not item.match_value.strip():
|
if not item.match_file.strip():
|
||||||
model.remove(i)
|
model.remove(i)
|
||||||
continue
|
continue
|
||||||
i += 1
|
i += 1
|
||||||
|
def _on_filematch_value_notify_editing(self,label,param,widget):
|
||||||
|
if label.props.editing == False:
|
||||||
|
if not label.get_text().strip():
|
||||||
|
model = widget.columnview.get_model().get_model()
|
||||||
|
i = 0
|
||||||
|
while i < model.get_n_items():
|
||||||
|
item = model.get_item(i)
|
||||||
|
if not item.match_file.strip():
|
||||||
|
model.remove(i)
|
||||||
|
continue
|
||||||
|
i += 1
|
||||||
|
|
||||||
def _on_windows_regkey_add_button_clicked(self,button,widget):
|
def _on_windows_regkey_add_button_clicked(self,button,widget):
|
||||||
widget.listview.get_model().get_model().append(RegistryKeyData())
|
widget.listview.get_model().get_model().append(RegistryKeyData())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user