mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
2025.03.16 01:08:36 (desktop)
This commit is contained in:
parent
c866419b30
commit
f23aa75776
@ -129,7 +129,7 @@ class Epic(GObject):
|
||||
self.__ignored_apps[app.catalog_item_id] = app
|
||||
self.__write_ignore_file()
|
||||
|
||||
def remove_ignored_apps(self,app:str|EpicIgnoredApp):
|
||||
def remove_ignored_app(self,app:str|EpicIgnoredApp):
|
||||
if isinstance(app,str):
|
||||
item_id = app
|
||||
elif isinstance(app,EpicIgnoredApp):
|
||||
|
||||
@ -50,7 +50,11 @@ from ..steam import Steam
|
||||
from ..epic import Epic
|
||||
from ._epic import (
|
||||
EpicNewAppsDialog,
|
||||
EpicNoIgnoredAppsDialog,
|
||||
EpicNoNewAppsDialog,
|
||||
EpicIgnoredAppsDialog,
|
||||
)
|
||||
|
||||
from ._backupdialog import BackupSingleDialog,BackupManyDialog
|
||||
from ..archiver import ArchiverManager
|
||||
from ._dialogs import (
|
||||
@ -416,18 +420,11 @@ class GameView(Gtk.Box):
|
||||
def _on_new_epic_games_button_clicked(self,button):
|
||||
epic = Epic()
|
||||
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())
|
||||
else:
|
||||
dialog = EpicNewAppsDialog(self.get_root())
|
||||
dialog.connect_after('response',self._on_new_apps_dialog_response)
|
||||
|
||||
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):
|
||||
@ -449,10 +446,18 @@ class GameView(Gtk.Box):
|
||||
choices.append(item.name)
|
||||
item.fuzzy_match = 0.0
|
||||
|
||||
result = rapidfuzz.process.extract(query=search_name,
|
||||
if settings.search_case_sensitive:
|
||||
processor=None
|
||||
query=search_name
|
||||
else:
|
||||
processor=lambda s: s.lower()
|
||||
query=search_name.lower()
|
||||
|
||||
result = rapidfuzz.process.extract(query=query,
|
||||
choices=choices,
|
||||
limit=settings.search_max_results,
|
||||
scorer=rapidfuzz.fuzz.WRatio)
|
||||
scorer=rapidfuzz.fuzz.WRatio,
|
||||
processor=processor)
|
||||
|
||||
|
||||
for name,match,pos in result:
|
||||
@ -1572,17 +1577,23 @@ class Application(Gtk.Application):
|
||||
def _on_action_epic_new_apps(self,action,param):
|
||||
epic = Epic()
|
||||
if not epic.find_new_apps():
|
||||
### TODO #####################################
|
||||
return
|
||||
dialog = EpicNoNewAppsDialog(self.appwindow)
|
||||
else:
|
||||
dialog = EpicNewAppsDialog(self.appwindow)
|
||||
dialog.connect_after("response",lambda d,r: self.appwindow.refresh())
|
||||
dialog.connect_after('response',lambda d,r: self.appwindow.refresh())
|
||||
|
||||
dialog.present()
|
||||
|
||||
def _on_action_epic_manage_ignore(self,action,param):
|
||||
### TODO ##########################################
|
||||
pass
|
||||
epic = Epic()
|
||||
if not epic.ignored_apps:
|
||||
dialog = EpicNoIgnoredAppsDialog(self.appwindow)
|
||||
else:
|
||||
dialog = EpicIgnoredAppsDialog(self.appwindow)
|
||||
dialog.connect_after('response',lambda d,r: self.appwindow.refresh())
|
||||
|
||||
dialog.present()
|
||||
|
||||
|
||||
def new_settings_dialog(self)->SettingsDialog:
|
||||
"""
|
||||
|
||||
@ -27,6 +27,35 @@ from ..utility import PLATFORM_WINDOWS
|
||||
|
||||
from ._gamedialog import GameDialog
|
||||
|
||||
class EpicNoNewAppsDialog(Gtk.MessageDialog):
|
||||
def __init__(self,parent:Gtk.Window|None):
|
||||
Gtk.MessageDialog.__init__(self,
|
||||
transient_for=parent,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text=_("There were no new Epic-Games apps found!"),
|
||||
use_markup=False,
|
||||
modal=True)
|
||||
|
||||
def do_response(self,response):
|
||||
self.hide()
|
||||
self.destroy()
|
||||
|
||||
|
||||
class EpicNoIgnoredAppsDialog(Gtk.MessageDialog):
|
||||
def __init__(self,parent:Gtk.Window|None):
|
||||
Gtk.MessageDialog.__init__(self,
|
||||
transient_for=parent,
|
||||
buttons=Gtk.ButtonsType.OK,
|
||||
text=_("There are no ignored Epic-Games apps!"),
|
||||
use_markup=False,
|
||||
modal=True)
|
||||
|
||||
def do_response(self,response):
|
||||
self.hide()
|
||||
self.destroy()
|
||||
|
||||
### EpicLookupGamesDialog #####################################################
|
||||
|
||||
class EpicLookupGamesDialog(GameSearchDialog):
|
||||
def __init__(self,parent:Gtk.Window|None=None,info:EpicGameInfo|None=None):
|
||||
GameSearchDialog.__init__(self,parent,info.name if info else None)
|
||||
@ -272,3 +301,147 @@ class EpicNewAppsDialog(Gtk.Dialog):
|
||||
for gameinfo in epic.find_new_apps():
|
||||
self.__liststore.append(gameinfo)
|
||||
|
||||
#### EpicIgnoreAppsDialog ##########################################################
|
||||
|
||||
class EpicIgnoredAppsDialogSorter(Gtk.Sorter):
|
||||
def do_compare(self,item1:EpicIgnoredApp,item2:EpicIgnoredApp):
|
||||
name1=item1.name.lower()
|
||||
name2=item2.name.lower()
|
||||
|
||||
if name1 < name2:
|
||||
return Gtk.Ordering.SMALLER
|
||||
elif name1 > name2:
|
||||
return Gtk.Ordering.LARGER
|
||||
|
||||
return Gtk.Ordering.EQUAL
|
||||
|
||||
|
||||
class EpicIgnoredAppsDialog(Gtk.Dialog):
|
||||
def __init__(self,parent:Gtk.Window|None=None):
|
||||
Gtk.Dialog.__init__(self,transient_for=parent)
|
||||
self.set_default_size(640,480)
|
||||
|
||||
epic = Epic()
|
||||
self.__liststore = Gio.ListStore.new(EpicIgnoredApp)
|
||||
for ignored in epic.ignored_apps.values():
|
||||
self.__liststore.append(ignored)
|
||||
|
||||
sort_model = Gtk.SortListModel(model=self.__liststore,sorter=EpicIgnoredAppsDialogSorter())
|
||||
selection = Gtk.SingleSelection(model=sort_model)
|
||||
factory = Gtk.SignalListItemFactory()
|
||||
factory.connect('setup',self._on_listview_item_setup)
|
||||
factory.connect('bind',self._on_listview_item_bind)
|
||||
|
||||
self.__listview = Gtk.ListView(model=selection,
|
||||
factory=factory,
|
||||
hexpand=True,
|
||||
vexpand=True)
|
||||
|
||||
scrolled = Gtk.ScrolledWindow(hexpand=True,
|
||||
vexpand=True)
|
||||
scrolled.set_child(self.__listview)
|
||||
self.get_content_area().append(scrolled)
|
||||
|
||||
self.add_button("Close",Gtk.ResponseType.OK)
|
||||
|
||||
def _on_listview_item_setup(self,factory,item):
|
||||
child = Gtk.Grid(hexpand=True,column_spacing=4,row_spacing=2)
|
||||
|
||||
child.name_label = Gtk.Label(use_markup=True,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,hexpand=False)
|
||||
child.catalogitemid_label = Gtk.Label(use_markup=False,xalign=0.0,hexpand=True)
|
||||
child.attach(label,0,1,1,1)
|
||||
child.attach(child.catalogitemid_label,1,1,1,1)
|
||||
|
||||
label = Gtk.Label(label=_("Reason:"),use_markup=False,xalign=0.0,hexpand=False)
|
||||
child.reason_label = Gtk.Label(use_markup=True,xalign=0.0,hexpand=True)
|
||||
child.attach(label,0,2,1,1)
|
||||
child.attach(child.reason_label,1,2,1,1)
|
||||
|
||||
action_grid = Gtk.Grid(column_spacing=2,row_spacing=2)
|
||||
|
||||
icon = Gtk.Image.new_from_icon_name("document-new-symbolic")
|
||||
icon.set_pixel_size(16)
|
||||
child.new_game_button = Gtk.Button()
|
||||
child.new_game_button.set_child(icon)
|
||||
child.new_game_button.set_tooltip_text("Add ignored SteamApp as a new game.")
|
||||
action_grid.attach(child.new_game_button,0,0,1,1)
|
||||
|
||||
icon = Gtk.Image.new_from_icon_name("list-remove-symbolic")
|
||||
icon.set_pixel_size(16)
|
||||
child.remove_button = Gtk.Button()
|
||||
child.remove_button.set_child(icon)
|
||||
child.remove_button.set_tooltip_text("Remove ignored SteamApp from the list.")
|
||||
action_grid.attach(child.remove_button,0,1,1,1)
|
||||
|
||||
child.attach(action_grid,2,0,1,3)
|
||||
|
||||
item.set_child(child)
|
||||
|
||||
def _on_listview_item_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.reason_label.set_markup("<i>{}</i>".format(GLib.markup_escape_text(data.reason)))
|
||||
|
||||
if hasattr(child.new_game_button,"_signal_clicked_connector"):
|
||||
child.new_game_button.disconnect(child.new_game_button._signal_clicked_connector)
|
||||
child.new_game_button._signal_clicked_connector = child.new_game_button.connect('clicked',
|
||||
self._on_listitem_new_game_button_clicked,
|
||||
data)
|
||||
|
||||
if hasattr(child.remove_button,'_signal_clicked_connector'):
|
||||
child.remove_button.disconnect(child.remove_button._signal_clicked_connector)
|
||||
child.remove_button._signal_clicked_connector = child.remove_button.connect('clicked',
|
||||
self._on_listitem_remove_button_clicked,
|
||||
data)
|
||||
|
||||
|
||||
def __remove_ignored_app(self,data:EpicIgnoredApp):
|
||||
epic = Epic()
|
||||
epic.remove_ignored_app(data)
|
||||
|
||||
for i in range(self.__liststore.get_n_items()):
|
||||
item = self.__liststore.get_item(i)
|
||||
if item.catalog_item_id == data.catalog_item_id:
|
||||
self.__liststore.remove(i)
|
||||
break
|
||||
|
||||
def _on_listitem_new_game_button_clicked(self,button,data:EpicIgnoredApp):
|
||||
def on_dialog_response(self,dialog,response,data):
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
self.__remove_item(data)
|
||||
|
||||
|
||||
game = Game("",data.name,"")
|
||||
epic = Epic()
|
||||
game_info = epic.find_apps()[data.catalog_item_id]
|
||||
|
||||
if PLATFORM_WINDOWS:
|
||||
windows = EpicWindowsData("","",installdir=game_info.installdir)
|
||||
else:
|
||||
windows = None
|
||||
|
||||
game.epic = EpicGameData(data.catalog_item_id,windows)
|
||||
|
||||
parent = self.get_transient_for()
|
||||
dialog=GameDialog(parent=parent,game=game)
|
||||
dialog.connect_after('response',on_dialog_response,data)
|
||||
|
||||
self.hide()
|
||||
dialog.present()
|
||||
|
||||
|
||||
def _on_listitem_remove_button_clicked(self,button,data:EpicIgnoredApp):
|
||||
epic = Epic()
|
||||
self.__remove_ignored_app(data)
|
||||
|
||||
def do_response(self,response):
|
||||
self.hide()
|
||||
self.destroy()
|
||||
|
||||
@ -514,10 +514,10 @@ class GameDialog(Gtk.Dialog):
|
||||
grid.attach(page.installdir_entry,1,2,1,1)
|
||||
vbox.append(grid)
|
||||
|
||||
page.filematch = self.__create_filematch_widget(_('Match Files'))
|
||||
page.filematch = self.__create_file_matcher()
|
||||
vbox.append(page.filematch)
|
||||
|
||||
page.ignorematch = self.__create_filematch_widget(_('Ignore Files'))
|
||||
page.ignorematch = self.__create_ignore_matcher()
|
||||
vbox.append(page.ignorematch)
|
||||
|
||||
page.lookup_regkeys = self.__create_registry_key_widget(_("Lookup Registry keys"))
|
||||
@ -564,10 +564,10 @@ class GameDialog(Gtk.Dialog):
|
||||
grid.attach(page.binary_entry,1,2,1,1)
|
||||
vbox.append(grid)
|
||||
|
||||
page.filematch = self.__create_filematch_widget('Match Files')
|
||||
page.filematch = self.__create_file_matcher()
|
||||
vbox.append(page.filematch)
|
||||
|
||||
page.ignorematch = self.__create_filematch_widget('Ignore Files')
|
||||
page.ignorematch = self.__create_ignore_matcher()
|
||||
vbox.append(page.ignorematch)
|
||||
|
||||
page.variables = self.__create_variables_widget()
|
||||
@ -607,10 +607,10 @@ class GameDialog(Gtk.Dialog):
|
||||
grid.attach(page.binary_entry,1,2,1,1)
|
||||
vbox.append(grid)
|
||||
|
||||
page.filematch = self.__create_filematch_widget('Match Files')
|
||||
page.filematch = self.__create_file_matcher()
|
||||
vbox.append(page.filematch)
|
||||
|
||||
page.ignorematch = self.__create_filematch_widget('Ignore Files')
|
||||
page.ignorematch = self.__create_ignore_matcher()
|
||||
vbox.append(page.ignorematch)
|
||||
|
||||
page.variables = self.__create_variables_widget()
|
||||
@ -659,10 +659,10 @@ class GameDialog(Gtk.Dialog):
|
||||
|
||||
nbvbox.append(nbgrid)
|
||||
|
||||
nbpage.filematch = self.__create_filematch_widget('Match Files')
|
||||
nbpage.filematch = self.__create_file_matcher()
|
||||
nbvbox.append(nbpage.filematch)
|
||||
|
||||
nbpage.ignorematch = self.__create_filematch_widget('Ignore Files')
|
||||
nbpage.ignorematch = self.__create_ignore_matcher()
|
||||
nbvbox.append(nbpage.ignorematch)
|
||||
|
||||
nbpage.variables = self.__create_variables_widget()
|
||||
@ -741,10 +741,10 @@ class GameDialog(Gtk.Dialog):
|
||||
|
||||
nbvbox.append(nbgrid)
|
||||
|
||||
nbpage.filematch = self.__create_filematch_widget('Match Files')
|
||||
nbpage.filematch = self.__create_file_matcher()
|
||||
nbvbox.append(nbpage.filematch)
|
||||
|
||||
nbpage.ignorematch = self.__create_filematch_widget('Ignore Files')
|
||||
nbpage.ignorematch = self.__create_ignore_matcher()
|
||||
nbvbox.append(nbpage.ignorematch)
|
||||
|
||||
nbpage.variables = self.__create_variables_widget()
|
||||
@ -786,7 +786,10 @@ class GameDialog(Gtk.Dialog):
|
||||
widget.set_margin_bottom(margin)
|
||||
|
||||
def __create_variables_widget(self):
|
||||
widget = Gtk.Frame.new("Variables")
|
||||
widget = Gtk.Frame()
|
||||
widget.set_label_widget(
|
||||
Gtk.Label(label="<span weight='bold'>{}</span>".format(GLib.markup_escape_text(_('Variables'))),
|
||||
use_markup=True))
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL,0)
|
||||
|
||||
model = Gio.ListStore.new(GameVariableData)
|
||||
@ -824,11 +827,11 @@ class GameDialog(Gtk.Dialog):
|
||||
widget.columnview)
|
||||
widget.actions.pack_start(widget.remove_button)
|
||||
|
||||
name_column = Gtk.ColumnViewColumn.new("Name",self.__variable_name_factory)
|
||||
name_column = Gtk.ColumnViewColumn.new(_("Name"),self.__variable_name_factory)
|
||||
name_column.set_expand(True)
|
||||
widget.columnview.append_column(name_column)
|
||||
|
||||
value_column = Gtk.ColumnViewColumn.new("Value",self.__variable_value_factory)
|
||||
value_column = Gtk.ColumnViewColumn.new(_("Value"),self.__variable_value_factory)
|
||||
value_column.set_expand(True)
|
||||
widget.columnview.append_column(value_column)
|
||||
|
||||
@ -854,7 +857,10 @@ class GameDialog(Gtk.Dialog):
|
||||
return dropdown
|
||||
|
||||
def __create_filematch_widget(self,title:str):
|
||||
widget = Gtk.Frame.new(title)
|
||||
widget = Gtk.Frame()
|
||||
widget.set_label_widget(
|
||||
Gtk.Label(label="<span weight='bold'>{}</span>".format(GLib.markup_escape_text(title)),
|
||||
use_markup=True))
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL,2)
|
||||
|
||||
widget.actions = Gtk.ActionBar()
|
||||
@ -891,8 +897,17 @@ class GameDialog(Gtk.Dialog):
|
||||
|
||||
return widget
|
||||
|
||||
def __create_file_matcher(self):
|
||||
return self.__create_filematch_widget(_("Match Files"))
|
||||
|
||||
def __create_ignore_matcher(self):
|
||||
return self.__create_filematch_widget(_("Match Files to ignore"))
|
||||
|
||||
def __create_registry_key_widget(self,title):
|
||||
widget = Gtk.Frame.new(title)
|
||||
widget = Gtk.Frame()
|
||||
widget.set_label_widget(
|
||||
Gtk.Label(label="<span weight='bold'>{}</span>".format(GLib.markup_escape_text(title)),
|
||||
use_markup=True))
|
||||
vbox=Gtk.Box.new(Gtk.Orientation.VERTICAL,2)
|
||||
|
||||
widget.actions = Gtk.ActionBar()
|
||||
|
||||
@ -225,19 +225,29 @@ class SettingsDialog(Gtk.Dialog):
|
||||
search_frame = self.create_frame('Search Settings')
|
||||
search_grid = self.create_grid()
|
||||
|
||||
label = self.create_label("Case sensitive search:")
|
||||
page.search_casesensitive_switch = Gtk.Switch()
|
||||
page.search_casesensitive_switch.set_active(settings.search_case_sensitive)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL,0)
|
||||
hbox.append(Gtk.Label(hexpand=True))
|
||||
hbox.append(page.search_casesensitive_switch)
|
||||
hbox.set_hexpand(True)
|
||||
search_grid.attach(label,0,0,1,1)
|
||||
search_grid.attach(hbox,1,0,1,1)
|
||||
|
||||
label = self.create_label("Minimum Characters:")
|
||||
page.search_minchars_spinbutton = Gtk.SpinButton.new_with_range(1,32,1)
|
||||
page.search_minchars_spinbutton.set_value(settings.search_min_chars)
|
||||
page.search_minchars_spinbutton.set_hexpand(True)
|
||||
search_grid.attach(label,0,0,1,1)
|
||||
search_grid.attach(page.search_minchars_spinbutton,1,0,1,1)
|
||||
search_grid.attach(label,0,1,1,1)
|
||||
search_grid.attach(page.search_minchars_spinbutton,1,1,1,1)
|
||||
|
||||
label = self.create_label("Maximum Results:")
|
||||
page.search_maxresults_spinbutton = Gtk.SpinButton.new_with_range(1,100,1)
|
||||
page.search_maxresults_spinbutton.set_value(settings.search_max_results)
|
||||
page.search_maxresults_spinbutton.set_hexpand(True)
|
||||
search_grid.attach(label,0,1,1,1)
|
||||
search_grid.attach(page.search_maxresults_spinbutton,1,1,1,1)
|
||||
search_grid.attach(label,0,2,1,1)
|
||||
search_grid.attach(page.search_maxresults_spinbutton,1,2,1,1)
|
||||
|
||||
search_frame.set_child(search_grid)
|
||||
vbox.append(search_frame)
|
||||
@ -487,6 +497,7 @@ class SettingsDialog(Gtk.Dialog):
|
||||
settings.archiver = self.general_page.archiver_dropdown.get_selected_item().key
|
||||
settings.gui_autoclose_backup_dialog = self.general_page.gui_autoclose_backup_dialog_switch.get_active()
|
||||
settings.gui_autoclose_restore_dialog = self.general_page.gui_autoclose_restore_dialog_switch.get_active()
|
||||
settings.search_case_sensitive = self.general_page.search_casesensitive_switch.get_active()
|
||||
settings.search_min_chars = self.general_page.search_minchars_spinbutton.get_value_as_int()
|
||||
settings.search_max_results = self.general_page.search_maxresults_spinbutton.get_value_as_int()
|
||||
settings.zipfile_compression = self.archiver_page.zf_compressor_dropdown.get_selected_item().compressor
|
||||
|
||||
@ -360,6 +360,14 @@ class Settings(GObject.GObject):
|
||||
def search_min_chars(self,min_chars:int):
|
||||
self.set_integer('search','minChars',min_chars)
|
||||
|
||||
@GObject.Property(type=bool,default=False)
|
||||
def search_case_sensitive(self)->bool:
|
||||
return self.get_boolean('search','caseSensitive',False)
|
||||
|
||||
@search_case_sensitive.setter
|
||||
def search_case_sensitive(self,case_sensitive):
|
||||
self.set_boolean('search','caseSensitive',bool(case_sensitive))
|
||||
|
||||
@GObject.Property(type=bool,default=False)
|
||||
def gui_autoclose_backup_dialog(self)->bool:
|
||||
return self.get_boolean('gui','autocloseBackupDialog',False)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user