2025.01.16 04:25:45

This commit is contained in:
Christian Moser 2025-01-16 04:25:46 +01:00
parent 39e9201539
commit 391b42f3bb
Failed to extract signature
5 changed files with 206 additions and 240 deletions

View File

@ -16,8 +16,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
###############################################################################
import gi
gi.require_version('Gtk','4.0')
from . import _import_gtk
__version__ = "0.0.1"
from .settings import settings

23
sgbackup/_import_gtk.py Normal file
View 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

View File

@ -16,6 +16,8 @@
# 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 import GLib
@ -281,19 +283,12 @@ class GameData(GObject):
self.__savegame_root = savegame_root
self.__savegame_dir = savegame_dir
self.__variables = {}
self.__filematchers = []
self.__ignorematchers = []
self.file_matchers = file_match
self.ignore_matchers = ignore_match
if variables is not None:
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
def savegame_type(self)->SavegameType:
@ -346,9 +341,8 @@ class GameData(GObject):
@file_matchers.setter
def file_matchers(self,fm:list[GameFileMatcher]|None):
if not fm:
self.__filematchers = []
else:
self.__filematchers = []
if fm:
for matcher in fm:
if not isinstance(matcher,GameFileMatcher):
raise TypeError("\"file_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
@ -363,9 +357,8 @@ class GameData(GObject):
return self.__ignorematchers
@ignore_matchers.setter
def ignore_matchers(self,im:list[GameFileMatcher]|None):
if not im:
self.__ignorematchers = []
else:
self.__ignorematchers = []
if im:
for matcher in im:
if not isinstance(matcher,GameFileMatcher):
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.
:rtype: dict[str:str]
"""
return self.variables
return dict(self.variables)
def match_file(self,rel_filename:str)->bool:
"""
@ -791,6 +784,9 @@ class SteamGame(GameData):
vars["INSTALLDIR"] = self.installdir if self.installdir else ""
vars["STEAM_APPID"] = str(self.appid)
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
@Property(type=int)
@ -810,8 +806,9 @@ class SteamGame(GameData):
@Property
def librarydir(self)->str|None:
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
@librarydir.setter
def librarydir(self,directory):
if not directory:
@ -820,13 +817,20 @@ class SteamGame(GameData):
raise ValueError("Steam librarydir is not a valid 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):
ret = super().serialize()
ret['appid'] = self.appid
if self.installdir:
ret['installdir'] = self.installdir if self.installdir else ""
ret['librarydir'] = self.librarydir if self.librarydir else ""
ret['installdir'] = str(self.installdir) if self.installdir else ""
ret['librarydir'] = str(self.librarydir) if self.librarydir else ""
return ret
@ -893,7 +897,7 @@ class Game(GObject):
@staticmethod
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):
conf_fm = conf['file_match'] if 'file_match' in conf else None
@ -904,11 +908,11 @@ class Game(GObject):
for cfm in conf_fm:
if ('type' in cfm and 'match' in cfm):
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:
logger.error("Adding GameFileMatcher to file_match failed! ({})!".format(ex))
_logger.error("Adding GameFileMatcher to file_match failed! ({})!".format(ex))
else:
logger.error("Illegal file_match settings! (\"type\" or \"match\" missing!)")
_logger.error("Illegal file_match settings! (\"type\" or \"match\" missing!)")
else:
file_match = None
@ -918,11 +922,11 @@ class Game(GObject):
for cim in conf_im:
if ('type' in cim and 'match' in cim):
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:
logger.error("Adding GameFileMatcher to ignore_match failed! ({})!".format(ex))
_logger.error("Adding GameFileMatcher to ignore_match failed! ({})!".format(ex))
else:
logger.error("Illegal ignore_match settings! (\"type\" or \"match\" missing!)")
_logger.error("Illegal ignore_match settings! (\"type\" or \"match\" missing!)")
else:
ignore_match = None
@ -938,18 +942,22 @@ class Game(GObject):
if appid is not None and sgroot and sgdir:
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()
if not 'id' in config or not 'name' in config:
if not 'key' in config or not 'name' in config:
return None
id = config['id']
dbid = config['dbid'] if 'dbid' in config else None
key = config['key']
name = config['name']
sgname = config['savegame_name'] if 'savegame_name' in config else id
sgtype = config['savegame_type'] if 'savegame_type' in config else SavegameType.UNSET
sgname = config['savegame_name'] if 'savegame_name' in config else key
sgtype = SavegameType.from_string(config['savegame_type']) if 'savegame_type' in config else SavegameType.UNSET
game = Game(id,name,sgname)
game = Game(key,name,sgname)
if dbid:
game.dbid = dbid
game.savegame_type = sgtype
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
@ -1007,7 +1015,12 @@ class Game(GObject):
if not os.path.isfile(filename):
raise FileNotFoundError("Filename \"{filename}\" not found!".format(filename=filename))
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):
GObject.__init__(self)
@ -1098,7 +1111,7 @@ class Game(GObject):
self.__old_filename = self.__filename
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:
self.__filename = fn
@ -1246,13 +1259,15 @@ class Game(GObject):
def serialize(self)->dict:
ret = {
'id': self.id,
'key': self.key,
'name': self.name,
'savegame_name': self.savegame_name,
'savegame_type': self.savegame_type.value,
'is_active': self.is_active,
'is_live': self.is_live,
}
if self.dbid:
ret['dbid'] = self.dbid
if (self.windows):
ret['windows'] = self.windows.serialize()
@ -1357,6 +1372,7 @@ class Game(GObject):
class GameManager(GObject):
__global_gamemanager = None
logger = logger.getChild('GameManager')
@staticmethod
def get_global():
@ -1410,9 +1426,12 @@ class GameManager(GObject):
try:
game = Game.new_from_json_file(gcf)
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
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),
what = str(ex)))
continue

View File

@ -17,7 +17,7 @@
###############################################################################
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__)
@ -84,6 +84,7 @@ class GameView(Gtk.ScrolledWindow):
self.columnview.set_single_click_activate(True)
self.set_child(self.columnview)
self.refresh()
@property
def _liststore(self)->Gio.ListStore:
@ -120,7 +121,7 @@ class GameView(Gtk.ScrolledWindow):
def _on_key_column_bind(self,factory,item):
label = item.get_child()
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):
item.set_child(Gtk.Label())
@ -128,14 +129,14 @@ class GameView(Gtk.ScrolledWindow):
def _on_name_column_bind(self,factory,item):
label = item.get_child()
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):
item.set_child(Gtk.Switch())
def _on_active_column_bind(self,factory,item):
switch = item.get_child()
game = item.get_data()
game = item.get_item()
switch.set_active(game.is_active)
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):
switch = item.get_child()
game = item.get_data()
switch.set_active(game.is_active)
game = item.get_item()
switch.set_active(game.is_live)
item._signal_live_state_set = switch.connect('state-set',self._on_live_state_set,game)
def _on_live_column_unbind(self,factory,item):
@ -174,7 +175,7 @@ class GameView(Gtk.ScrolledWindow):
game.save()
if not state:
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.text = "Do you want to create a new savegame for <i>{game}</i>?".format(game=game.name)
dialog.props.use_markup = True

View File

@ -16,10 +16,14 @@
# 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.GObject import Property,Signal,GObject,BindingFlags
from ..game import (
Game,
GameData,
GameFileMatcher,
GameFileType,
SavegameType,
@ -793,201 +797,104 @@ class GameDialog(Gtk.Dialog):
return widget
@Property(type=bool,default=False)
def has_game(self)->bool:
return (self.__game is not None)
def reset(self):
"""
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)
self.__live_switch.set_active(True)
self.__name_entry.set_text("")
self.__sgname_entry.set_text("")
self.__game_variables.columnview.get_model().get_model().remove_all()
def set_variables(var_widget,vars:dict[str:str]|None):
model = var_widget.columnview.get_model().get_model()
model.remove_all()
if vars:
for k,v in vars.items():
model.append(GameVariableData(str(k),str(v)))
def set_game_widget_data(widget,data:GameData|None):
def set_filematch(fm_widget,filematchers:list[GameFileMatcher]):
model = fm_widget.columnview.get_model().get_model()
model.remove_all()
if filematchers:
for fm in filematchers:
model.append(GameFileMatcher(fm.match_type,fm.match_file))
#windows
self.__windows.sgroot_entry.set_text("")
self.__windows.sgdir_entry.set_text("")
self.__windows.variables.columnview.get_model().get_model().remove_all()
self.__windows.filematch.columnview.get_model().get_model().remove_all()
self.__windows.ignorematch.columnview.get_model().get_model().remove_all()
self.__windows.lookup_regkeys.listview.get_model().get_model().remove_all()
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
self.__steam_windows.sgroot_entry.set_text("")
self.__steam_windows.sgdir_entry.set_text("")
self.__steam_windows.appid_entry.set_text("")
self.__steam_windows.installdir_entry.set_text("")
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()
widget.sgroot_entry.set_text(data.savegame_root if data else "")
widget.sgdir_entry.set_text(data.savegame_dir if data else "")
set_variables(widget.variables,data.variables if data else None)
set_filematch(widget.filematch,data.file_matchers if data else None)
set_filematch(widget.ignorematch,data.ignore_matchers if data else None)
#steam linux
self.__steam_linux.sgroot_entry.set_text("")
self.__steam_linux.sgdir_entry.set_text("")
self.__steam_linux.appid_entry.set_text("")
self.__steam_linux.installdir_entry.set_text("")
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()
self.__active_switch.set_active(self.__game.is_active if self.has_game else True)
self.__live_switch.set_active(self.__game.is_live if self.has_game else True)
self.__name_entry.set_text(self.__game.name if self.has_game else "")
self.__sgname_entry.set_text(self.__game.savegame_name if self.has_game else "")
set_variables(self.__game_variables,self.__game.variables if self.has_game else None)
#steam macos
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)
if self.has_game:
model = self.__savegame_type_dropdown.get_model()
sgtype = self.__game.savegame_type
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)
break
for name,value in self.__game.variables.items():
self.__game_variables.get_model().get_model().append(GameVariableData(name,value))
if self.__game.windows:
self.__windows.sgroot_entry.set_text(self.__game.windows.savegame_root)
self.__windows.sgdir_entry.set_text(self.__game.windows.savegame_dir)
self.__windows.installdir_entry.set_text(self.__game.windows.installdir)
#filematch
fm_model = self.__windows.filematch.columnview.get_model().get_model()
for fm in self.__game.windows.file_matchers:
fm_model.append(GameFileMatcher(im.match_type,im.match_file))
im_model = self.__windows.ignorematch.columnview.get_model().get_model()
for im in self.__game.windows.ignore_matchers:
im_model.append(GameFileMatcher(im.match_type,im.match_file))
# set lookup regkeys
var_model = self.__windows.variables.columnview.get_model().get_model()
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))
#set installdir regkeys
for rk in self.__game.windows.installdir_registry_keys:
irk_model.append(RegistryKeyData(rk))
#set variables
for name,value in self.__game.windows.variables.items():
var_model.append(GameVariableData(name,value))
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)
#windows
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))
#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))
#set installdir regkeys
for rk in self.__game.windows.installdir_registry_keys:
irk_model.append(RegistryKeyData(rk))
#linux
set_game_widget_data(self.__linux,self.__game.linux if self.has_game else None)
self.__linux.binary_entry.set_text(self.__game.linux.binary if self.has_game and self.__game.linux else "")
#macos
set_game_widget_data(self.__macos,self.__game.macos if self.__game else None)
self.__macos.binary_entry.set_text(self.__game.macos.binary if self.has_game and self.__game.macos else "")
#steam windows
set_game_widget_data(self.__steam_windows,self.__game.steam_windows if self.has_game else None)
self.__steam_windows.appid_entry.set_text(str(self.__game.steam_windows.appid)
if self.has_game and self.__game.steam_windows else "")
self.__steam_windows.installdir_entry.set_text(self.__game.steam_windows.installdir
if self.has_game
and self.__game.steam_windows
and self.__game.steam_windows.installdir
else "")
#steam linux
set_game_widget_data(self.__steam_linux,self.__game.steam_linux if self.has_game else None)
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 "")
#steam macos
set_game_widget_data(self.__steam_macos,self.__game.steam_macos if self.has_game else None)
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.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()
def save(self):
@ -1005,11 +912,11 @@ class GameDialog(Gtk.Dialog):
for i in range(fm_model.get_n_items()):
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()):
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()):
var = var_model.get_item(i)
@ -1043,13 +950,13 @@ class GameDialog(Gtk.Dialog):
name = self.__name_entry.get_text()
savegame_name = self.__sgname_entry.get_text()
savegame_type = self.__savegame_type_dropdown.get_selected_item().savegame_type
if self.__game:
if self.has_game:
self.__game.key = key
self.__game.name = name
self.__game.savegame_type = savegame_type
self.__game.savegame_name = savegame_name
self.__game.variables = variables
self.__game.filename = '.'.join((self.__game.key(),'gameconf'))
self.__game.filename = '.'.join((self.__game.key,'gameconf'))
else:
self.__game = Game(key,name,savegame_name)
self.__game.savegame_type = savegame_type
@ -1279,7 +1186,7 @@ class GameDialog(Gtk.Dialog):
def _on_variable_name_bind(self,factory,item):
label = item.get_child()
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):
label = Gtk.Label()
@ -1288,7 +1195,7 @@ class GameDialog(Gtk.Dialog):
def _on_variable_value_bind(self,factory,item):
label = item.get_child()
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):
data = item.get_item()
@ -1322,13 +1229,19 @@ class GameDialog(Gtk.Dialog):
def _on_filematch_value_bind(self,factory,item,widget):
label = item.get_child()
data = item.get_item()
if (data.match_value):
label.set_text(data.match_value)
if (data.match_file):
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:
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.bind_property('text',data,'match_value',BindingFlags.DEFAULT)
label.connect('changed',self._on_filematch_value_label_changed,widget)
label.start_editing()
def _on_windows_regkey_setup(self,factory,item):
label = Gtk.EditableLabel()
@ -1378,16 +1291,27 @@ class GameDialog(Gtk.Dialog):
widget.columnview.get_model().get_model().append(GameFileMatcher(GameFileType.GLOB,""))
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()
i = 0
while i < model.get_n_items():
item = model.get_item(i)
if not item.match_value.strip():
if not item.match_file.strip():
model.remove(i)
continue
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):
widget.listview.get_model().get_model().append(RegistryKeyData())