mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
2025.02.17 02:21:41 (desktop)
This commit is contained in:
parent
35d8b71751
commit
0abb7db5c3
@ -1,24 +0,0 @@
|
||||
[build-system]
|
||||
builbackend = 'setuptools.build_meta'
|
||||
requires = ['setuptools >= 61.0']
|
||||
|
||||
[project]
|
||||
dynamic = ["version"]
|
||||
name = 'sgbackup'
|
||||
version = '0.0.0'
|
||||
requires_python = '>= 3.11'
|
||||
description = 'Savegame Backup Tool'
|
||||
readme = 'README.md'
|
||||
license = {file = 'LICENSE'}
|
||||
authors = [
|
||||
{name = 'Christian Moser', email = 'christian@mydevel.at'},
|
||||
]
|
||||
dependencies = ['gi','yaml']
|
||||
|
||||
[project.scripts]
|
||||
sgbackup = 'sgbackup:cli_main'
|
||||
csgbackup = 'sgbackup:curses_main'
|
||||
|
||||
[project.gui-scripts]
|
||||
gsgbackup = 'sgbackup:gui_main'
|
||||
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
rapidfuzz
|
||||
|
||||
38
setup.py
Normal file
38
setup.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
import subprocess
|
||||
import bz2
|
||||
|
||||
PACKAGE_ROOT=os.path.dirname(__file__)
|
||||
|
||||
sys.path.insert(0,PACKAGE_ROOT)
|
||||
import sgbackup
|
||||
|
||||
setup(
|
||||
name='sgbackup',
|
||||
version=sgbackup.__version__
|
||||
description='A backup tool for savegames.',
|
||||
author="Christian Moser",
|
||||
author_email="christian@cmoser.eu",
|
||||
packages=[
|
||||
'sgbackup',
|
||||
'sgbackup.archivers',
|
||||
'sgbackup.commands',
|
||||
'sgbackup.curses',
|
||||
'sgbackup.help',
|
||||
'sgbackup.gui',
|
||||
],
|
||||
package_data={
|
||||
'sgbackup':[
|
||||
'icons/sgbackup.ico',
|
||||
'icons/hicolor/symbolic/*/*.svg'
|
||||
],
|
||||
'sgbackup.gui': [
|
||||
'*.ui'
|
||||
],
|
||||
},
|
||||
platforms=['win32','linux']
|
||||
)
|
||||
@ -21,7 +21,7 @@ from . import _import_gtk
|
||||
__version__ = "0.0.1"
|
||||
from .settings import settings
|
||||
from . import _logging
|
||||
from .main import cli_main,curses_main,gui_main
|
||||
from .main import cli_main,gui_main
|
||||
from . import game
|
||||
from .command import Command
|
||||
from . import commands
|
||||
@ -31,7 +31,7 @@ __ALL__ = [
|
||||
"settings"
|
||||
"cli_main",
|
||||
"gui_main",
|
||||
"curses_main",
|
||||
#"curses_main",
|
||||
'game',
|
||||
"Command",
|
||||
"commands",
|
||||
|
||||
@ -164,9 +164,6 @@ class GameView(Gtk.Box):
|
||||
pass
|
||||
self.__liststore.append(g)
|
||||
self.__sort_model = Gtk.SortListModel.new(self._liststore,self.__name_sorter)
|
||||
self.__sort_model
|
||||
self.__action_dialog = None
|
||||
self.__backup_dialog = None
|
||||
|
||||
factory_icon = Gtk.SignalListItemFactory.new()
|
||||
factory_icon.connect('setup',self._on_icon_column_setup)
|
||||
@ -319,12 +316,14 @@ class GameView(Gtk.Box):
|
||||
def _on_key_column_setup(self,factory,item):
|
||||
label = Gtk.Label()
|
||||
label.set_xalign(0.0)
|
||||
label.set_use_markup(True)
|
||||
item.set_child(label)
|
||||
|
||||
def _on_key_column_bind(self,factory,item):
|
||||
label = item.get_child()
|
||||
game = item.get_item()
|
||||
game.bind_property('key',label,'label',BindingFlags.SYNC_CREATE)
|
||||
game.bind_property('key',label,'label',BindingFlags.SYNC_CREATE,
|
||||
lambda _binding,s: '<span size="large">{}</span>'.format(GLib.markup_escape_text(s)))
|
||||
|
||||
def _on_name_column_setup(self,factory,item):
|
||||
label = Gtk.Label()
|
||||
@ -424,8 +423,13 @@ class GameView(Gtk.Box):
|
||||
game = item.get_item()
|
||||
archiver_manager = ArchiverManager.get_global()
|
||||
|
||||
if not hasattr(child.backup_button,'_signal_clicked_connection'):
|
||||
child.backup_button._signal_clicked_connection = child.backup_button.connect('clicked',self._on_columnview_backup_button_clicked,item)
|
||||
# check if we are already connected.
|
||||
# if we dont check we might have more than one dialog open or execute backups more than once
|
||||
# due to Gtk4 reusing the widgets. When selecting a row in the columnview this method is called.
|
||||
if hasattr(child.backup_button,'_signal_clicked_connection'):
|
||||
child.backup_button.disconnect(child.backup_button._signal_clicked_connection)
|
||||
child.backup_button._signal_clicked_connection = child.backup_button.connect('clicked',self._on_columnview_backup_button_clicked,item)
|
||||
|
||||
if not hasattr(child.backup_button,'_property_backup_in_progress_binding'):
|
||||
child.backup_button._property_backup_in_progress_binding = archiver_manager.bind_property('backup-in-progress',
|
||||
child.backup_button,
|
||||
@ -433,8 +437,9 @@ class GameView(Gtk.Box):
|
||||
BindingFlags.SYNC_CREATE,
|
||||
lambda binding,x: False if x else True)
|
||||
|
||||
if not hasattr(child.edit_button,'_signal_clicked_connection'):
|
||||
child.edit_button._signal_clicked_connection = child.edit_button.connect('clicked',self._on_columnview_edit_button_clicked,item)
|
||||
if hasattr(child.edit_button,'_signal_clicked_connection'):
|
||||
child.edit_button.disconnect(child.edit_button._signal_clicked_connection)
|
||||
child.edit_button._signal_clicked_connection = child.edit_button.connect('clicked',self._on_columnview_edit_button_clicked,item)
|
||||
|
||||
if not hasattr(child.edit_button,'_property_backup_in_progress_binding'):
|
||||
child.edit_button._property_backup_in_progress_binding = archiver_manager.bind_property('backup-in-progress',
|
||||
@ -443,8 +448,10 @@ class GameView(Gtk.Box):
|
||||
BindingFlags.SYNC_CREATE,
|
||||
lambda binding,x: False if x else True)
|
||||
|
||||
if not hasattr(child.remove_button,'_signal_clicked_connection'):
|
||||
child.remove_button._signal_clicked_connection = child.remove_button.connect('clicked',self._on_columnview_remove_button_clicked,item)
|
||||
if hasattr(child.remove_button,'_signal_clicked_connection'):
|
||||
child.remove_button.disconnect(child.remove_button._signal_clicked_connection)
|
||||
child.remove_button._signal_clicked_connection = child.remove_button.connect('clicked',self._on_columnview_remove_button_clicked,item)
|
||||
|
||||
if not hasattr(child.remove_button,'_property_backup_in_progress_binding'):
|
||||
child.remove_button._property_backup_in_progress_binding = archiver_manager.bind_property('backup-in-progress',
|
||||
child.remove_button,'sensitive',
|
||||
@ -458,30 +465,22 @@ class GameView(Gtk.Box):
|
||||
child.backup_button.set_sensitive(False)
|
||||
|
||||
def _on_columnview_backup_button_clicked(self,button,item):
|
||||
def on_dialog_response(dialog,response):
|
||||
self.__backup_dialog = None
|
||||
|
||||
if self.__backup_dialog is None:
|
||||
game = item.get_item()
|
||||
self.__backup_dialog = BackupSingleDialog(self.get_root(),game)
|
||||
self.__backup_dialog.connect('response',on_dialog_response)
|
||||
self.__backup_dialog.run()
|
||||
game = item.get_item()
|
||||
dialog = BackupSingleDialog(self.get_root(),game)
|
||||
dialog.connect('response',on_dialog_response)
|
||||
dialog.run()
|
||||
|
||||
def _on_columnview_edit_button_clicked(self,button,item):
|
||||
def on_dialog_response(dialog,response):
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
self.refresh()
|
||||
self.__action_dialog = None
|
||||
|
||||
if self.__action_dialog is None:
|
||||
game = item.get_item()
|
||||
game = item.get_item()
|
||||
|
||||
self.__action_dialog = GameDialog(self.get_root(),game)
|
||||
self.__action_dialog.set_modal(False)
|
||||
self.__action_dialog.connect('response',on_dialog_response)
|
||||
self.__action_dialog.present()
|
||||
else:
|
||||
self.__action_dialog.present()
|
||||
dialog = GameDialog(self.get_root(),game)
|
||||
dialog.set_modal(False)
|
||||
dialog.connect('response',on_dialog_response)
|
||||
dialog.present()
|
||||
|
||||
|
||||
def _on_columnview_remove_button_clicked(self,button,item):
|
||||
@ -497,21 +496,17 @@ class GameView(Gtk.Box):
|
||||
|
||||
dialog.hide()
|
||||
dialog.destroy()
|
||||
self.__action_dialog = None
|
||||
|
||||
game = item.get_item()
|
||||
if self.__action_dialog is None:
|
||||
self.__action_dialog = Gtk.MessageDialog(buttons=Gtk.ButtonsType.YES_NO,
|
||||
text="Do you really want to remove the game <span weight='bold'>{game}</span>?".format(
|
||||
game=game.name),
|
||||
use_markup=True,
|
||||
secondary_text="Removing games cannot be undone!!!")
|
||||
self.__action_dialog.set_transient_for(self.get_root())
|
||||
self.__action_dialog.set_modal(False)
|
||||
self.__action_dialog.connect('response',on_dialog_response,game)
|
||||
self.__action_dialog.present()
|
||||
else:
|
||||
self.__action_dialog.present()
|
||||
dialog = Gtk.MessageDialog(buttons=Gtk.ButtonsType.YES_NO,
|
||||
text="Do you really want to remove the game <span weight='bold'>{game}</span>?".format(
|
||||
game=game.name),
|
||||
use_markup=True,
|
||||
secondary_text="Removing games cannot be undone!!!")
|
||||
dialog.set_transient_for(self.get_root())
|
||||
dialog.set_modal(False)
|
||||
dialog.connect('response',on_dialog_response,game)
|
||||
dialog.present()
|
||||
|
||||
# GameView class
|
||||
|
||||
|
||||
@ -100,7 +100,10 @@ class RegistryKeyData(GObject):
|
||||
"""
|
||||
GObject.__init__(self)
|
||||
if not regkey:
|
||||
self.__regkey = ""
|
||||
self.regkey = ""
|
||||
else:
|
||||
self.regkey = regkey
|
||||
|
||||
|
||||
@Property(type=str)
|
||||
def regkey(self)->str:
|
||||
@ -972,12 +975,12 @@ class GameDialog(Gtk.Dialog):
|
||||
irk = []
|
||||
|
||||
for i in range(grk_model.get_n_items()):
|
||||
item = grk.model.get_item(i)
|
||||
item = grk_model.get_item(i)
|
||||
if item.regkey:
|
||||
grk.append(item.regkey)
|
||||
|
||||
for i in range(irk_model.get_n_items()):
|
||||
item = irk.model.get_item(i)
|
||||
item = irk_model.get_item(i)
|
||||
if item.regkey:
|
||||
irk.append(item.regkey)
|
||||
|
||||
@ -1255,8 +1258,8 @@ class GameDialog(Gtk.Dialog):
|
||||
label = item.get_child()
|
||||
data = item.get_item()
|
||||
label.set_text(data.regkey)
|
||||
label.bind_property('text',data,'regkey',GObject.BindingFlags.DEFAULT)
|
||||
label.connect('changed',self._on_windows_regkey_label_changed,widget)
|
||||
label.bind_property('text',data,'regkey',BindingFlags.DEFAULT)
|
||||
label.connect('notify::editing',self._on_windows_regkey_label_notify_editing,widget)
|
||||
if not label.get_text():
|
||||
label.start_editing()
|
||||
label.grab_focus()
|
||||
@ -1316,16 +1319,15 @@ class GameDialog(Gtk.Dialog):
|
||||
def _on_windows_regkey_add_button_clicked(self,button,widget):
|
||||
widget.listview.get_model().get_model().append(RegistryKeyData())
|
||||
|
||||
def _on_windows_regkey_label_changed(self,label,widget):
|
||||
if not label.get_text():
|
||||
model = widget.listview.get_model().get_model()
|
||||
i = 0
|
||||
while i < model.get_n_items():
|
||||
item = model.get_item(i)
|
||||
if not item.regkey:
|
||||
model.remove(i)
|
||||
continue
|
||||
i += 1
|
||||
def _on_windows_regkey_label_notify_editing(self,label,state,widget):
|
||||
if not label.get_editing():
|
||||
if not label.get_text():
|
||||
model = widget.listview.get_model().get_model()
|
||||
i = 0
|
||||
for i in reversed(range(model.get_n_items())):
|
||||
item = model.get_item(i)
|
||||
if not item.regkey:
|
||||
model.remove(i)
|
||||
|
||||
def do_response(self,response):
|
||||
if (response == Gtk.ResponseType.APPLY):
|
||||
|
||||
@ -172,8 +172,17 @@ class SteamLibrariesDialog(Gtk.Dialog):
|
||||
lib = item.get_item()
|
||||
child.label.set_text(lib.directory)
|
||||
child.label.bind_property('text',lib,'directory',BindingFlags.DEFAULT)
|
||||
child.chooser_button.connect('clicked',self._on_list_chooser_button_clicked,child.label)
|
||||
child.remove_button.connect('clicked',self._on_list_remove_button_clicked,child.label)
|
||||
if hasattr(child.chooser_button,'_signal_clicked_connector'):
|
||||
child.chooser_button.disconnect(child.chooser_button._signal_clicked_connector)
|
||||
child.chooser_button._signal_clicked_connector = child.chooser_button.connect('clicked',
|
||||
self._on_list_chooser_button_clicked,
|
||||
child.label)
|
||||
|
||||
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_list_remove_button_clicked,
|
||||
child.label)
|
||||
|
||||
def do_response(self,response):
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
@ -219,6 +228,7 @@ class NewSteamAppsDialog(Gtk.Dialog):
|
||||
factory = Gtk.SignalListItemFactory()
|
||||
factory.connect('setup',self._on_listitem_setup)
|
||||
factory.connect('bind',self._on_listitem_bind)
|
||||
factory.connect('unbind',self._on_listitem_unbind)
|
||||
|
||||
self.__listview = Gtk.ListView.new(selection,factory)
|
||||
self.__listview.set_vexpand(True)
|
||||
@ -287,23 +297,32 @@ class NewSteamAppsDialog(Gtk.Dialog):
|
||||
child.name_label.set_markup("<span weight='bold' size='large'>{}</span>".format(GLib.markup_escape_text(data.name)))
|
||||
child.appid_label.set_text(str(data.appid))
|
||||
child.installdir_label.set_text(data.installdir)
|
||||
if not hasattr(child.add_app_button,'_signal_clicked_connector'):
|
||||
child.add_app_button._signal_clicked_connector = child.add_app_button.connect('clicked',self._on_add_steamapp_button_clicked,data)
|
||||
if not hasattr(child.ignore_app_button,'_signal_clicked_connector'):
|
||||
child.ignore_app_button._signal_clicked_connector = child.ignore_app_button.connect('clicked',self._on_ignore_steamapp_button_clicked,data)
|
||||
|
||||
# Check if we are already connected.
|
||||
# if we dont check we might have more than one dialog open
|
||||
# due to Gtk4 reusing the widgets.
|
||||
# When selecting a row in the columnview this method is called so we
|
||||
# need to ensure that the last binding is used to work as expected.
|
||||
if hasattr(child.add_app_button,'_signal_clicked_connector'):
|
||||
child.add_app_button.disconnect(child.add_app_button._signal_clicked_connector)
|
||||
child.add_app_button._signal_clicked_connector = child.add_app_button.connect('clicked',self._on_add_steamapp_button_clicked,data)
|
||||
|
||||
if hasattr(child.ignore_app_button,'_signal_clicked_connector'):
|
||||
child.ignore_app_button.disconnect(child.ignore_app_button._signal_clicked_connector)
|
||||
child.ignore_app_button._signal_clicked_connector = child.ignore_app_button.connect('clicked',self._on_ignore_steamapp_button_clicked,data)
|
||||
|
||||
def _on_listitem_unbind(self,factory,item):
|
||||
child = item.get_child()
|
||||
data = item.get_item()
|
||||
|
||||
def _on_add_steamapp_button_clicked(self,button,data:SteamApp,*args):
|
||||
def on_dialog_response(dialog,response):
|
||||
self.__gamedialog = None
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
for i in range(self.__listmodel.get_n_items()):
|
||||
if data.appid == self.__listmodel.get_item(i).appid:
|
||||
self.__listmodel.remove(i)
|
||||
break
|
||||
|
||||
if self.__gamedialog is not None:
|
||||
return
|
||||
|
||||
game = Game("Enter key",data.name,"")
|
||||
if PLATFORM_WINDOWS:
|
||||
game.steam_windows = SteamWindowsGame(data.appid,"","",installdir=data.installdir)
|
||||
|
||||
0
sgbackup/help/__init__.py
Normal file
0
sgbackup/help/__init__.py
Normal file
@ -29,9 +29,9 @@ def cli_main():
|
||||
logger.debug("Running cli_main()")
|
||||
return 0
|
||||
|
||||
def curses_main():
|
||||
logger.debug("Running curses_main()")
|
||||
return 0
|
||||
#def curses_main():
|
||||
# logger.debug("Running curses_main()")
|
||||
# return 0
|
||||
|
||||
def gui_main():
|
||||
logger.debug("Running gui_main()")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user