1
0
Fork 0
mirror of https://github.com/deepfakes/faceswap synced 2025-06-09 04:36:50 -04:00

locales: Add GUI menu translations

This commit is contained in:
torzdf 2023-06-07 14:16:27 +01:00
parent 013f3016f1
commit 50a5113690
16 changed files with 1018 additions and 513 deletions

View file

@ -104,6 +104,13 @@ display\_graph module
:undoc-members:
:show-inheritance:
menu module
===========
.. automodule:: lib.gui.menu
:members:
:undoc-members:
:show-inheritance:
popup_configure module
======================
.. automodule:: lib.gui.popup_configure

View file

@ -7,13 +7,14 @@ import logging
import os
import sys
import tkinter as tk
import typing as T
from tkinter import ttk
import webbrowser
from subprocess import Popen, PIPE, STDOUT
from lib.multithreading import MultiThread
from lib.serializer import get_serializer
from lib.serializer import get_serializer, Serializer
from lib.utils import FaceswapError
import update_deps
@ -21,23 +22,33 @@ from .popup_configure import open_popup
from .custom_widgets import Tooltip
from .utils import get_config, get_images
if T.TYPE_CHECKING:
from scripts.gui import FaceswapGui
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
# LOCALES
_LANG = gettext.translation("gui.tooltips", localedir="locales", fallback=True)
_LANG = gettext.translation("gui.menu", localedir="locales", fallback=True)
_ = _LANG.gettext
_WORKING_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
_RESOURCES = [(_("faceswap.dev - Guides and Forum"), "https://www.faceswap.dev"),
_RESOURCES: T.List[T.Tuple[str, str]] = [
(_("faceswap.dev - Guides and Forum"), "https://www.faceswap.dev"),
(_("Patreon - Support this project"), "https://www.patreon.com/faceswap"),
(_("Discord - The FaceSwap Discord server"), "https://discord.gg/VasFUAy"),
(_("Github - Our Source Code"), "https://github.com/deepfakes/faceswap")]
class MainMenuBar(tk.Menu): # pylint:disable=too-many-ancestors
""" GUI Main Menu Bar """
def __init__(self, master=None):
""" GUI Main Menu Bar
Parameters
----------
master: :class:`tkinter.Tk`
The root tkinter object
"""
def __init__(self, master: "FaceswapGui") -> None:
logger.debug("Initializing %s", self.__class__.__name__)
super().__init__(master)
self.root = master
@ -46,99 +57,130 @@ class MainMenuBar(tk.Menu): # pylint:disable=too-many-ancestors
self.settings_menu = SettingsMenu(self)
self.help_menu = HelpMenu(self)
self.add_cascade(label="File", menu=self.file_menu, underline=0)
self.add_cascade(label="Settings", menu=self.settings_menu, underline=0)
self.add_cascade(label="Help", menu=self.help_menu, underline=0)
self.add_cascade(label=_("File"), menu=self.file_menu, underline=0)
self.add_cascade(label=_("Settings"), menu=self.settings_menu, underline=0)
self.add_cascade(label=_("Help"), menu=self.help_menu, underline=0)
logger.debug("Initialized %s", self.__class__.__name__)
class SettingsMenu(tk.Menu): # pylint:disable=too-many-ancestors
""" Settings menu items and functions """
def __init__(self, parent):
""" Settings menu items and functions
Parameters
----------
parent: :class:`tkinter.Menu`
The main menu bar to hold this menu item
"""
def __init__(self, parent: MainMenuBar) -> None:
logger.debug("Initializing %s", self.__class__.__name__)
super().__init__(parent, tearoff=0)
self.root = parent.root
self.build()
self._build()
logger.debug("Initialized %s", self.__class__.__name__)
def build(self):
def _build(self) -> None:
""" Add the settings menu to the menu bar """
# pylint: disable=cell-var-from-loop
logger.debug("Building settings menu")
self.add_command(label="Configure Settings...",
self.add_command(label=_("Configure Settings..."),
underline=0,
command=open_popup)
logger.debug("Built settings menu")
class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
""" File menu items and functions """
def __init__(self, parent):
""" File menu items and functions
Parameters
----------
parent: :class:`tkinter.Menu`
The main menu bar to hold this menu item
"""
def __init__(self, parent: MainMenuBar) -> None:
logger.debug("Initializing %s", self.__class__.__name__)
super().__init__(parent, tearoff=0)
self.root = parent.root
self._config = get_config()
self.recent_menu = tk.Menu(self, tearoff=0, postcommand=self.refresh_recent_menu)
self.build()
self.recent_menu = tk.Menu(self, tearoff=0, postcommand=self._refresh_recent_menu)
self._build()
logger.debug("Initialized %s", self.__class__.__name__)
def build(self):
def _refresh_recent_menu(self) -> None:
""" Refresh recent menu on save/load of files """
self.recent_menu.delete(0, "end")
self._build_recent_menu()
def _build(self) -> None:
""" Add the file menu to the menu bar """
logger.debug("Building File menu")
self.add_command(label="New Project...",
self.add_command(label=_("New Project..."),
underline=0,
accelerator="Ctrl+N",
command=self._config.project.new)
self.root.bind_all("<Control-n>", self._config.project.new)
self.add_command(label="Open Project...",
self.add_command(label=_("Open Project..."),
underline=0,
accelerator="Ctrl+O",
command=self._config.project.load)
self.root.bind_all("<Control-o>", self._config.project.load)
self.add_command(label="Save Project",
self.add_command(label=_("Save Project"),
underline=0,
accelerator="Ctrl+S",
command=lambda: self._config.project.save(save_as=False))
self.root.bind_all("<Control-s>", lambda e: self._config.project.save(e, save_as=False))
self.add_command(label="Save Project as...",
self.add_command(label=_("Save Project as..."),
underline=13,
accelerator="Ctrl+Alt+S",
command=lambda: self._config.project.save(save_as=True))
self.root.bind_all("<Control-Alt-s>", lambda e: self._config.project.save(e, save_as=True))
self.add_command(label="Reload Project from Disk",
self.add_command(label=_("Reload Project from Disk"),
underline=0,
accelerator="F5",
command=self._config.project.reload)
self.root.bind_all("<F5>", self._config.project.reload)
self.add_command(label="Close Project",
self.add_command(label=_("Close Project"),
underline=0,
accelerator="Ctrl+W",
command=self._config.project.close)
self.root.bind_all("<Control-w>", self._config.project.close)
self.add_separator()
self.add_command(label="Open Task...",
self.add_command(label=_("Open Task..."),
underline=5,
accelerator="Ctrl+Alt+T",
command=lambda: self._config.tasks.load(current_tab=False))
self.root.bind_all("<Control-Alt-t>",
lambda e: self._config.tasks.load(e, current_tab=False))
self.add_separator()
self.add_cascade(label="Open recent", underline=6, menu=self.recent_menu)
self.add_cascade(label=_("Open recent"), underline=6, menu=self.recent_menu)
self.add_separator()
self.add_command(label="Quit",
self.add_command(label=_("Quit"),
underline=0,
accelerator="Alt+F4",
command=self.root.close_app)
self.root.bind_all("<Alt-F4>", self.root.close_app)
logger.debug("Built File menu")
def build_recent_menu(self):
@classmethod
def _clear_recent_files(cls, serializer: Serializer, menu_file: str) -> None:
""" Creates or clears recent file list
Parameters
----------
serializer: :class:`~lib.serializer.Serializer`
The serializer to use for storing files
menu_file: str
The file name holding the recent files
"""
logger.debug("clearing recent files list: '%s'", menu_file)
serializer.save(menu_file, [])
def _build_recent_menu(self) -> None:
""" Load recent files into menu bar """
logger.debug("Building Recent Files menu")
serializer = get_serializer("json")
menu_file = os.path.join(self._config.pathcache, ".recent.json")
if not os.path.isfile(menu_file) or os.path.getsize(menu_file) == 0:
self.clear_recent_files(serializer, menu_file)
self._clear_recent_files(serializer, menu_file)
try:
recent_files = serializer.load(menu_file)
except FaceswapError as err:
@ -146,7 +188,7 @@ class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
# Some reports of corruption breaking menus
logger.warning("There was an error opening the recent files list so it has been "
"reset.")
self.clear_recent_files(serializer, menu_file)
self._clear_recent_files(serializer, menu_file)
recent_files = []
logger.debug("Loaded recent files: %s", recent_files)
@ -163,14 +205,14 @@ class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
if command.lower() == "project":
load_func = self._config.project.load
lbl = command
kwargs = dict(filename=filename)
kwargs = {"filename": filename}
else:
load_func = self._config.tasks.load
lbl = f"{command} Task"
kwargs = dict(filename=filename, current_tab=False)
load_func = self._config.tasks.load # type:ignore
lbl = _("{} Task").format(command)
kwargs = {"filename": filename, "current_tab": False}
self.recent_menu.add_command(
label=f"{filename} ({lbl.title()})",
command=lambda kw=kwargs, fn=load_func: fn(**kw))
command=lambda kw=kwargs, fn=load_func: fn(**kw)) # type:ignore
if removed_files:
for recent_item in removed_files:
logger.debug("Removing from recent files: `%s`", recent_item[0])
@ -178,222 +220,76 @@ class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
serializer.save(menu_file, recent_files)
self.recent_menu.add_separator()
self.recent_menu.add_command(
label="Clear recent files",
label=_("Clear recent files"),
underline=0,
command=lambda srl=serializer, mnu=menu_file: self.clear_recent_files(srl, mnu))
command=lambda srl=serializer, mnu=menu_file: self._clear_recent_files( # type:ignore
srl, mnu))
logger.debug("Built Recent Files menu")
@staticmethod
def clear_recent_files(serializer, menu_file):
""" Creates or clears recent file list """
logger.debug("clearing recent files list: '%s'", menu_file)
serializer.save(menu_file, [])
def refresh_recent_menu(self):
""" Refresh recent menu on save/load of files """
self.recent_menu.delete(0, "end")
self.build_recent_menu()
class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
""" Help menu items and functions """
def __init__(self, parent):
""" Help menu items and functions
Parameters
----------
parent: :class:`tkinter.Menu`
The main menu bar to hold this menu item
"""
def __init__(self, parent: MainMenuBar) -> None:
logger.debug("Initializing %s", self.__class__.__name__)
super().__init__(parent, tearoff=0)
self.root = parent.root
self.recources_menu = tk.Menu(self, tearoff=0)
self._branches_menu = tk.Menu(self, tearoff=0)
self.build()
self._build()
logger.debug("Initialized %s", self.__class__.__name__)
def build(self):
""" Build the help menu """
logger.debug("Building Help menu")
self.add_command(label="Check for updates...",
underline=0,
command=lambda action="check": self.in_thread(action))
self.add_command(label="Update Faceswap...",
underline=0,
command=lambda action="update": self.in_thread(action))
if self._build_branches_menu():
self.add_cascade(label="Switch Branch", underline=7, menu=self._branches_menu)
self.add_separator()
self._build_recources_menu()
self.add_cascade(label="Resources", underline=0, menu=self.recources_menu)
self.add_separator()
self.add_command(label="Output System Information",
underline=0,
command=lambda action="output_sysinfo": self.in_thread(action))
logger.debug("Built help menu")
def _build_branches_menu(self):
""" Build branch selection menu.
Queries git for available branches and builds a menu based on output.
Returns
-------
bool
``True`` if menu was successfully built otherwise ``False``
"""
stdout = self._get_branches()
if stdout is None:
return False
branches = self._filter_branches(stdout)
if not branches:
return False
for branch in branches:
self._branches_menu.add_command(
label=branch,
command=lambda b=branch: self._switch_branch(b))
return True
@staticmethod
def _get_branches():
""" Get the available github branches
Returns
-------
str
The list of branches available. If no branches were found or there was an
error then `None` is returned
"""
gitcmd = "git branch -a"
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
logger.debug("Unable to list git branches. return code: %s, message: %s",
retcode,
stdout.decode(locale.getpreferredencoding(),
errors="replace").strip().replace("\n", " - "))
return None
return stdout.decode(locale.getpreferredencoding(), errors="replace")
@staticmethod
def _filter_branches(stdout):
""" Filter the branches, remove duplicates and the current branch and return a sorted
list.
def _in_thread(self, action: str):
""" Perform selected action inside a thread
Parameters
----------
stdout: str
The output from the git branch query converted to a string
Returns
-------
list
Unique list of available branches sorted in alphabetical order
action: str
The action to be performed. The action corresponds to the function name to be called
"""
current = None
branches = set()
for line in stdout.splitlines():
branch = line[line.rfind("/") + 1:] if "/" in line else line.strip()
if branch.startswith("*"):
branch = branch.replace("*", "").strip()
current = branch
continue
branches.add(branch)
logger.debug("Found branches: %s", branches)
if current in branches:
logger.debug("Removing current branch from output: %s", current)
branches.remove(current)
branches = sorted(list(branches), key=str.casefold)
logger.debug("Final branches: %s", branches)
return branches
@staticmethod
def _switch_branch(branch):
""" Change the currently checked out branch, and return a notification.
Parameters
----------
str
The branch to switch to
"""
logger.info("Switching branch to '%s'...", branch)
gitcmd = f"git checkout {branch}"
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
logger.error("Unable to switch branch. return code: %s, message: %s",
retcode,
stdout.decode(locale.getdefaultlocale(),
errors="replace").strip().replace("\n", " - "))
return
logger.info("Succesfully switched to '%s'. You may want to check for updates to make sure "
"that you have the latest code.", branch)
logger.info("Please restart Faceswap to complete the switch.")
def _build_recources_menu(self):
""" Build resources menu """
# pylint: disable=cell-var-from-loop
logger.debug("Building Resources Files menu")
for resource in _RESOURCES:
self.recources_menu.add_command(
label=resource[0],
command=lambda link=resource[1]: webbrowser.open_new(link))
logger.debug("Built resources menu")
def in_thread(self, action):
""" Perform selected action inside a thread """
logger.debug("Performing help action: %s", action)
thread = MultiThread(getattr(self, action), thread_count=1)
thread.start()
logger.debug("Performed help action: %s", action)
@staticmethod
def clear_console():
""" Clear the console window """
get_config().tk_vars.console_clear.set(True)
def output_sysinfo(self):
def _output_sysinfo(self):
""" Output system information to console """
logger.debug("Obtaining system information")
self.root.config(cursor="watch")
self.clear_console()
self._clear_console()
try:
from lib.sysinfo import sysinfo # pylint:disable=import-outside-toplevel
info = sysinfo
except Exception as err: # pylint:disable=broad-except
info = f"Error obtaining system info: {str(err)}"
self.clear_console()
self._clear_console()
logger.debug("Obtained system information: %s", info)
print(info)
self.root.config(cursor="")
def check(self):
""" Check for updates and clone repository """
logger.debug("Checking for updates...")
self.root.config(cursor="watch")
encoding = locale.getpreferredencoding()
logger.debug("Encoding: %s", encoding)
self.check_for_updates(encoding, check=True)
self.root.config(cursor="")
@classmethod
def _check_for_updates(cls, encoding: str, check: bool = False) -> bool:
""" Check whether an update is required
def update(self):
""" Check for updates and clone repository """
logger.debug("Updating Faceswap...")
self.root.config(cursor="watch")
encoding = locale.getpreferredencoding()
logger.debug("Encoding: %s", encoding)
success = False
if self.check_for_updates(encoding):
success = self.do_update(encoding)
update_deps.main(is_gui=True)
if success:
logger.info("Please restart Faceswap to complete the update.")
self.root.config(cursor="")
Parameters
----------
encoding: str
The encoding to use for decoding process returns
check: bool
``True`` if we are just checking for updates ``False`` if a check and update is to be
performed. Default: ``False``
@staticmethod
def check_for_updates(encoding, check=False):
""" Check whether an update is required """
Returns
-------
bool
``True`` if an update is required
"""
# Do the check
logger.info("Checking for updates...")
update = False
@ -426,9 +322,29 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
logger.debug("Checked for update. Update required: %s", update)
return update
@staticmethod
def do_update(encoding):
""" Update Faceswap """
def _check(self) -> None:
""" Check for updates and clone repository """
logger.debug("Checking for updates...")
self.root.config(cursor="watch")
encoding = locale.getpreferredencoding()
logger.debug("Encoding: %s", encoding)
self._check_for_updates(encoding, check=True)
self.root.config(cursor="")
@classmethod
def _do_update(cls, encoding: str) -> bool:
""" Update Faceswap
Parameters
----------
encoding: str
The encoding to use for decoding process returns
Returns
-------
bool
``True`` if update was successful
"""
logger.info("A new version is available. Updating...")
gitcmd = "git pull"
with Popen(gitcmd,
@ -438,7 +354,8 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
bufsize=1,
cwd=_WORKING_DIR) as cmd:
while True:
output = cmd.stdout.readline().decode(encoding, errors="replace")
out = cmd.stdout
output = "" if out is None else out.readline().decode(encoding, errors="replace")
if output == "" and cmd.poll() is not None:
break
if output:
@ -453,10 +370,170 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
retval = True
return retval
def _update(self) -> None:
""" Check for updates and clone repository """
logger.debug("Updating Faceswap...")
self.root.config(cursor="watch")
encoding = locale.getpreferredencoding()
logger.debug("Encoding: %s", encoding)
success = False
if self._check_for_updates(encoding):
success = self._do_update(encoding)
update_deps.main(is_gui=True)
if success:
logger.info("Please restart Faceswap to complete the update.")
self.root.config(cursor="")
def _build(self) -> None:
""" Build the help menu """
logger.debug("Building Help menu")
self.add_command(label=_("Check for updates..."),
underline=0,
command=lambda action="_check": self._in_thread(action)) # type:ignore
self.add_command(label=_("Update Faceswap..."),
underline=0,
command=lambda action="_update": self._in_thread(action)) # type:ignore
if self._build_branches_menu():
self.add_cascade(label=_("Switch Branch"), underline=7, menu=self._branches_menu)
self.add_separator()
self._build_recources_menu()
self.add_cascade(label=_("Resources"), underline=0, menu=self.recources_menu)
self.add_separator()
self.add_command(
label=_("Output System Information"),
underline=0,
command=lambda action="_output_sysinfo": self._in_thread(action)) # type:ignore
logger.debug("Built help menu")
def _build_branches_menu(self) -> bool:
""" Build branch selection menu.
Queries git for available branches and builds a menu based on output.
Returns
-------
bool
``True`` if menu was successfully built otherwise ``False``
"""
stdout = self._get_branches()
if stdout is None:
return False
branches = self._filter_branches(stdout)
if not branches:
return False
for branch in branches:
self._branches_menu.add_command(
label=branch,
command=lambda b=branch: self._switch_branch(b)) # type:ignore
return True
@classmethod
def _get_branches(cls) -> T.Optional[str]:
""" Get the available github branches
Returns
-------
str or ``None``
The list of branches available. If no branches were found or there was an
error then `None` is returned
"""
gitcmd = "git branch -a"
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
logger.debug("Unable to list git branches. return code: %s, message: %s",
retcode,
stdout.decode(locale.getpreferredencoding(),
errors="replace").strip().replace("\n", " - "))
return None
return stdout.decode(locale.getpreferredencoding(), errors="replace")
@classmethod
def _filter_branches(cls, stdout: str) -> T.List[str]:
""" Filter the branches, remove duplicates and the current branch and return a sorted
list.
Parameters
----------
stdout: str
The output from the git branch query converted to a string
Returns
-------
list[str]
Unique list of available branches sorted in alphabetical order
"""
current = None
branches = set()
for line in stdout.splitlines():
branch = line[line.rfind("/") + 1:] if "/" in line else line.strip()
if branch.startswith("*"):
branch = branch.replace("*", "").strip()
current = branch
continue
branches.add(branch)
logger.debug("Found branches: %s", branches)
if current in branches:
logger.debug("Removing current branch from output: %s", current)
branches.remove(current)
retval = sorted(list(branches), key=str.casefold)
logger.debug("Final branches: %s", retval)
return retval
@classmethod
def _switch_branch(cls, branch: str) -> None:
""" Change the currently checked out branch, and return a notification.
Parameters
----------
str
The branch to switch to
"""
logger.info("Switching branch to '%s'...", branch)
gitcmd = f"git checkout {branch}"
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
logger.error("Unable to switch branch. return code: %s, message: %s",
retcode,
stdout.decode(T.cast(str, locale.getdefaultlocale()),
errors="replace").strip().replace("\n", " - "))
return
logger.info("Succesfully switched to '%s'. You may want to check for updates to make sure "
"that you have the latest code.", branch)
logger.info("Please restart Faceswap to complete the switch.")
def _build_recources_menu(self) -> None:
""" Build resources menu """
# pylint: disable=cell-var-from-loop
logger.debug("Building Resources Files menu")
for resource in _RESOURCES:
self.recources_menu.add_command(
label=resource[0],
command=lambda link=resource[1]: webbrowser.open_new(link)) # type:ignore
logger.debug("Built resources menu")
@classmethod
def _clear_console(cls) -> None:
""" Clear the console window """
get_config().tk_vars.console_clear.set(True)
class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
""" Task bar buttons """
def __init__(self, parent):
""" Task bar buttons
Parameters
----------
parent: :class:`tkinter.ttk.Frame`
The frame that holds the task bar
"""
def __init__(self, parent: ttk.Frame) -> None:
super().__init__(parent)
self._config = get_config()
self.pack(side=tk.TOP, anchor=tk.W, fill=tk.X, expand=False)
@ -470,75 +547,43 @@ class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
self._settings_btns()
self._section_separator()
def _project_btns(self):
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
@classmethod
def _loader_and_kwargs(cls, btntype: str) -> T.Tuple[str, T.Dict[str, bool]]:
""" Get the loader name and key word arguments for the given button type
for btntype in ("new", "load", "save", "save_as", "reload"):
logger.debug("Adding button: '%s'", btntype)
Parameters
----------
btntype: str
The button type to obtain the information for
loader, kwargs = self._loader_and_kwargs(btntype)
cmd = getattr(self._config.project, loader)
btn = ttk.Button(frame,
image=get_images().icons[btntype],
command=lambda fn=cmd, kw=kwargs: fn(**kw))
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = self.set_help(btntype)
Tooltip(btn, text=hlp, wrap_length=200)
def _task_btns(self):
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
for loadtype in ("load", "save", "save_as", "clear", "reload"):
btntype = f"{loadtype}2"
logger.debug("Adding button: '%s'", btntype)
loader, kwargs = self._loader_and_kwargs(loadtype)
if loadtype == "load":
kwargs["current_tab"] = True
cmd = getattr(self._config.tasks, loader)
btn = ttk.Button(
frame,
image=get_images().icons[btntype],
command=lambda fn=cmd, kw=kwargs: fn(**kw))
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = self.set_help(btntype)
Tooltip(btn, text=hlp, wrap_length=200)
@staticmethod
def _loader_and_kwargs(btntype):
Returns
-------
loader: str
The name of the loader to use for the given button type
kwargs: dict[str, bool]
The keyword arguments to use for the returned loader
"""
if btntype == "save":
loader = btntype
kwargs = dict(save_as=False)
kwargs = {"save_as": False}
elif btntype == "save_as":
loader = "save"
kwargs = dict(save_as=True)
kwargs = {"save_as": True}
else:
loader = btntype
kwargs = {}
logger.debug("btntype: %s, loader: %s, kwargs: %s", btntype, loader, kwargs)
return loader, kwargs
def _settings_btns(self):
# pylint: disable=cell-var-from-loop
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
for name in ("extract", "train", "convert"):
btntype = f"settings_{name}"
btntype = btntype if btntype in get_images().icons else "settings"
logger.debug("Adding button: '%s'", btntype)
btn = ttk.Button(
frame,
image=get_images().icons[btntype],
command=lambda n=name: open_popup(name=n))
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = _("Configure {} settings...").format(name.title())
Tooltip(btn, text=hlp, wrap_length=200)
@classmethod
def _set_help(cls, btntype: str) -> str:
""" Set the helptext for option buttons
@staticmethod
def set_help(btntype):
""" Set the helptext for option buttons """
Parameters
----------
btntype: str
The button type to set the help text for
"""
logger.debug("Setting help")
hlp = ""
task = _("currently selected Task") if btntype[-1] == "2" else _("Project")
@ -559,11 +604,68 @@ class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
hlp = _("Load {}...").format(msg)
return hlp
def _group_separator(self):
def _project_btns(self) -> None:
""" Place the project buttons """
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
for btntype in ("new", "load", "save", "save_as", "reload"):
logger.debug("Adding button: '%s'", btntype)
loader, kwargs = self._loader_and_kwargs(btntype)
cmd = getattr(self._config.project, loader)
btn = ttk.Button(frame,
image=get_images().icons[btntype],
command=lambda fn=cmd, kw=kwargs: fn(**kw)) # type:ignore
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = self._set_help(btntype)
Tooltip(btn, text=hlp, wrap_length=200)
def _task_btns(self) -> None:
""" Place the task buttons """
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
for loadtype in ("load", "save", "save_as", "clear", "reload"):
btntype = f"{loadtype}2"
logger.debug("Adding button: '%s'", btntype)
loader, kwargs = self._loader_and_kwargs(loadtype)
if loadtype == "load":
kwargs["current_tab"] = True
cmd = getattr(self._config.tasks, loader)
btn = ttk.Button(
frame,
image=get_images().icons[btntype],
command=lambda fn=cmd, kw=kwargs: fn(**kw)) # type:ignore
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = self._set_help(btntype)
Tooltip(btn, text=hlp, wrap_length=200)
def _settings_btns(self) -> None:
""" Place the settings buttons """
# pylint: disable=cell-var-from-loop
frame = ttk.Frame(self._btn_frame)
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
for name in ("extract", "train", "convert"):
btntype = f"settings_{name}"
btntype = btntype if btntype in get_images().icons else "settings"
logger.debug("Adding button: '%s'", btntype)
btn = ttk.Button(
frame,
image=get_images().icons[btntype],
command=lambda n=name: open_popup(name=n)) # type:ignore
btn.pack(side=tk.LEFT, anchor=tk.W)
hlp = _("Configure {} settings...").format(name.title())
Tooltip(btn, text=hlp, wrap_length=200)
def _group_separator(self) -> None:
""" Place a group separator """
separator = ttk.Separator(self._btn_frame, orient="vertical")
separator.pack(padx=(2, 1), fill=tk.Y, side=tk.LEFT)
def _section_separator(self):
def _section_separator(self) -> None:
""" Place a section separator """
frame = ttk.Frame(self)
frame.pack(side=tk.BOTTOM, fill=tk.X)
separator = ttk.Separator(frame, orient="horizontal")

Binary file not shown.

View file

@ -0,0 +1,155 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: faceswap.spanish\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-07 13:54+0100\n"
"PO-Revision-Date: 2023-06-07 14:11+0100\n"
"Last-Translator: \n"
"Language-Team: tokafondo\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.3.1\n"
#: lib/gui/menu.py:37
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Guías y foro"
#: lib/gui/menu.py:38
msgid "Patreon - Support this project"
msgstr "Patreon - Apoya este proyecto"
#: lib/gui/menu.py:39
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - El servidor de Discord de FaceSwap"
#: lib/gui/menu.py:40
msgid "Github - Our Source Code"
msgstr "Github - Nuestro código fuente"
#: lib/gui/menu.py:60
msgid "File"
msgstr ""
#: lib/gui/menu.py:61
msgid "Settings"
msgstr ""
#: lib/gui/menu.py:62
msgid "Help"
msgstr ""
#: lib/gui/menu.py:85
msgid "Configure Settings..."
msgstr ""
#: lib/gui/menu.py:116
msgid "New Project..."
msgstr ""
#: lib/gui/menu.py:121
msgid "Open Project..."
msgstr ""
#: lib/gui/menu.py:126
msgid "Save Project"
msgstr ""
#: lib/gui/menu.py:131
msgid "Save Project as..."
msgstr ""
#: lib/gui/menu.py:136
msgid "Reload Project from Disk"
msgstr ""
#: lib/gui/menu.py:141
msgid "Close Project"
msgstr ""
#: lib/gui/menu.py:147
msgid "Open Task..."
msgstr ""
#: lib/gui/menu.py:154
msgid "Open recent"
msgstr ""
#: lib/gui/menu.py:156
msgid "Quit"
msgstr ""
#: lib/gui/menu.py:211
msgid "{} Task"
msgstr ""
#: lib/gui/menu.py:223
msgid "Clear recent files"
msgstr ""
#: lib/gui/menu.py:391
msgid "Check for updates..."
msgstr ""
#: lib/gui/menu.py:394
msgid "Update Faceswap..."
msgstr ""
#: lib/gui/menu.py:398
msgid "Switch Branch"
msgstr ""
#: lib/gui/menu.py:401
msgid "Resources"
msgstr ""
#: lib/gui/menu.py:404
msgid "Output System Information"
msgstr ""
#: lib/gui/menu.py:589
msgid "currently selected Task"
msgstr "tarea actualmente seleccionada"
#: lib/gui/menu.py:589
msgid "Project"
msgstr "Proyecto"
#: lib/gui/menu.py:591
msgid "Reload {} from disk"
msgstr "Recargar {} del disco"
#: lib/gui/menu.py:593
msgid "Create a new {}..."
msgstr "Crear un nuevo {}..."
#: lib/gui/menu.py:595
msgid "Reset {} to default"
msgstr "Reiniciar {} a los ajustes por defecto"
#: lib/gui/menu.py:597
msgid "Save {}"
msgstr "Guardar {}"
#: lib/gui/menu.py:599
msgid "Save {} as..."
msgstr "Guardar {} como..."
#: lib/gui/menu.py:603
msgid " from a task or project file"
msgstr " de un archivo de tarea o proyecto"
#: lib/gui/menu.py:604
msgid "Load {}..."
msgstr "Cargar {}..."
#: lib/gui/menu.py:659
msgid "Configure {} settings..."
msgstr "Configurar los ajustes de {}..."

View file

@ -6,16 +6,16 @@ msgid ""
msgstr ""
"Project-Id-Version: faceswap.spanish\n"
"POT-Creation-Date: 2021-03-22 18:37+0000\n"
"PO-Revision-Date: 2021-03-22 18:39+0000\n"
"PO-Revision-Date: 2023-06-07 14:12+0100\n"
"Last-Translator: \n"
"Language-Team: tokafondo\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.4.2\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.3.1\n"
#: lib/gui/command.py:184
msgid "Output command line options to the console"
@ -129,62 +129,6 @@ msgstr "Grabar {} a un fichero"
msgid "Enable or disable {} display"
msgstr "Activar o desactivar la muestra de {}"
#: lib/gui/menu.py:32
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Guías y foro"
#: lib/gui/menu.py:33
msgid "Patreon - Support this project"
msgstr "Patreon - Apoya este proyecto"
#: lib/gui/menu.py:34
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - El servidor de Discord de FaceSwap"
#: lib/gui/menu.py:35
msgid "Github - Our Source Code"
msgstr "Github - Nuestro código fuente"
#: lib/gui/menu.py:527
msgid "Configure {} settings..."
msgstr "Configurar los ajustes de {}..."
#: lib/gui/menu.py:535
msgid "Project"
msgstr "Proyecto"
#: lib/gui/menu.py:535
msgid "currently selected Task"
msgstr "tarea actualmente seleccionada"
#: lib/gui/menu.py:537
msgid "Reload {} from disk"
msgstr "Recargar {} del disco"
#: lib/gui/menu.py:539
msgid "Create a new {}..."
msgstr "Crear un nuevo {}..."
#: lib/gui/menu.py:541
msgid "Reset {} to default"
msgstr "Reiniciar {} a los ajustes por defecto"
#: lib/gui/menu.py:543
msgid "Save {}"
msgstr "Guardar {}"
#: lib/gui/menu.py:545
msgid "Save {} as..."
msgstr "Guardar {} como..."
#: lib/gui/menu.py:549
msgid " from a task or project file"
msgstr " de un archivo de tarea o proyecto"
#: lib/gui/menu.py:550
msgid "Load {}..."
msgstr "Cargar {}..."
#: lib/gui/popup_configure.py:209
msgid "Close without saving"
msgstr "Cerrar sin guardar"

154
locales/gui.menu.pot Normal file
View file

@ -0,0 +1,154 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-07 13:54+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ./lib/gui/menu.py:37
msgid "faceswap.dev - Guides and Forum"
msgstr ""
#: ./lib/gui/menu.py:38
msgid "Patreon - Support this project"
msgstr ""
#: ./lib/gui/menu.py:39
msgid "Discord - The FaceSwap Discord server"
msgstr ""
#: ./lib/gui/menu.py:40
msgid "Github - Our Source Code"
msgstr ""
#: ./lib/gui/menu.py:60
msgid "File"
msgstr ""
#: ./lib/gui/menu.py:61
msgid "Settings"
msgstr ""
#: ./lib/gui/menu.py:62
msgid "Help"
msgstr ""
#: ./lib/gui/menu.py:85
msgid "Configure Settings..."
msgstr ""
#: ./lib/gui/menu.py:116
msgid "New Project..."
msgstr ""
#: ./lib/gui/menu.py:121
msgid "Open Project..."
msgstr ""
#: ./lib/gui/menu.py:126
msgid "Save Project"
msgstr ""
#: ./lib/gui/menu.py:131
msgid "Save Project as..."
msgstr ""
#: ./lib/gui/menu.py:136
msgid "Reload Project from Disk"
msgstr ""
#: ./lib/gui/menu.py:141
msgid "Close Project"
msgstr ""
#: ./lib/gui/menu.py:147
msgid "Open Task..."
msgstr ""
#: ./lib/gui/menu.py:154
msgid "Open recent"
msgstr ""
#: ./lib/gui/menu.py:156
msgid "Quit"
msgstr ""
#: ./lib/gui/menu.py:211
msgid "{} Task"
msgstr ""
#: ./lib/gui/menu.py:223
msgid "Clear recent files"
msgstr ""
#: ./lib/gui/menu.py:391
msgid "Check for updates..."
msgstr ""
#: ./lib/gui/menu.py:394
msgid "Update Faceswap..."
msgstr ""
#: ./lib/gui/menu.py:398
msgid "Switch Branch"
msgstr ""
#: ./lib/gui/menu.py:401
msgid "Resources"
msgstr ""
#: ./lib/gui/menu.py:404
msgid "Output System Information"
msgstr ""
#: ./lib/gui/menu.py:589
msgid "currently selected Task"
msgstr ""
#: ./lib/gui/menu.py:589
msgid "Project"
msgstr ""
#: ./lib/gui/menu.py:591
msgid "Reload {} from disk"
msgstr ""
#: ./lib/gui/menu.py:593
msgid "Create a new {}..."
msgstr ""
#: ./lib/gui/menu.py:595
msgid "Reset {} to default"
msgstr ""
#: ./lib/gui/menu.py:597
msgid "Save {}"
msgstr ""
#: ./lib/gui/menu.py:599
msgid "Save {} as..."
msgstr ""
#: ./lib/gui/menu.py:603
msgid " from a task or project file"
msgstr ""
#: ./lib/gui/menu.py:604
msgid "Load {}..."
msgstr ""
#: ./lib/gui/menu.py:659
msgid "Configure {} settings..."
msgstr ""

View file

@ -119,62 +119,6 @@ msgstr ""
msgid "Enable or disable {} display"
msgstr ""
#: ./lib/gui/menu.py:32
msgid "faceswap.dev - Guides and Forum"
msgstr ""
#: ./lib/gui/menu.py:33
msgid "Patreon - Support this project"
msgstr ""
#: ./lib/gui/menu.py:34
msgid "Discord - The FaceSwap Discord server"
msgstr ""
#: ./lib/gui/menu.py:35
msgid "Github - Our Source Code"
msgstr ""
#: ./lib/gui/menu.py:527
msgid "Configure {} settings..."
msgstr ""
#: ./lib/gui/menu.py:535
msgid "Project"
msgstr ""
#: ./lib/gui/menu.py:535
msgid "currently selected Task"
msgstr ""
#: ./lib/gui/menu.py:537
msgid "Reload {} from disk"
msgstr ""
#: ./lib/gui/menu.py:539
msgid "Create a new {}..."
msgstr ""
#: ./lib/gui/menu.py:541
msgid "Reset {} to default"
msgstr ""
#: ./lib/gui/menu.py:543
msgid "Save {}"
msgstr ""
#: ./lib/gui/menu.py:545
msgid "Save {} as..."
msgstr ""
#: ./lib/gui/menu.py:549
msgid " from a task or project file"
msgstr ""
#: ./lib/gui/menu.py:550
msgid "Load {}..."
msgstr ""
#: ./lib/gui/popup_configure.py:209
msgid "Close without saving"
msgstr ""

Binary file not shown.

View file

@ -0,0 +1,155 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-07 13:54+0100\n"
"PO-Revision-Date: 2023-06-07 14:11+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ko_KR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.3.1\n"
#: lib/gui/menu.py:37
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Guides and Forum"
#: lib/gui/menu.py:38
msgid "Patreon - Support this project"
msgstr "Patreon - Support this project"
#: lib/gui/menu.py:39
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - The FaceSwap Discord server"
#: lib/gui/menu.py:40
msgid "Github - Our Source Code"
msgstr "Github - Our Source Code"
#: lib/gui/menu.py:60
msgid "File"
msgstr ""
#: lib/gui/menu.py:61
msgid "Settings"
msgstr ""
#: lib/gui/menu.py:62
msgid "Help"
msgstr ""
#: lib/gui/menu.py:85
msgid "Configure Settings..."
msgstr ""
#: lib/gui/menu.py:116
msgid "New Project..."
msgstr ""
#: lib/gui/menu.py:121
msgid "Open Project..."
msgstr ""
#: lib/gui/menu.py:126
msgid "Save Project"
msgstr ""
#: lib/gui/menu.py:131
msgid "Save Project as..."
msgstr ""
#: lib/gui/menu.py:136
msgid "Reload Project from Disk"
msgstr ""
#: lib/gui/menu.py:141
msgid "Close Project"
msgstr ""
#: lib/gui/menu.py:147
msgid "Open Task..."
msgstr ""
#: lib/gui/menu.py:154
msgid "Open recent"
msgstr ""
#: lib/gui/menu.py:156
msgid "Quit"
msgstr ""
#: lib/gui/menu.py:211
msgid "{} Task"
msgstr ""
#: lib/gui/menu.py:223
msgid "Clear recent files"
msgstr ""
#: lib/gui/menu.py:391
msgid "Check for updates..."
msgstr ""
#: lib/gui/menu.py:394
msgid "Update Faceswap..."
msgstr ""
#: lib/gui/menu.py:398
msgid "Switch Branch"
msgstr ""
#: lib/gui/menu.py:401
msgid "Resources"
msgstr ""
#: lib/gui/menu.py:404
msgid "Output System Information"
msgstr ""
#: lib/gui/menu.py:589
msgid "currently selected Task"
msgstr "현재 선택된 작업"
#: lib/gui/menu.py:589
msgid "Project"
msgstr "프로젝트"
#: lib/gui/menu.py:591
msgid "Reload {} from disk"
msgstr "디스크에서 {}를 다시 가져옵니다"
#: lib/gui/menu.py:593
msgid "Create a new {}..."
msgstr "새로운 {}를 만들기."
#: lib/gui/menu.py:595
msgid "Reset {} to default"
msgstr "{} 기본으로 재설정"
#: lib/gui/menu.py:597
msgid "Save {}"
msgstr "{} 저장"
#: lib/gui/menu.py:599
msgid "Save {} as..."
msgstr "{}를 다른 이름으로 저장."
#: lib/gui/menu.py:603
msgid " from a task or project file"
msgstr " 작업 또는 프로젝트 파일에서"
#: lib/gui/menu.py:604
msgid "Load {}..."
msgstr "{} 가져오기."
#: lib/gui/menu.py:659
msgid "Configure {} settings..."
msgstr "{} 세팅 설정하기."

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-03-22 18:37+0000\n"
"PO-Revision-Date: 2022-11-26 16:12+0900\n"
"PO-Revision-Date: 2023-06-07 14:13+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ko_KR\n"
@ -15,7 +15,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.2\n"
"X-Generator: Poedit 3.3.1\n"
#: lib/gui/command.py:184
msgid "Output command line options to the console"
@ -128,62 +128,6 @@ msgstr "{}(s)를 파일에 저장합니다"
msgid "Enable or disable {} display"
msgstr "{} display를 활성화 또는 비활성화"
#: lib/gui/menu.py:32
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Guides and Forum"
#: lib/gui/menu.py:33
msgid "Patreon - Support this project"
msgstr "Patreon - Support this project"
#: lib/gui/menu.py:34
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - The FaceSwap Discord server"
#: lib/gui/menu.py:35
msgid "Github - Our Source Code"
msgstr "Github - Our Source Code"
#: lib/gui/menu.py:527
msgid "Configure {} settings..."
msgstr "{} 세팅 설정하기."
#: lib/gui/menu.py:535
msgid "Project"
msgstr "프로젝트"
#: lib/gui/menu.py:535
msgid "currently selected Task"
msgstr "현재 선택된 작업"
#: lib/gui/menu.py:537
msgid "Reload {} from disk"
msgstr "디스크에서 {}를 다시 가져옵니다"
#: lib/gui/menu.py:539
msgid "Create a new {}..."
msgstr "새로운 {}를 만들기."
#: lib/gui/menu.py:541
msgid "Reset {} to default"
msgstr "{} 기본으로 재설정"
#: lib/gui/menu.py:543
msgid "Save {}"
msgstr "{} 저장"
#: lib/gui/menu.py:545
msgid "Save {} as..."
msgstr "{}를 다른 이름으로 저장."
#: lib/gui/menu.py:549
msgid " from a task or project file"
msgstr " 작업 또는 프로젝트 파일에서"
#: lib/gui/menu.py:550
msgid "Load {}..."
msgstr "{} 가져오기."
#: lib/gui/popup_configure.py:209
msgid "Close without saving"
msgstr "저장하지 않고 닫기"

Binary file not shown.

View file

@ -0,0 +1,156 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-07 13:54+0100\n"
"PO-Revision-Date: 2023-06-07 14:05+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.3.1\n"
#: ./lib/gui/menu.py:37
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Руководства и Форум"
#: ./lib/gui/menu.py:38
msgid "Patreon - Support this project"
msgstr "Patreon - Поддержите этот проект"
#: ./lib/gui/menu.py:39
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - Discord сервер Faceswap"
#: ./lib/gui/menu.py:40
msgid "Github - Our Source Code"
msgstr "Github - Наш исходный код"
#: ./lib/gui/menu.py:60
msgid "File"
msgstr ""
#: ./lib/gui/menu.py:61
msgid "Settings"
msgstr ""
#: ./lib/gui/menu.py:62
msgid "Help"
msgstr ""
#: ./lib/gui/menu.py:85
msgid "Configure Settings..."
msgstr ""
#: ./lib/gui/menu.py:116
msgid "New Project..."
msgstr ""
#: ./lib/gui/menu.py:121
msgid "Open Project..."
msgstr ""
#: ./lib/gui/menu.py:126
msgid "Save Project"
msgstr ""
#: ./lib/gui/menu.py:131
msgid "Save Project as..."
msgstr ""
#: ./lib/gui/menu.py:136
msgid "Reload Project from Disk"
msgstr ""
#: ./lib/gui/menu.py:141
msgid "Close Project"
msgstr ""
#: ./lib/gui/menu.py:147
msgid "Open Task..."
msgstr ""
#: ./lib/gui/menu.py:154
msgid "Open recent"
msgstr ""
#: ./lib/gui/menu.py:156
msgid "Quit"
msgstr ""
#: ./lib/gui/menu.py:211
msgid "{} Task"
msgstr ""
#: ./lib/gui/menu.py:223
msgid "Clear recent files"
msgstr ""
#: ./lib/gui/menu.py:391
msgid "Check for updates..."
msgstr ""
#: ./lib/gui/menu.py:394
msgid "Update Faceswap..."
msgstr ""
#: ./lib/gui/menu.py:398
msgid "Switch Branch"
msgstr ""
#: ./lib/gui/menu.py:401
msgid "Resources"
msgstr ""
#: ./lib/gui/menu.py:404
msgid "Output System Information"
msgstr ""
#: ./lib/gui/menu.py:589
msgid "currently selected Task"
msgstr "текущая выбранная задача"
#: ./lib/gui/menu.py:589
msgid "Project"
msgstr "Проект"
#: ./lib/gui/menu.py:591
msgid "Reload {} from disk"
msgstr "Перезагрузить {} из диска"
#: ./lib/gui/menu.py:593
msgid "Create a new {}..."
msgstr "Создать новый {}..."
#: ./lib/gui/menu.py:595
msgid "Reset {} to default"
msgstr "Сбросить {} по умолчанию"
#: ./lib/gui/menu.py:597
msgid "Save {}"
msgstr "Сохранить {}"
#: ./lib/gui/menu.py:599
msgid "Save {} as..."
msgstr "Сохранить {} как..."
#: ./lib/gui/menu.py:603
msgid " from a task or project file"
msgstr " из файла задачи или проекта"
#: ./lib/gui/menu.py:604
msgid "Load {}..."
msgstr "Загрузить {}..."
#: ./lib/gui/menu.py:659
msgid "Configure {} settings..."
msgstr "Настройка параметров {}..."

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-03-22 18:37+0000\n"
"PO-Revision-Date: 2023-04-11 16:07+0700\n"
"PO-Revision-Date: 2023-06-07 14:14+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ru\n"
@ -16,7 +16,7 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.2.2\n"
"X-Generator: Poedit 3.3.1\n"
#: lib/gui/command.py:184
msgid "Output command line options to the console"
@ -129,62 +129,6 @@ msgstr "Сохранить {}(ы) в файл"
msgid "Enable or disable {} display"
msgstr "Включить или выключить отображение {}"
#: lib/gui/menu.py:32
msgid "faceswap.dev - Guides and Forum"
msgstr "faceswap.dev - Руководства и Форум"
#: lib/gui/menu.py:33
msgid "Patreon - Support this project"
msgstr "Patreon - Поддержите этот проект"
#: lib/gui/menu.py:34
msgid "Discord - The FaceSwap Discord server"
msgstr "Discord - Discord сервер Faceswap"
#: lib/gui/menu.py:35
msgid "Github - Our Source Code"
msgstr "Github - Наш исходный код"
#: lib/gui/menu.py:527
msgid "Configure {} settings..."
msgstr "Настройка параметров {}..."
#: lib/gui/menu.py:535
msgid "Project"
msgstr "Проект"
#: lib/gui/menu.py:535
msgid "currently selected Task"
msgstr "текущая выбранная задача"
#: lib/gui/menu.py:537
msgid "Reload {} from disk"
msgstr "Перезагрузить {} из диска"
#: lib/gui/menu.py:539
msgid "Create a new {}..."
msgstr "Создать новый {}..."
#: lib/gui/menu.py:541
msgid "Reset {} to default"
msgstr "Сбросить {} по умолчанию"
#: lib/gui/menu.py:543
msgid "Save {}"
msgstr "Сохранить {}"
#: lib/gui/menu.py:545
msgid "Save {} as..."
msgstr "Сохранить {} как..."
#: lib/gui/menu.py:549
msgid " from a task or project file"
msgstr " из файла задачи или проекта"
#: lib/gui/menu.py:550
msgid "Load {}..."
msgstr "Загрузить {}..."
#: lib/gui/popup_configure.py:209
msgid "Close without saving"
msgstr "Закрыть без сохранения"