def on_runner_changed(self, widget): """Action called when runner drop down is changed.""" new_runner_index = widget.get_active() if self.runner_index and new_runner_index != self.runner_index: dlg = QuestionDialog( { "parent": self, "question": _("Are you sure you want to change the runner for this game ? " "This will reset the full configuration for this game and " "is not reversible."), "title": _("Confirm runner change"), } ) if dlg.result == Gtk.ResponseType.YES: self.runner_index = new_runner_index self._switch_runner(widget) else: # Revert the dropdown menu to the previously selected runner widget.set_active(self.runner_index) else: self.runner_index = new_runner_index self._switch_runner(widget)
def confirm_cancel(self, _widget=None): """Ask a confirmation before cancelling the install""" remove_checkbox = Gtk.CheckButton.new_with_label( _("Remove game files")) if self.interpreter and self.interpreter.target_path: remove_checkbox.set_active(self.interpreter.game_dir_created) remove_checkbox.show() confirm_cancel_dialog = QuestionDialog({ "question": _("Are you sure you want to cancel the installation?"), "title": _("Cancel installation?"), "widgets": [remove_checkbox] }) if confirm_cancel_dialog.result != Gtk.ResponseType.YES: logger.debug("User aborted installation cancellation") return True if self._cancel_files_func: self._cancel_files_func() if self.interpreter: self.interpreter.revert( remove_game_dir=remove_checkbox.get_active()) self.interpreter.cleanup( ) # still remove temporary downloads in any case self.destroy()
def install(self): success = super(hatari, self).install() if not success: return False config_path = os.path.expanduser('~/.hatari') if not os.path.exists(config_path): os.makedirs(config_path) bios_path = os.path.expanduser('~/.hatari/bios') if not os.path.exists(bios_path): os.makedirs(bios_path) dlg = QuestionDialog({ 'question': "Do you want to select an Atari ST BIOS file?", 'title': "Use BIOS file?", }) if dlg.result == dlg.YES: bios_dlg = FileDialog("Select a BIOS file") bios_filename = bios_dlg.filename shutil.copy(bios_filename, bios_path) bios_path = os.path.join(bios_path, os.path.basename(bios_filename)) runner_config = LutrisConfig(runner='hatari') runner_config.config_type = 'runner' runner_config.runner_config = {'hatari': {'bios_file': bios_path}} runner_config.save() return True
def on_runner_installed(*args): bios_path = system.create_folder('~/.pcsxr/bios') dlg = QuestionDialog({ 'question': ("Do you want to select a Playstation BIOS file?\n\n" "The BIOS is the core code running the machine.\n" "PCSX-Reloaded includes an emulated BIOS, but it is " "still incomplete. \n" "Using an original BIOS avoids some bugs and reduced " "compatibility \n" "with some games."), 'title': "Use BIOS file?", }) if dlg.result == dlg.YES: bios_dlg = FileDialog("Select a BIOS file") bios_src = bios_dlg.filename shutil.copy(bios_src, bios_path) # Save bios in config bios_path = os.path.join(bios_path, os.path.basename(bios_src)) config = LutrisConfig(runner_slug='pcsxr') config.raw_runner_config.update({'bios': bios_path}) config.save() if callback: callback()
def on_apply_button_clicked(self, widget): widget.set_sensitive(False) remove_from_library_button = self.builder.get_object( 'remove_from_library_button' ) remove_from_library = remove_from_library_button.get_active() remove_contents_button = self.builder.get_object( 'remove_contents_button' ) remove_contents = remove_contents_button.get_active() if remove_contents and not hasattr(self.game.runner, 'no_game_remove_warning'): game_dir = self.game.directory.replace('&', '&') dlg = QuestionDialog({ 'question': "Are you sure you want to delete EVERYTHING under " "\n<b>%s</b>?\n (This can't be undone)" % game_dir, 'title': "CONFIRM DANGEROUS OPERATION" }) if dlg.result != Gtk.ResponseType.YES: widget.set_sensitive(True) return self.game.remove(remove_from_library, remove_contents) self.callback(self.game.slug, remove_from_library) self.on_close()
def on_game_duplicate(self, _widget): confirm_dlg = QuestionDialog({ "parent": self.window, "question": _("Do you wish to duplicate %s?\nThe configuration will be duplicated, " "but the games files will <b>not be duplicated</b>.") % gtk_safe(self.game.name), "title": _("Duplicate game?"), }) if confirm_dlg.result != Gtk.ResponseType.YES: return assigned_name = get_unusued_game_name(self.game.name) old_config_id = self.game.game_config_id if old_config_id: new_config_id = duplicate_game_config(self.game.slug, old_config_id) else: new_config_id = None db_game = get_game_by_field(self.game.id, "id") db_game["name"] = assigned_name db_game["configpath"] = new_config_id db_game.pop("id") # Disconnect duplicate from service- there should be at most # 1 PGA game for a service game. db_game.pop("service", None) db_game.pop("service_id", None) game_id = add_game(**db_game) new_game = Game(game_id) new_game.save()
def on_installer_selected(self, _widget, installer_slug): """Sets the script interpreter to the correct script then proceed to install folder selection. If the installed game depends on another one and it's not installed, prompt the user to install it and quit this installer. """ self.clean_widgets() try: self.interpreter = interpreter.ScriptInterpreter( self.get_script_from_slug(installer_slug), self ) except MissingGameDependency as ex: dlg = QuestionDialog( { "question": _("This game requires %s. Do you want to install it?") % ex.slug, "title": _("Missing dependency"), } ) if dlg.result == Gtk.ResponseType.YES: InstallerWindow( installers=self.installers, service=self.service, appid=self.appid, application=self.application, ) self.destroy() return self.title_label.set_markup(_(u"<b>Installing {}</b>").format(gtk_safe(self.interpreter.installer.game_name))) self.select_install_folder()
def prepare_install(self, script_slug): install_script = None for script in self.scripts: if script["slug"] == script_slug: install_script = script if not install_script: raise ValueError("Could not find script %s" % script_slug) try: self.interpreter = interpreter.ScriptInterpreter( install_script, self) except MissingGameDependency as ex: dlg = QuestionDialog({ "question": "This game requires %s. Do you want to install it?" % ex.slug, "title": "Missing dependency", }) if dlg.result == Gtk.ResponseType.YES: InstallerWindow( game_slug=ex.slug, parent=self.parent, application=self.application, ) self.destroy() return self.title_label.set_markup(u"<b>Installing {}</b>".format( escape_gtk_label(self.interpreter.game_name))) self.select_install_folder()
def install(self): success = super(pcsxr, self).install() if not success: return False config_path = os.path.expanduser('~/.pcsxr') if not os.path.exists(config_path): os.makedirs(config_path) # Bios bios_path = os.path.expanduser('~/.pcsxr/bios') if not os.path.exists(bios_path): os.makedirs(bios_path) dlg = QuestionDialog({ 'question': ("Do you want to select a Playstation BIOS file?\n\n" "The BIOS is the core code running the machine.\n" "PCSX-Reloaded includes an emulated BIOS, but it is " "still incomplete. \n" "Using an original BIOS avoids some bugs and reduced " "compatibility \n" "with some games."), 'title': "Use BIOS file?", }) if dlg.result == dlg.YES: bios_dlg = FileDialog("Select a BIOS file") bios_src = bios_dlg.filename shutil.copy(bios_src, bios_path) # Save bios in config bios_path = os.path.join(bios_path, os.path.basename(bios_src)) runner_config = LutrisConfig(runner='pcsxr') runner_config.config_type = 'runner' runner_config.runner_config = {'pcsxr': {'bios': bios_path}} runner_config.save() return True
def on_save(self, _button): """Save game info and destroy widget. Return True if success.""" try: if self.slug_entry.get_sensitive() and self.slug != self.slug_entry.get_text(): # Warn the user they made changes to the slug that need to be applied dlg = QuestionDialog( { "question": _("You have modified the idenitifier, but not applied it." "Would you like to apply those changes now?"), "title": _("Confirm pending identifier change"), } ) if dlg.result == Gtk.ResponseType.YES: self.change_game_slug() except AttributeError: pass if not self.is_valid(): logger.warning(_("Current configuration is not valid, ignoring save request")) return False name = self.name_entry.get_text() if not self.slug: self.slug = slugify(name) if not self.game: self.game = Game() year = None if self.year_entry.get_text(): year = int(self.year_entry.get_text()) if not self.lutris_config.game_config_id: self.lutris_config.game_config_id = make_game_config_id(self.slug) runner_class = runners.import_runner(self.runner_name) runner = runner_class(self.lutris_config) self.game.name = name self.game.slug = self.slug self.game.year = year self.game.game_config_id = self.lutris_config.game_config_id self.game.runner = runner self.game.runner_name = self.runner_name self.game.directory = runner.game_path self.game.is_installed = True if self.runner_name in ("steam", "winesteam"): self.game.steamid = self.lutris_config.game_config["appid"] self.game.config = self.lutris_config self.game.save() self.destroy() self.saved = True return True
def on_runner_installed(*args): dlg = QuestionDialog({ 'question': "Do you want to select a premium license file?", 'title': "Use premium version?", }) if dlg.result == dlg.YES: license_dlg = FileDialog("Select a license file") license_filename = license_dlg.filename if not license_filename: return shutil.copy(license_filename, os.path.join(settings.RUNNER_DIR, 'redream'))
def on_remove_clicked(self, widget): dialog = QuestionDialog( { "title": _("Do you want to uninstall %s?") % self.runner.human_name, "question": _("This will remove <b>%s</b> and all associated data." % self.runner.human_name) } ) if Gtk.ResponseType.YES == dialog.result: self.runner.uninstall() self.emit("runner-removed")
def cancel_installation(self, widget=None): """Ask a confirmation before cancelling the install""" confirm_cancel_dialog = QuestionDialog({ "question": "Are you sure you want to cancel the installation?", "title": "Cancel installation?", }) if confirm_cancel_dialog.result != Gtk.ResponseType.YES: return True if self.interpreter: self.interpreter.revert() self.interpreter.cleanup() self.destroy()
def on_installed_toggled(self, _widget, path): row = self.runner_store[path] if row[self.COL_VER] in self.installing: confirm_dlg = QuestionDialog({ "question": "Do you want to cancel the download?", "title": "Download starting", }) if confirm_dlg.result == confirm_dlg.YES: self.cancel_install(row) elif row[self.COL_INSTALLED]: self.uninstall_runner(row) else: self.install_runner(row)
def on_installer_selected(self, _widget, installer_version): """Sets the script interpreter to the correct script then proceed to install folder selection. If the installed game depends on another one and it's not installed, prompt the user to install it and quit this installer. """ self.clean_widgets() try: script = None for _script in self.installers: if _script["version"] == installer_version: script = _script self.interpreter = interpreter.ScriptInterpreter(script, self) except MissingGameDependency as ex: dlg = QuestionDialog({ "question": _("This game requires %s. Do you want to install it?") % ex.slug, "title": _("Missing dependency"), }) if dlg.result == Gtk.ResponseType.YES: InstallerWindow( installers=self.installers, service=self.service, appid=self.appid, application=self.application, ) self.destroy() return self.title_label.set_markup( _("<b>Installing {}</b>").format( gtk_safe(self.interpreter.installer.game_name))) self.select_install_folder() desktop_shortcut_button = Gtk.CheckButton(_("Create desktop shortcut"), visible=True) desktop_shortcut_button.connect( "clicked", self.on_create_desktop_shortcut_clicked) self.widget_box.pack_start(desktop_shortcut_button, False, False, 5) menu_shortcut_button = Gtk.CheckButton( _("Create application menu shortcut"), visible=True) menu_shortcut_button.connect("clicked", self.on_create_menu_shortcut_clicked) self.widget_box.pack_start(menu_shortcut_button, False, False, 5)
def cancel_installation(self, widget=None): """Ask a confirmation before cancelling the install""" confirm_cancel_dialog = QuestionDialog({ "question": "Are you sure you want to cancel the installation?", "title": "Cancel installation?", }) if confirm_cancel_dialog.result != Gtk.ResponseType.YES: logger.warning( "Attempting to terminate with the system wineserver. " "This is most likely to fail or to have no effect.") system.execute([system.find_executable("wineserver"), "-k9"]) return True if self.interpreter: self.interpreter.revert() self.interpreter.cleanup() self.destroy()
def cancel_installation(self, widget=None): """Ask a confirmation before cancelling the install""" remove_checkbox = Gtk.CheckButton.new_with_label("Remove game files") if self.interpreter: remove_checkbox.set_active(self.interpreter.game_dir_created) remove_checkbox.show() confirm_cancel_dialog = QuestionDialog({ "question": "Are you sure you want to cancel the installation?", "title": "Cancel installation?", "widgets": [remove_checkbox] }) if confirm_cancel_dialog.result != Gtk.ResponseType.YES: logger.debug("User cancelled installation") return True if self.interpreter: self.interpreter.revert() self.interpreter.cleanup() self.destroy()
def on_runner_installed(*args): bios_path = system.create_folder('~/.hatari/bios') dlg = QuestionDialog({ 'question': "Do you want to select an Atari ST BIOS file?", 'title': "Use BIOS file?", }) if dlg.result == dlg.YES: bios_dlg = FileDialog("Select a BIOS file") bios_filename = bios_dlg.filename if not bios_filename: return shutil.copy(bios_filename, bios_path) bios_path = os.path.join(bios_path, os.path.basename(bios_filename)) config = LutrisConfig(runner_slug='hatari') config.raw_runner_config.update({'bios_file': bios_path}) config.save() if callback: callback()
def install(self): success = super(pcsxr, self).install() if not success: return False config_path = os.path.expanduser('~/.pcsxr') if not os.path.exists(config_path): os.makedirs(config_path) bios_path = os.path.expanduser('~/.pcsxr/bios') if not os.path.exists(bios_path): os.makedirs(bios_path) dlg = QuestionDialog({ 'question': "Do you want to select a Playstation BIOS file?", 'title': "Use BIOS file?", }) if dlg.result == dlg.YES: bios_dlg = FileDialog("Select a BIOS file") bios_filename = bios_dlg.filename shutil.copy(bios_filename, bios_path) return True
def on_delete_clicked(self, button): button.set_sensitive(False) if self.delete_files and not hasattr(self.game.runner, "no_game_remove_warning"): dlg = QuestionDialog({ "question": _("Please confirm.\nEverything under <b>%s</b>\n" "will be deleted.") % gtk_safe(self.game.directory), "title": _("Permanently delete files?"), }) if dlg.result != Gtk.ResponseType.YES: button.set_sensitive(True) return if self.delete_files: self.folder_label.set_markup( "Uninstalling game and deleting files...") else: self.folder_label.set_markup("Uninstalling game...") AsyncCall(self.game.remove, self.delete_cb, self.delete_files)
def cancel_installation(self, widget=None): """Ask a confirmation before cancelling the install""" remove_checkbox = Gtk.CheckButton.new_with_label("Remove game files") if self.interpreter: remove_checkbox.set_active(self.interpreter.game_dir_created) remove_checkbox.show() confirm_cancel_dialog = QuestionDialog( { "question": "Are you sure you want to cancel the installation?", "title": "Cancel installation?", "widgets": [remove_checkbox] } ) if confirm_cancel_dialog.result != Gtk.ResponseType.YES: logger.warning("Attempting to terminate with the system wineserver. " "This is most likely to fail or to have no effect.") system.execute([system.find_executable("wineserver"), "-k9"]) return True if self.interpreter: self.interpreter.game_dir_created = remove_checkbox.get_active() self.interpreter.revert() self.interpreter.cleanup() self.destroy()