mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
added EpicGames support
This commit is contained in:
parent
f3ef3df537
commit
db8a01d43d
@ -24,24 +24,24 @@ from .settings import settings
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from i18n import gettext as _
|
from .i18n import gettext as _
|
||||||
|
from .game import GameManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
PLATFORM_WINDOWS = sys.platform.lower().startswith('win')
|
|
||||||
|
|
||||||
class EpicGameInfo(GObject):
|
class EpicGameInfo(GObject):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name:str,
|
name:str,
|
||||||
installdir:str,
|
installdir:str,
|
||||||
appname:str,
|
catalog_item_id:str,
|
||||||
main_appname:str):
|
main_catalog_item_id:str):
|
||||||
GObject.__init__(self)
|
GObject.__init__(self)
|
||||||
|
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__installdir = installdir
|
self.__installdir = installdir
|
||||||
self.__appname = appname
|
self.__catalog_item_id = catalog_item_id
|
||||||
self.__main_appname = main_appname
|
self.__main_catalog_item_id = main_catalog_item_id
|
||||||
|
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
@ -53,27 +53,27 @@ class EpicGameInfo(GObject):
|
|||||||
return self.__installdir
|
return self.__installdir
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def appname(self)->str:
|
def catalog_item_id(self)->str:
|
||||||
return self.__appname
|
return self.__catalog_item_id
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def main_appname(self)->str:
|
def main_catalog_item_id(self)->str:
|
||||||
return self.__main_appname
|
return self.__main_catalog_item_id
|
||||||
|
|
||||||
@Property(type=bool,default=False)
|
@Property(type=bool,default=False)
|
||||||
def is_main(self)->bool:
|
def is_main(self)->bool:
|
||||||
return (self.appname == self.main_appname)
|
return (self.catalog_item_id == self.main_catalog_item_id)
|
||||||
|
|
||||||
class EpicIgnoredApp(GObject):
|
class EpicIgnoredApp(GObject):
|
||||||
def __init__(self,appname:str,name:str,reason:str):
|
def __init__(self,catalog_item_id:str,name:str,reason:str):
|
||||||
GObject.__init__(self)
|
GObject.__init__(self)
|
||||||
self.__appname = appname
|
self.__catalog_item_id = catalog_item_id
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__reason = reason
|
self.__reason = reason
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def appname(self)->str:
|
def catalog_item_id(self)->str:
|
||||||
return self.__appname
|
return self.__catalog_item_id
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def name(self)->str:
|
def name(self)->str:
|
||||||
@ -85,7 +85,7 @@ class EpicIgnoredApp(GObject):
|
|||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
'appname':self.appname,
|
'catalog_item_id':self.catalog_item_id,
|
||||||
'name':self.name,
|
'name':self.name,
|
||||||
'reason':self.reason,
|
'reason':self.reason,
|
||||||
}
|
}
|
||||||
@ -107,11 +107,11 @@ class Epic(GObject):
|
|||||||
def __parse_ignore_file(self)->dict[str:EpicIgnoredApp]:
|
def __parse_ignore_file(self)->dict[str:EpicIgnoredApp]:
|
||||||
ret = {}
|
ret = {}
|
||||||
if os.path.isfile(self.ignore_file):
|
if os.path.isfile(self.ignore_file):
|
||||||
with open(self.ignore_file,'r',encoding="urf-8") as ifile:
|
with open(self.ignore_file,'r',encoding="utf-8") as ifile:
|
||||||
data = json.loads(ifile.read())
|
data = json.loads(ifile.read())
|
||||||
|
|
||||||
for i in data:
|
for i in data:
|
||||||
ret[i['appname']] = EpicIgnoredApp(i['appname'],i['name'],i['reason'])
|
ret[i['catalog_item_id']] = EpicIgnoredApp(i['catalog_item_id'],i['name'],i['reason'])
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -126,24 +126,24 @@ class Epic(GObject):
|
|||||||
if not isinstance(app,EpicIgnoredApp):
|
if not isinstance(app,EpicIgnoredApp):
|
||||||
raise TypeError('app is not an EpicIgnoredApp instance!')
|
raise TypeError('app is not an EpicIgnoredApp instance!')
|
||||||
|
|
||||||
self.__ignored_apps[app.appname] = app
|
self.__ignored_apps[app.catalog_item_id] = app
|
||||||
self.__write_ignore_file()
|
self.__write_ignore_file()
|
||||||
|
|
||||||
def remove_ignored_apps(self,app:str|EpicIgnoredApp):
|
def remove_ignored_apps(self,app:str|EpicIgnoredApp):
|
||||||
if isinstance(app,str):
|
if isinstance(app,str):
|
||||||
appname = app
|
item_id = app
|
||||||
elif isinstance(app,EpicIgnoredApp):
|
elif isinstance(app,EpicIgnoredApp):
|
||||||
appname = app.appname
|
item_id = app.catalog_item_id
|
||||||
else:
|
else:
|
||||||
raise TypeError("app is not a string and not an EpicIgnoredApp instance!")
|
raise TypeError("app is not a string and not an EpicIgnoredApp instance!")
|
||||||
|
|
||||||
if appname in self.__ignored_apps:
|
if item_id in self.__ignored_apps:
|
||||||
del self.__ignored_apps[appname]
|
del self.__ignored_apps[item_id]
|
||||||
self.__write_ignore_file()
|
self.__write_ignore_file()
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def ignored_apps(self)->dict[str:EpicIgnoredApp]:
|
def ignored_apps(self)->dict[str:EpicIgnoredApp]:
|
||||||
return self.__ignored_apps
|
return dict(self.__ignored_apps)
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def datadir(self):
|
def datadir(self):
|
||||||
@ -169,8 +169,8 @@ class Epic(GObject):
|
|||||||
return EpicGameInfo(
|
return EpicGameInfo(
|
||||||
name=data['DisplayName'],
|
name=data['DisplayName'],
|
||||||
installdir=data['InstallLocation'],
|
installdir=data['InstallLocation'],
|
||||||
appname=data['AppName'],
|
catalog_item_id=data['CatalogItemId'],
|
||||||
main_appname=data['MainGameAppName']
|
main_catalog_item_id=data['MainGameCatalogItemId']
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -181,13 +181,15 @@ class Epic(GObject):
|
|||||||
manifest_file = os.path.join(manifest_dir,item)
|
manifest_file = os.path.join(manifest_dir,item)
|
||||||
info = self.parse_manifest(manifest_file)
|
info = self.parse_manifest(manifest_file)
|
||||||
if info is not None:
|
if info is not None:
|
||||||
ret += info
|
ret.append(info)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_apps(self)->list[EpicGameInfo]:
|
def find_apps(self)->list[EpicGameInfo]:
|
||||||
return [i for i in self.parse_all_manifests() if i.appname == i.main_appname]
|
return [i for i in self.parse_all_manifests() if i.is_main]
|
||||||
|
|
||||||
def get_new_apps(self)->list[EpicGameInfo]:
|
def find_new_apps(self)->list[EpicGameInfo]:
|
||||||
return []
|
gm = GameManager.get_global()
|
||||||
|
return [i for i in self.find_apps()
|
||||||
|
if not gm.has_epic_game(i.catalog_item_id) and not i.catalog_item_id in self.__ignored_apps]
|
||||||
|
|
||||||
@ -1207,19 +1207,21 @@ class EpicWindowsData(EpicPlatformData):
|
|||||||
|
|
||||||
|
|
||||||
class EpicGameData(GObject):
|
class EpicGameData(GObject):
|
||||||
def __init__(self,appname:str,windows:EpicWindowsData|None):
|
def __init__(self,
|
||||||
|
catalog_item_id:str|None=None,
|
||||||
|
windows:EpicWindowsData|None=None):
|
||||||
GObject.__init__(self)
|
GObject.__init__(self)
|
||||||
self.__appname = appname
|
self.__catalog_item_id = catalog_item_id
|
||||||
self.windows = windows
|
self.windows = windows
|
||||||
|
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def appname(self)->str:
|
def catalog_item_id(self)->str:
|
||||||
return self.__appname
|
return self.__catalog_item_id if self.__catalog_item_id else ""
|
||||||
|
|
||||||
@appname.setter
|
@catalog_item_id.setter
|
||||||
def appname(self,appname:str):
|
def catalog_item_id(self,catalog_item_id:str):
|
||||||
self.__appname = appname
|
self.__catalog_item_id = catalog_item_id
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def windows(self)->EpicWindowsData|None:
|
def windows(self)->EpicWindowsData|None:
|
||||||
@ -1236,7 +1238,7 @@ class EpicGameData(GObject):
|
|||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
ret = {
|
ret = {
|
||||||
"appname": self.appname
|
"catalog_item_id": self.catalog_item_id
|
||||||
}
|
}
|
||||||
if self.windows and self.windows.is_valid:
|
if self.windows and self.windows.is_valid:
|
||||||
ret["windows"] = self.windows.serialize()
|
ret["windows"] = self.windows.serialize()
|
||||||
@ -1299,7 +1301,7 @@ class Game(GObject):
|
|||||||
librarydir=data['librarydir'] if ('librarydir' in data and data['librarydir']) else None
|
librarydir=data['librarydir'] if ('librarydir' in data and data['librarydir']) else None
|
||||||
)
|
)
|
||||||
|
|
||||||
if ('steam' not in conf or not 'appid' in conf['steam']):
|
if ('steam' not in conf):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
steam=conf['steam']
|
steam=conf['steam']
|
||||||
@ -1322,7 +1324,7 @@ class Game(GObject):
|
|||||||
if windows is None and linux is None and macos is None:
|
if windows is None and linux is None and macos is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return SteamGameData(steam['appid'],
|
return SteamGameData(steam['appid'] if 'appid' in steam else -1,
|
||||||
windows=windows,
|
windows=windows,
|
||||||
linux=linux,
|
linux=linux,
|
||||||
macos=macos)
|
macos=macos)
|
||||||
@ -1344,7 +1346,7 @@ class Game(GObject):
|
|||||||
librarydir=data['librarydir'] if ('librarydir' in data and data['librarydir']) else None
|
librarydir=data['librarydir'] if ('librarydir' in data and data['librarydir']) else None
|
||||||
)
|
)
|
||||||
|
|
||||||
if not "epic" in conf or not "appname" in conf["epic"]:
|
if not "epic" in conf:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if ("windows" in conf['epic']):
|
if ("windows" in conf['epic']):
|
||||||
@ -1352,7 +1354,7 @@ class Game(GObject):
|
|||||||
else:
|
else:
|
||||||
windows = None
|
windows = None
|
||||||
|
|
||||||
return EpicGameData(conf['epic']['appname'],
|
return EpicGameData(conf['epic']['catalog_item_id'] if 'catalog_item_id' in conf['epic'] else "",
|
||||||
windows=windows)
|
windows=windows)
|
||||||
|
|
||||||
# new_epic_data()
|
# new_epic_data()
|
||||||
@ -1811,8 +1813,17 @@ class GameManager(GObject):
|
|||||||
|
|
||||||
@Property
|
@Property
|
||||||
def steam_games(self)->dict[int:Game]:
|
def steam_games(self)->dict[int:Game]:
|
||||||
return self.__steam_games
|
return dict(self.__steam_games)
|
||||||
|
|
||||||
|
def has_steam_game(self,appid:int)->bool:
|
||||||
|
return (appid in self.__steam_games)
|
||||||
|
@Property
|
||||||
|
def epic_games(self)->dict[str:Game]:
|
||||||
|
return dict(self.__epic_games)
|
||||||
|
|
||||||
|
def has_epic_game(self,catalog_item_id:str)->bool:
|
||||||
|
return (catalog_item_id in self.__epic_games)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
if self.__games:
|
if self.__games:
|
||||||
self.__games = {}
|
self.__games = {}
|
||||||
@ -1844,7 +1855,7 @@ class GameManager(GObject):
|
|||||||
if game.steam:
|
if game.steam:
|
||||||
self.__steam_games[game.steam.appid] = game
|
self.__steam_games[game.steam.appid] = game
|
||||||
if game.epic:
|
if game.epic:
|
||||||
self.__epic_games[game.epic.appname] = game
|
self.__epic_games[game.epic.catalog_item_id] = game
|
||||||
|
|
||||||
def remove_game(self,game:Game|str):
|
def remove_game(self,game:Game|str):
|
||||||
if isinstance(game,str):
|
if isinstance(game,str):
|
||||||
|
|||||||
@ -46,8 +46,9 @@ from ._steam import (
|
|||||||
SteamNoIgnoredAppsDialog,
|
SteamNoIgnoredAppsDialog,
|
||||||
SteamIgnoreAppsDialog,
|
SteamIgnoreAppsDialog,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ..steam import Steam
|
from ..steam import Steam
|
||||||
|
from ..epic import Epic
|
||||||
|
from ._epic import EpicNewAppsDialog
|
||||||
from ._backupdialog import BackupSingleDialog,BackupManyDialog
|
from ._backupdialog import BackupSingleDialog,BackupManyDialog
|
||||||
from ..archiver import ArchiverManager
|
from ..archiver import ArchiverManager
|
||||||
from ._dialogs import (
|
from ._dialogs import (
|
||||||
@ -392,7 +393,7 @@ class GameView(Gtk.Box):
|
|||||||
def do_game_live_changed(self,game:Game):
|
def do_game_live_changed(self,game:Game):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _on_new_steamapps_dialog_response(self,dialog,response):
|
def _on_new_apps_dialog_response(self,dialog,response):
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
def _on_add_game_button_clicked(self,button):
|
def _on_add_game_button_clicked(self,button):
|
||||||
@ -404,15 +405,28 @@ class GameView(Gtk.Box):
|
|||||||
steam = Steam()
|
steam = Steam()
|
||||||
if steam.find_new_steamapps():
|
if steam.find_new_steamapps():
|
||||||
dialog = NewSteamAppsDialog(parent=self.get_root())
|
dialog = NewSteamAppsDialog(parent=self.get_root())
|
||||||
dialog.connect_after('response',self._on_new_steamapps_dialog_response)
|
dialog.connect_after('response',self._on_new_apps_dialog_response)
|
||||||
dialog.present()
|
dialog.present()
|
||||||
else:
|
else:
|
||||||
dialog = SteamNoNewAppsDialog(parent=self.get_root())
|
dialog = SteamNoNewAppsDialog(parent=self.get_root())
|
||||||
dialog.present()
|
dialog.present()
|
||||||
|
|
||||||
def _on_new_epic_games_button_clicked(self,button):
|
def _on_new_epic_games_button_clicked(self,button):
|
||||||
# TODO
|
epic = Epic()
|
||||||
pass
|
if not epic.find_new_apps():
|
||||||
|
dialog = Gtk.MessageDialog(
|
||||||
|
transient_for=self.get_root(),
|
||||||
|
message="No new Epic-Games applications found!",
|
||||||
|
buttons=Gtk.ButtonsType.OK,
|
||||||
|
modal=False
|
||||||
|
)
|
||||||
|
dialog.connect('response',lambda d,r: d.destroy())
|
||||||
|
dialog.present()
|
||||||
|
return
|
||||||
|
|
||||||
|
dialog = EpicNewAppsDialog(self.get_root())
|
||||||
|
dialog.connect_after('response',self._on_new_apps_dialog_response)
|
||||||
|
dialog.present()
|
||||||
|
|
||||||
def _on_backup_active_live_button_clicked(self,button):
|
def _on_backup_active_live_button_clicked(self,button):
|
||||||
backup_games = []
|
backup_games = []
|
||||||
|
|||||||
229
sgbackup/gui/_epic.py
Normal file
229
sgbackup/gui/_epic.py
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
###############################################################################
|
||||||
|
# sgbackup - The SaveGame Backup tool #
|
||||||
|
# Copyright (C) 2024,2025 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/>. #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
from gi.repository import Gtk,GLib,Gio
|
||||||
|
from gi.repository.GObject import GObject,Property,Signal,SignalFlags
|
||||||
|
|
||||||
|
from ..i18n import gettext as _,gettext_noop as N_
|
||||||
|
from ..game import GameManager,Game,EpicGameData,EpicWindowsData
|
||||||
|
from ..epic import Epic,EpicGameInfo,EpicIgnoredApp
|
||||||
|
from ..utility import PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
from ._gamedialog import GameDialog
|
||||||
|
|
||||||
|
class EpicNewAppsDialogSorter(Gtk.Sorter):
|
||||||
|
def do_compare(self,item1:EpicGameInfo,item2:EpicGameInfo):
|
||||||
|
name1 = item1.name.lower()
|
||||||
|
name2 = item2.name.lower()
|
||||||
|
|
||||||
|
if name1 > name2:
|
||||||
|
return Gtk.Ordering.LARGER
|
||||||
|
elif name1 < name2:
|
||||||
|
return Gtk.Ordering.SMALLER
|
||||||
|
return Gtk.Ordering.EQUAL
|
||||||
|
|
||||||
|
class EpicNewAppsDialog(Gtk.Dialog):
|
||||||
|
def __init__(self,parent:Gtk.Window|None=None):
|
||||||
|
Gtk.Dialog.__init__(self,
|
||||||
|
transient_for=parent,
|
||||||
|
title=_("SGBackup: Manage new Epic-Games apps"),
|
||||||
|
modal=False)
|
||||||
|
|
||||||
|
self.set_default_size(800,600)
|
||||||
|
scrolled = Gtk.ScrolledWindow()
|
||||||
|
|
||||||
|
epic = Epic()
|
||||||
|
self.__liststore = Gio.ListStore.new(EpicGameInfo)
|
||||||
|
for info in epic.find_new_apps():
|
||||||
|
self.__liststore.append(info)
|
||||||
|
|
||||||
|
sort_model = Gtk.SortListModel(model=self.__liststore,
|
||||||
|
sorter=EpicNewAppsDialogSorter())
|
||||||
|
selection = Gtk.SingleSelection(model=sort_model,
|
||||||
|
autoselect=False,
|
||||||
|
can_unselect=True)
|
||||||
|
|
||||||
|
factory = Gtk.SignalListItemFactory()
|
||||||
|
factory.connect('setup',self._on_listview_setup)
|
||||||
|
factory.connect('bind',self._on_listview_bind)
|
||||||
|
|
||||||
|
self.__listview = Gtk.ListView(model=selection,factory=factory,hexpand=True,vexpand=True)
|
||||||
|
scrolled.set_child(self.__listview)
|
||||||
|
self.get_content_area().append(scrolled)
|
||||||
|
self.__close_button = self.add_button(_("Close"),Gtk.ResponseType.OK)
|
||||||
|
|
||||||
|
|
||||||
|
def _on_listview_setup(self,factory,item):
|
||||||
|
child = Gtk.Grid(column_spacing=4,row_spacing=2)
|
||||||
|
|
||||||
|
child.name_label = Gtk.Label(xalign=0.0,hexpand=True)
|
||||||
|
child.attach(child.name_label,1,0,1,1)
|
||||||
|
|
||||||
|
label = Gtk.Label(label=_("CatalogItemId:"),
|
||||||
|
use_markup=False,
|
||||||
|
xalign=0.0)
|
||||||
|
child.catalogitemid_label = Gtk.Label(xalign=0.0,
|
||||||
|
use_markup=False,
|
||||||
|
hexpand=True)
|
||||||
|
child.attach(label,0,1,1,1)
|
||||||
|
child.attach(child.catalogitemid_label,1,1,1,1)
|
||||||
|
|
||||||
|
label = Gtk.Label(label=_("Installation Directory:"),
|
||||||
|
use_markup=False,
|
||||||
|
xalign=0.0)
|
||||||
|
child.installdir_label = Gtk.Label(xalign=0.0,
|
||||||
|
use_markup=False,
|
||||||
|
hexpand=True)
|
||||||
|
child.attach(label,0,2,1,1)
|
||||||
|
child.attach(child.installdir_label,1,2,1,1)
|
||||||
|
|
||||||
|
actiongrid = Gtk.Grid(row_spacing=2,column_spacing=2)
|
||||||
|
|
||||||
|
icon = Gtk.Image.new_from_icon_name('list-add-symbolic')
|
||||||
|
icon.set_pixel_size(16)
|
||||||
|
child.new_button = Gtk.Button()
|
||||||
|
child.new_button.set_child(icon)
|
||||||
|
child.new_button.set_tooltip_text(_("Add Epic-Games-app as a new game."))
|
||||||
|
actiongrid.attach(child.new_button,0,0,1,1)
|
||||||
|
|
||||||
|
icon = Gtk.Image.new_from_icon_name('edit-delete-symbolic')
|
||||||
|
icon.set_pixel_size(16)
|
||||||
|
child.ignore_button = Gtk.Button()
|
||||||
|
child.ignore_button.set_child(icon)
|
||||||
|
child.ignore_button.set_tooltip_text(_("Add Epic-Games-app to the ignore list."))
|
||||||
|
actiongrid.attach(child.ignore_button,1,0,1,1)
|
||||||
|
|
||||||
|
icon = Gtk.Image.new_from_icon_name('edit-find-symbolic')
|
||||||
|
icon.set_pixel_size(16)
|
||||||
|
child.lookup_button = Gtk.Button()
|
||||||
|
child.lookup_button.set_child(icon)
|
||||||
|
child.lookup_button.set_tooltip_text(_("Lookup Epic-Games-app for already registered game."))
|
||||||
|
actiongrid.attach(child.lookup_button,0,1,1,1)
|
||||||
|
|
||||||
|
icon = Gtk.Image.new_from_icon_name('folder-download-symbolic')
|
||||||
|
icon.set_pixel_size(16)
|
||||||
|
child.online_button = Gtk.Button()
|
||||||
|
child.online_button.set_child(icon)
|
||||||
|
child.online_button.set_tooltip_text(_("Lookup Epic-Games-app online."))
|
||||||
|
actiongrid.attach(child.online_button,1,1,1,1)
|
||||||
|
|
||||||
|
child.attach(actiongrid,2,0,1,3)
|
||||||
|
item.set_child(child)
|
||||||
|
|
||||||
|
|
||||||
|
def _on_listview_bind(self,factory,item):
|
||||||
|
child = item.get_child()
|
||||||
|
data = item.get_item()
|
||||||
|
|
||||||
|
child.name_label.set_markup("<span size='large' weight='bold'>{}</span>".format(
|
||||||
|
GLib.markup_escape_text(data.name)))
|
||||||
|
child.catalogitemid_label.set_text(data.catalog_item_id)
|
||||||
|
child.installdir_label.set_text(data.installdir)
|
||||||
|
|
||||||
|
if hasattr(child.new_button,'_signal_clicked_connector'):
|
||||||
|
child.new_button.disconnect(child.new_button._signal_clicked_connector)
|
||||||
|
child.new_button._signal_clicked_connector = child.new_button.connect('clicked',
|
||||||
|
self._on_listview_new_button_clicked,
|
||||||
|
data)
|
||||||
|
|
||||||
|
if hasattr(child.ignore_button,'_signal_clicked_connector'):
|
||||||
|
child.ignore_button.disconnect(child.ignore_button._signal_clicked_connector)
|
||||||
|
child.ignore_button._signal_clicked_connector = child.ignore_button.connect('clicked',
|
||||||
|
self._on_listview_ignore_button_clicked,
|
||||||
|
data)
|
||||||
|
|
||||||
|
if hasattr(child.lookup_button,'_signal_clicked_connector'):
|
||||||
|
child.lookup_button.disconnect(child.lookup_button._signal_clicked_connector)
|
||||||
|
child.lookup_button._signal_clicked_connector = child.lookup_button.connect('clicked',
|
||||||
|
self._on_listview_lookup_button_clicked,
|
||||||
|
data)
|
||||||
|
child.lookup_button.set_sensitive(False)
|
||||||
|
|
||||||
|
if hasattr(child.online_button,'_signal_clicked_connector'):
|
||||||
|
child.online_button.disconnect(child.online_button._signal_clicked_connector)
|
||||||
|
child.online_button._signal_clicked_connector = child.online_button.connect('clicked',
|
||||||
|
self._on_listview_online_button_clicked,
|
||||||
|
data)
|
||||||
|
child.online_button.set_sensitive(False)
|
||||||
|
|
||||||
|
def _on_game_dialog_response(self,dialog,response,info:EpicGameInfo):
|
||||||
|
if response == Gtk.ResponseType.APPLY:
|
||||||
|
for i in range(self.__liststore.get_n_items()):
|
||||||
|
item = self.__liststore.get_item(i)
|
||||||
|
if item.catalog_item_id == info.catalog_item_id:
|
||||||
|
self.__liststore.remove(i)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def _on_listview_new_button_clicked(self,button:Gtk.Button,info:EpicGameInfo):
|
||||||
|
game = Game("",info.name,"")
|
||||||
|
if PLATFORM_WINDOWS:
|
||||||
|
windows = EpicWindowsData("","",installdir=info.installdir)
|
||||||
|
else:
|
||||||
|
windows = None
|
||||||
|
|
||||||
|
game.epic = EpicGameData(catalog_item_id=info.catalog_item_id,
|
||||||
|
windows=windows)
|
||||||
|
|
||||||
|
dialog = GameDialog(parent=self,game=game)
|
||||||
|
dialog.connect_after('response',self._on_dialog_reponse,info)
|
||||||
|
dialog.present()
|
||||||
|
|
||||||
|
|
||||||
|
def _on_ignore_dialog_response(self,dialog,response,info:EpicGameInfo):
|
||||||
|
if response == Gtk.ResponseType.YES:
|
||||||
|
epic = Epic()
|
||||||
|
epic.add_ignored_app(EpicIgnoredApp(info.catalog_item_id,
|
||||||
|
info.name,
|
||||||
|
dialog.reason_entry.get_text()))
|
||||||
|
for i in range(self.__liststore.get_n_items()):
|
||||||
|
item = self.__liststore.get_item()
|
||||||
|
if item.catalog_item_id == info.catalog_item_id:
|
||||||
|
self.__liststore.remove(i)
|
||||||
|
break
|
||||||
|
|
||||||
|
dialog.hide()
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
def _on_listview_ignore_button_clicked(self,button:Gtk.Button,info:EpicGameInfo):
|
||||||
|
dialog = Gtk.MessageDialog(transient_for=self,
|
||||||
|
text=_("Do you really won to add the game <i>{game}</i> to the ignore list?").format(
|
||||||
|
game=GLib.markup_escape_text(info.name)),
|
||||||
|
use_markup=True,
|
||||||
|
secondary_text=_("Please enter a reason below."),
|
||||||
|
secondary_use_markup=True,
|
||||||
|
buttons=Gtk.ButtonsType.YES_NO,
|
||||||
|
modal=False)
|
||||||
|
dialog.reason_entry = Gtk.Entry()
|
||||||
|
dialog.reason_entry.set_hexpand(True)
|
||||||
|
dialog.get_content_area().append(dialog.reason_entry)
|
||||||
|
dialog.connect('response',self._on_ignore_dialog_response,info)
|
||||||
|
dialog.present()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _on_listview_lookup_button_clicked(self,button:Gtk.Button,info:EpicGameInfo):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _on_listview_online_button_clicked(self,button:Gtk.Button,info:EpicGameInfo):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_response(self,response):
|
||||||
|
self.hide()
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
@ -755,9 +755,9 @@ class GameDialog(Gtk.Dialog):
|
|||||||
page = Gtk.Box.new(Gtk.Orientation.VERTICAL,2)
|
page = Gtk.Box.new(Gtk.Orientation.VERTICAL,2)
|
||||||
grid = Gtk.Grid()
|
grid = Gtk.Grid()
|
||||||
|
|
||||||
label = self.__create_label(_("AppName:"))
|
label = self.__create_label(_("CatalogIemID:"))
|
||||||
page.appname_entry = Gtk.Entry()
|
page.catalogitemid_entry = Gtk.Entry()
|
||||||
page.appname_entry.set_hexpand(True)
|
page.catalogitemid_entry.set_hexpand(True)
|
||||||
grid.attach(label,0,0,1,1)
|
grid.attach(label,0,0,1,1)
|
||||||
grid.attach(page.appname_entry,1,0,1,1)
|
grid.attach(page.appname_entry,1,0,1,1)
|
||||||
page.append(grid)
|
page.append(grid)
|
||||||
@ -1015,9 +1015,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
else "")
|
else "")
|
||||||
|
|
||||||
# Epic Games
|
# Epic Games
|
||||||
set_game_widget_data(self.__epic.windows,self.__game.epic.windows if self.has_game and self.__game.epic else None)
|
set_game_widget_data(self.__epic.windows,self.__game.epic.windows
|
||||||
|
if self.has_game and self.__game.epic else None)
|
||||||
|
|
||||||
self.__epic.appname_entry.set_text(self.__game.epic.appname if self.has_game and self.__game.epic else "")
|
self.__epic.catalogitemid_entry.set_text(self.__game.epic.catalog_item_id
|
||||||
|
if self.has_game and self.__game.epic else "")
|
||||||
self.__epic.windows.installdir_entry.set_text(self.__game.epic.windows.installdir
|
self.__epic.windows.installdir_entry.set_text(self.__game.epic.windows.installdir
|
||||||
if self.has_game
|
if self.has_game
|
||||||
and self.__game.epic
|
and self.__game.epic
|
||||||
@ -1254,9 +1256,9 @@ class GameDialog(Gtk.Dialog):
|
|||||||
data = get_epic_data(self.__epic.windows)
|
data = get_epic_data(self.__epic.windows)
|
||||||
|
|
||||||
if self.__game.epic:
|
if self.__game.epic:
|
||||||
self.__game.epic.appname = self.__epic.appname_entry.get_text()
|
self.__game.epic.catalog_item_id = self.__epic.catalogitemid_entry.get_text()
|
||||||
else:
|
else:
|
||||||
self.__game.epic = EpicGameData(appname=self.__epic.appname_entry.get_text())
|
self.__game.epic = EpicGameData(appname=self.__epic.catalogitemid_entry.get_text())
|
||||||
|
|
||||||
if self.__game.epic.windows:
|
if self.__game.epic.windows:
|
||||||
self.__game.epic.windows.savegame_root = data['sgroot']
|
self.__game.epic.windows.savegame_root = data['sgroot']
|
||||||
|
|||||||
@ -238,7 +238,7 @@ class SteamGameLookupDialog(GameSearchDialog):
|
|||||||
def do_prepare_game(self, game):
|
def do_prepare_game(self, game):
|
||||||
game = super().do_prepare_game(game)
|
game = super().do_prepare_game(game)
|
||||||
if game.steam:
|
if game.steam:
|
||||||
if not game.steam.appid != self.steam_app.appid:
|
if not game.steam.appid != self.steam_app.appid and game.steam_appid >= 0:
|
||||||
raise ValueError("Steam appid error")
|
raise ValueError("Steam appid error")
|
||||||
|
|
||||||
if PLATFORM_WINDOWS:
|
if PLATFORM_WINDOWS:
|
||||||
@ -494,6 +494,9 @@ class SteamNoNewAppsDialog(Gtk.MessageDialog):
|
|||||||
self.hide()
|
self.hide()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
### SteamIgnoreApps ###########################################################
|
||||||
|
|
||||||
class SteamNoIgnoredAppsDialog(Gtk.MessageDialog):
|
class SteamNoIgnoredAppsDialog(Gtk.MessageDialog):
|
||||||
def __init__(self,parent:Gtk.Window|None=None):
|
def __init__(self,parent:Gtk.Window|None=None):
|
||||||
Gtk.MessageDialog.__init__(self,buttons=Gtk.ButtonsType.OK)
|
Gtk.MessageDialog.__init__(self,buttons=Gtk.ButtonsType.OK)
|
||||||
@ -506,7 +509,8 @@ class SteamNoIgnoredAppsDialog(Gtk.MessageDialog):
|
|||||||
def do_response(self,response):
|
def do_response(self,response):
|
||||||
self.hide()
|
self.hide()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
class SteamIgnoreAppsSorter(Gtk.Sorter):
|
class SteamIgnoreAppsSorter(Gtk.Sorter):
|
||||||
def do_compare(self,item1:IgnoreSteamApp,item2:IgnoreSteamApp):
|
def do_compare(self,item1:IgnoreSteamApp,item2:IgnoreSteamApp):
|
||||||
s1 = item1.name.lower()
|
s1 = item1.name.lower()
|
||||||
|
|||||||
@ -350,7 +350,7 @@ class Steam(GObject):
|
|||||||
new_apps = []
|
new_apps = []
|
||||||
for lib in self.libraries:
|
for lib in self.libraries:
|
||||||
for app in lib.steam_apps:
|
for app in lib.steam_apps:
|
||||||
if not app.appid in GameManager.get_global().steam_games and not app.appid in self.ignore_apps:
|
if not GameManager.get_global().has_steam_game(app.appid) and not app.appid in self.ignore_apps:
|
||||||
new_apps.append(app)
|
new_apps.append(app)
|
||||||
return sorted(new_apps)
|
return sorted(new_apps)
|
||||||
|
|
||||||
|
|||||||
@ -17,15 +17,29 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.platform.lower() == 'win32':
|
def _platform_is_linux():
|
||||||
PLATFORM_WINDOWS=True
|
if sys.platform == 'linux':
|
||||||
else:
|
return True
|
||||||
PLATFORM_WINDOWS=False
|
for i in ('freebsd','netbsd','openbsd','dragonfly'):
|
||||||
|
if sys.platform.startswith(i):
|
||||||
if sys.platform.lower() in ['linux','freebsd','netbsd','openbsd','dragonfly','macos','cygwin']:
|
return True
|
||||||
PLATFORM_UNIX = True
|
return False
|
||||||
else:
|
|
||||||
PLATFORM_UNIX = False
|
def _platform_is_unix():
|
||||||
|
if sys.platform in ('linux','darwin','aix'):
|
||||||
|
return True
|
||||||
|
for i in ('freebsd','netbsd','openbsd','dragonfly'):
|
||||||
|
if sys.platform.startswith(i):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
PLATFORM_WINDOWS = (sys.platform == 'win32')
|
||||||
|
PLATFORM_LINUX = _platform_is_linux()
|
||||||
|
PLATFORM_MACOS = (sys.platform == 'darwin')
|
||||||
|
PLATFORM_UNIX = _platform_is_unix()
|
||||||
|
|
||||||
|
del _platform_is_unix
|
||||||
|
del _platform_is_linux
|
||||||
|
|
||||||
def sanitize_windows_path(path:str)->str:
|
def sanitize_windows_path(path:str)->str:
|
||||||
return path.replace('/','\\')
|
return path.replace('/','\\')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user