diff --git a/src/UI_PY.ps1 b/src/UI_PY.ps1 index 097c7cb..708ef0d 100644 --- a/src/UI_PY.ps1 +++ b/src/UI_PY.ps1 @@ -3,7 +3,7 @@ $PYDir = ".\windows\design" $TS_Dir = "..\languages" $QM_Dir = ".\resources\translations" $PY_Dir = ".\windows" -$Languages = "german", "japanese", "filipino", "russian" +$Languages = "en", "de", "ja", "fil", "ru", "tr" Set-Location $(Split-Path -Path $MyInvocation.MyCommand.Path) # Get Files $FileNames = New-Object Collections.Generic.List[String] @@ -46,10 +46,15 @@ for () { $files += "$UIDir\$basename.ui " $files += "$PY_Dir\$basename.py " } - + Foreach ($language in $Languages) { cmd.exe /c "pyside2-lupdate -noobsolete $files -ts $TS_Dir/$language.qt.ts" - cmd.exe /c "lrelease -silent -removeidentical $TS_Dir/$language.qt.ts -qm $QM_Dir/$language.qm" + New-Item -ItemType Directory -Force -Path $QM_Dir/$language | Out-Null + New-Item -ItemType Directory -Force -Path $QM_Dir/$language/infos | Out-Null + if ($language -ne "en") { + Copy-Item -Path "$QM_Dir/en/infos/*" -Destination "$QM_Dir/$language/infos" -PassThru + } + cmd.exe /c "lrelease -silent -removeidentical $TS_Dir/$language.qt.ts -qm $QM_Dir/$language/$language.qm" } $ChangedFiles.Clear() Write-Output "Done!" diff --git a/src/app.py b/src/app.py index 7804887..5bf3836 100644 --- a/src/app.py +++ b/src/app.py @@ -10,6 +10,7 @@ from PySide2.QtGui import Qt # -Root imports- from .resources.resources_manager import (ResourcePaths, Logger) from .inference import converter +from .translator import Translator from . import constants as const # -Other- # Logging @@ -63,12 +64,13 @@ class CustomApplication(QtWidgets.QApplication): self.threadpool = QtCore.QThreadPool(self) # -Load Windows- # Workaround for circular dependency - from .windows import (mainwindow, settingswindow, presetseditorwindow) + from .windows import (mainwindow, settingswindow, presetseditorwindow, infowindow) # Collection of windows self.windows: Dict[str, QtWidgets.QWidget] = { 'main': mainwindow.MainWindow(self), 'settings': settingswindow.SettingsWindow(self), 'presetsEditor': presetseditorwindow.PresetsEditorWindow(self), + 'info': infowindow.InfoWindow(self), } self.mainWindow = self.windows['main'] self.settingsWindow = self.windows['settings'] @@ -126,9 +128,9 @@ class CustomApplication(QtWidgets.QApplication): # -After- # Load language - language = QtCore.QLocale(self.settings.value('user/language', - const.DEFAULT_SETTINGS['language'])).language() - self.translator.load_language(language) + lang_code = self.settings.value('user/language', + const.DEFAULT_SETTINGS['language']) + self.translator.load_language(self.translator.LANGUAGES[lang_code]) # nopep8 # Load Theme theme = self.settings.value('user/theme', const.DEFAULT_SETTINGS['theme']) @@ -221,7 +223,7 @@ class CustomApplication(QtWidgets.QApplication): self.settings.setValue('user/exportDirectory', self.windows['settings'].exportDirectory) self.settings.setValue('user/language', - self.translator.loaded_language) + self.translator.loaded_language.code) self.settings.setValue('user/inputPaths', self.windows['main'].inputPaths) self.settings.setValue('user/inputsDirectory', @@ -266,78 +268,6 @@ class CustomApplication(QtWidgets.QApplication): self.logger.info('--- Done! ---') -class Translator: - """Localizer for the application - - Manages the languages for the applications - - Args: - loaded_language (str): - Currently loaded language in the application. To change, run method load_language. - """ - - def __init__(self, app: CustomApplication): - self.app = app - self.logger = app.logger - self.loaded_language: str - self._translator = QtCore.QTranslator(self.app) - - def load_language(self, language: QtCore.QLocale.Language = QtCore.QLocale.English) -> bool: - """Load a language on the application - - Note: - language arg info: - If the language given is not supported, a warning message will be reported to the logger - and the language will be set to english - - Args: - language (QtCore.QLocale.Language, optional): Language to load. Defaults to English. - - Returns: - bool: Whether the applications language was successfully changed to the given language - """ - language_str = QtCore.QLocale.languageToString(language).lower() - self.logger.info(f'Translating to "{language_str.capitalize()}"...', - indent_forwards=True) - # Get path where translation file should be - translation_path = os.path.join(self.app.resources.localizationDir, f'{language_str}.qm') - if (not os.path.isfile(translation_path) and - language != QtCore.QLocale.English): - # Translation file does not exist - # Load default language (english) - self.logger.warning(f'Translation file does not exist! Switching to English. Language: {language_str}') - self.logger.indent_backwards() - self.load_language() - return False - # get language name to later store in settings - self.loaded_language = QtCore.QLocale(language).name() - # Load language - if language == QtCore.QLocale.English: - # English is base language so remove translator - self.app.removeTranslator(self._translator) - else: - self._translator.load(translation_path) - self.app.installTranslator(self._translator) - - # -Windows are initialized- - # Update translation on all windows - for window in self.app.windows.values(): - window.update_translation() - # Update settings window - for button in self.app.windows['settings'].ui.frame_languages.findChildren(QtWidgets.QPushButton): - language_str = QtCore.QLocale.languageToString(language).lower() - button_name = f'pushButton_{language_str}' - if button.objectName() == button_name: - # Language found - button.setChecked(True) - else: - # Not selected language - button.setChecked(False) - - self.logger.indent_backwards() - return True - - class ThemeManager: """Theme Manager for the application diff --git a/src/constants.py b/src/constants.py index e9e354c..79e6551 100644 --- a/src/constants.py +++ b/src/constants.py @@ -6,6 +6,7 @@ Store Appliation info and default data from PySide2 import QtCore # -Root imports- from .inference import converter +from .translator import Translator from collections import OrderedDict import torch @@ -43,7 +44,7 @@ DEFAULT_SETTINGS = { # Export path (Default: desktop) 'exportDirectory': QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DesktopLocation), # Language in format {language}_{country} (Default: system language) - 'language': QtCore.QLocale.system().name(), + 'language': Translator.SUPPORTED_LANGUAGES[QtCore.QLocale.system().language().name.decode('utf-8')], # Presets for seperations 'presets': [ ['ALL', { diff --git a/src/inference/lib/layers.py b/src/inference/lib/layers.py index 5f1ab45..6accbdf 100644 --- a/src/inference/lib/layers.py +++ b/src/inference/lib/layers.py @@ -5,19 +5,6 @@ import torch.nn.functional as F from . import spec_utils -model_size_converter = { - '33966KB': { - - }, - '123821KB': { - - }, - '129605KB': { - - } -} - - class Conv2DBNActiv(nn.Module): def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU): diff --git a/src/infos.py b/src/infos.py deleted file mode 100644 index 00a8d70..0000000 --- a/src/infos.py +++ /dev/null @@ -1,2 +0,0 @@ -CONVERTER_TITLE = "Conversion Section" -CONVERTER_TEXT = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." diff --git a/src/resources/resources_manager.py b/src/resources/resources_manager.py index 27666c8..e1e66b5 100644 --- a/src/resources/resources_manager.py +++ b/src/resources/resources_manager.py @@ -52,14 +52,6 @@ class ResourcePaths: upload = os.path.join(abs_path, IMAGE_FOLDER, 'upload.png') download = os.path.join(abs_path, IMAGE_FOLDER, 'download.png') - class flags: - _FLAG_FOLDER = 'flags' - english = os.path.join(abs_path, IMAGE_FOLDER, _FLAG_FOLDER, 'english.png') - german = os.path.join(abs_path, IMAGE_FOLDER, _FLAG_FOLDER, 'german.png') - japanese = os.path.join(abs_path, IMAGE_FOLDER, _FLAG_FOLDER, 'japan.png') - filipino = os.path.join(abs_path, IMAGE_FOLDER, _FLAG_FOLDER, 'filipino.png') - turkish = os.path.join(abs_path, IMAGE_FOLDER, _FLAG_FOLDER, 'turkish.png') - class themes: dark_path = os.path.join(abs_path, THEMES_FOLDER, 'dark.qss') light_path = os.path.join(abs_path, THEMES_FOLDER, 'light.qss') diff --git a/src/resources/themes/dark.qss b/src/resources/themes/dark.qss index c7235b7..b1732d8 100644 --- a/src/resources/themes/dark.qss +++ b/src/resources/themes/dark.qss @@ -146,9 +146,12 @@ QListWidget#listWidget_presets::item:selected { } /* Command Line*/ QTextBrowser { + border: none; + background-color: #2d2d2d; +} +QTextBrowser#textBrowser_command { font: 8pt "Courier"; color: #EEE; - background-color: #2d2d2d; } /* Audio Player */ QLabel[audioPlayer="true"] { diff --git a/src/resources/translations/de/de.qm b/src/resources/translations/de/de.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/de/de.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/images/flags/german.png b/src/resources/translations/de/flag.png similarity index 100% rename from src/resources/images/flags/german.png rename to src/resources/translations/de/flag.png diff --git a/src/resources/translations/de/infos/settings_conversion.md b/src/resources/translations/de/infos/settings_conversion.md new file mode 100644 index 0000000..36ffaed --- /dev/null +++ b/src/resources/translations/de/infos/settings_conversion.md @@ -0,0 +1 @@ +German \ No newline at end of file diff --git a/src/resources/translations/en/en.qm b/src/resources/translations/en/en.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/en/en.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/images/flags/english.png b/src/resources/translations/en/flag.png similarity index 100% rename from src/resources/images/flags/english.png rename to src/resources/translations/en/flag.png diff --git a/src/resources/translations/en/infos/settings_conversion.md b/src/resources/translations/en/infos/settings_conversion.md new file mode 100644 index 0000000..f99c6fa --- /dev/null +++ b/src/resources/translations/en/infos/settings_conversion.md @@ -0,0 +1,11 @@ +# Ultimate Vocal Remover GUI v5.0.0 + +## About + +This application is a heavily modified version of the vocal remover AI created and posted by GitHub user [tsurumeso](https://github.com/tsurumeso). You can find tsurumeso's original command line version [here](https://github.com/tsurumeso/vocal-remover). The official v5 GUI is still under developement and will be released some time in Q3 2021. The v5 beta is available via command line only at this time. You can test it [here](https://github.com/Anjok07/ultimatevocalremovergui/tree/v5-beta-cml). + +- **The Developers** + - [Anjok07](https://github.com/anjok07)- Model collaborator & UVR developer. + - [aufr33](https://github.com/aufr33) - Model collaborator & fellow UVR developer. This project wouldn't be what it is without your help, thank you for your continued support! + - [DilanBoskan](https://github.com/DilanBoskan) - The main UVR GUI developer. Thank you for helping bring the GUI to life! Your hard work and continued support is greatly appreciated. + - [tsurumeso](https://github.com/tsurumeso) - The engineer who authored the original AI code. Thank you for the hard work and dedication you put into the AI code UVR is built on! diff --git a/src/resources/translations/fil/fil.qm b/src/resources/translations/fil/fil.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/fil/fil.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/images/flags/filipino.png b/src/resources/translations/fil/flag.png similarity index 100% rename from src/resources/images/flags/filipino.png rename to src/resources/translations/fil/flag.png diff --git a/src/resources/translations/fil/infos/settings_conversion.md b/src/resources/translations/fil/infos/settings_conversion.md new file mode 100644 index 0000000..1cbaecd --- /dev/null +++ b/src/resources/translations/fil/infos/settings_conversion.md @@ -0,0 +1 @@ +Filipino \ No newline at end of file diff --git a/src/resources/translations/filipino.qm b/src/resources/translations/filipino.qm deleted file mode 100644 index 4740816..0000000 Binary files a/src/resources/translations/filipino.qm and /dev/null differ diff --git a/src/resources/translations/german.qm b/src/resources/translations/german.qm deleted file mode 100644 index 17551f3..0000000 Binary files a/src/resources/translations/german.qm and /dev/null differ diff --git a/src/resources/images/flags/japan.png b/src/resources/translations/ja/flag.png similarity index 100% rename from src/resources/images/flags/japan.png rename to src/resources/translations/ja/flag.png diff --git a/src/resources/translations/ja/infos/settings_conversion.md b/src/resources/translations/ja/infos/settings_conversion.md new file mode 100644 index 0000000..dc09008 --- /dev/null +++ b/src/resources/translations/ja/infos/settings_conversion.md @@ -0,0 +1 @@ +Japanese \ No newline at end of file diff --git a/src/resources/translations/ja/ja.qm b/src/resources/translations/ja/ja.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/ja/ja.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/translations/japanese.qm b/src/resources/translations/japanese.qm deleted file mode 100644 index 1621160..0000000 Binary files a/src/resources/translations/japanese.qm and /dev/null differ diff --git a/src/resources/translations/ru/infos/settings_conversion.md b/src/resources/translations/ru/infos/settings_conversion.md new file mode 100644 index 0000000..9814eb5 --- /dev/null +++ b/src/resources/translations/ru/infos/settings_conversion.md @@ -0,0 +1 @@ +Russian \ No newline at end of file diff --git a/src/resources/translations/ru/ru.qm b/src/resources/translations/ru/ru.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/ru/ru.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/translations/russian.qm b/src/resources/translations/russian.qm deleted file mode 100644 index 7431612..0000000 Binary files a/src/resources/translations/russian.qm and /dev/null differ diff --git a/src/resources/images/flags/turkish.png b/src/resources/translations/tr/flag.png similarity index 100% rename from src/resources/images/flags/turkish.png rename to src/resources/translations/tr/flag.png diff --git a/src/resources/translations/tr/infos/settings_conversion.md b/src/resources/translations/tr/infos/settings_conversion.md new file mode 100644 index 0000000..6c1c743 --- /dev/null +++ b/src/resources/translations/tr/infos/settings_conversion.md @@ -0,0 +1,2 @@ +Turkish +Turkish \ No newline at end of file diff --git a/src/resources/translations/tr/tr.qm b/src/resources/translations/tr/tr.qm new file mode 100644 index 0000000..be651ee --- /dev/null +++ b/src/resources/translations/tr/tr.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/src/resources/user/settings.ini b/src/resources/user/settings.ini index 8273222..da854f9 100644 --- a/src/resources/user/settings.ini +++ b/src/resources/user/settings.ini @@ -1,18 +1,18 @@ [settingswindow] -size=@Size(940 483) -pos=@Point(133 193) +size=@Size(940 551) +pos=@Point(371 253) checkBox_gpuConversion=false -checkBox_tta=false +checkBox_tta=true checkBox_modelFolder=false checkBox_outputImage=false -checkBox_postProcess=false -checkBox_deepExtraction=false +checkBox_postProcess=true +checkBox_deepExtraction=true comboBox_instrumental=MGM-v5-2Band-32000-BETA1 comboBox_vocal= -comboBox_winSize=352 -doubleSpinBox_aggressiveness=-0.1 +comboBox_winSize=320 +doubleSpinBox_aggressiveness=0.02 comboBox_highEndProcess=Mirroring -comboBox_presets=NONE +comboBox_presets=Custom checkBox_notifiyOnFinish=false checkBox_notifyUpdates=true checkBox_settingsStartup=false @@ -23,17 +23,22 @@ comboBox_command=Off checkBox_autoSaveInstrumentals=true checkBox_autoSaveVocals=true -[mainwindow] -size=@Size(947 559) -pos=@Point(185 175) -isMaximized=false - [user] exportDirectory=C:/Users/boska/Desktop -language=en_US -inputPaths=C:/Users/boska/Desktop/BagsdreedBoys.png +language=en +inputPaths=@Invalid() inputsDirectory=C:/Users/boska/Desktop presets=@Variant(\0\0\0\x7f\0\0\0\x18PySide::PyObjectWrapper\0\0\0\0\xc3\x80\x3X\x3\0\0\0\x41LLq\0}q\x1(X\xe\0\0\0\x61ggressivenessq\x2G?\xb9\x99\x99\x99\x99\x99\x9aX\xe\0\0\0\x64\x65\x65pExtractionq\x3\x88X\xe\0\0\0highEndProcessq\x4X\x6\0\0\0\x42ypassq\x5X\v\0\0\0modelFolderq\x6\x88X\v\0\0\0outputImageq\a\x88X\v\0\0\0postProcessq\b\x88X\x3\0\0\0ttaq\t\x88X\n\0\0\0windowSizeq\nM\0\x4u\x86q\v.), @Variant(\0\0\0\x7f\0\0\0\x18PySide::PyObjectWrapper\0\0\0\0\xc7\x80\x3X\x4\0\0\0NONEq\0}q\x1(X\xe\0\0\0\x61ggressivenessq\x2G\xbf\xb9\x99\x99\x99\x99\x99\x9aX\xe\0\0\0\x64\x65\x65pExtractionq\x3\x89X\xe\0\0\0highEndProcessq\x4X\t\0\0\0Mirroringq\x5X\v\0\0\0modelFolderq\x6\x89X\v\0\0\0outputImageq\a\x89X\v\0\0\0postProcessq\b\x89X\x3\0\0\0ttaq\t\x89X\n\0\0\0windowSizeq\nM`\x1u\x86q\v.) presets_loadDir=C:/Users/boska/Desktop presets_saveDir=C:/Users/boska/Desktop theme=dark + +[mainwindow] +size=@Size(946 559) +pos=@Point(486 260) +isMaximized=false + +[infowindow] +size=@Size(555 462) +pos=@Point(1316 273) +isMaximized=false diff --git a/src/translator.py b/src/translator.py new file mode 100644 index 0000000..ce90e7e --- /dev/null +++ b/src/translator.py @@ -0,0 +1,103 @@ +""" +Translator Class File +""" +# pylint: disable=no-name-in-module, import-error +# -GUI- +from typing import DefaultDict, Dict +from PySide2 import QtWidgets +from PySide2 import QtCore +from PySide2 import QtGui +import PySide2 +from PySide2.QtGui import Qt +# -Root imports- +# None +# -Other- +# System +import os +import sys + + +class Language: + """ + Single language in the UVR System + """ + + def __init__(self, name: str, code: str, folder_path: str): + self.name = name + self.code = code + self.folder_path = folder_path + self.flag_path = os.path.join(folder_path, 'flag.png') + self.qm_path = os.path.join(folder_path, f'{code}.qm') + self.load_infos() + + def load_infos(self): + with open(os.path.join(self.folder_path, 'infos', 'settings_conversion.md')) as f: + self.settings_conversion = "\n".join(f.readlines()) + + +class Translator: + """Localizer for the application + + Manages the languages for the applications + + Args: + loaded_language (str): + Currently loaded language in the application. To change, run method load_language. + """ + SUPPORTED_LANGUAGES = DefaultDict(lambda: "en", **{ + 'english': 'en', + 'german': 'de', + 'japanese': 'ja', + 'filipino': 'fil', + 'russian': 'ru', + 'turkish': 'tr', + }) + LANGUAGES: Dict[str, Language] = {} + + def __init__(self, app): + self.app = app + self.logger = app.logger + self.loaded_language: Language + self._translator = QtCore.QTranslator(self.app) + + for lang_name, lang_code in self.SUPPORTED_LANGUAGES.items(): + self.LANGUAGES[lang_code] = Language(lang_name, lang_code, + os.path.join(self.app.resources.localizationDir, lang_code)) + + def load_language(self, language: Language) -> bool: + """Load a language on the application + + Note: + language arg info: + If the language given is not supported, a warning message will be reported to the logger + and the language will be set to english + + Args: + language (QtCore.QLocale.Language, optional): Language to load. Defaults to English. + + Returns: + bool: Whether the applications language was successfully changed to the given language + """ + self.logger.info(f'Translating to "{language.name}"...', + indent_forwards=True) + # Load language + self._translator.load(language.qm_path) + self.app.installTranslator(self._translator) + + # -Windows are initialized- + # Update translation on all windows + for window in self.app.windows.values(): + window.update_translation() + # Update settings window + for button in self.app.windows['settings'].ui.frame_languages.findChildren(QtWidgets.QPushButton): + button_name = f'pushButton_{language.code}' + if button.objectName() == button_name: + # Language found + button.setChecked(True) + else: + # Not selected language + button.setChecked(False) + + self.logger.indent_backwards() + self.loaded_language = language + return True diff --git a/src/windows/design/infowindow_ui.py b/src/windows/design/infowindow_ui.py new file mode 100644 index 0000000..80e85ff --- /dev/null +++ b/src/windows/design/infowindow_ui.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +################################################################################ +# Form generated from reading UI file 'infowindow.ui' +## +# Created by: Qt User Interface Compiler version 5.15.2 +## +# WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import * +from PySide2.QtGui import * +from PySide2.QtWidgets import * + + +class Ui_InfoWindow(object): + def setupUi(self, InfoWindow): + if not InfoWindow.objectName(): + InfoWindow.setObjectName(u"InfoWindow") + InfoWindow.resize(450, 357) + self.verticalLayout = QVBoxLayout(InfoWindow) + self.verticalLayout.setSpacing(0) + self.verticalLayout.setObjectName(u"verticalLayout") + self.verticalLayout.setContentsMargins(5, 0, 0, 0) + self.textEdit = QTextBrowser(InfoWindow) + self.textEdit.setObjectName(u"textEdit") + self.textEdit.setUndoRedoEnabled(False) + self.textEdit.setReadOnly(True) + self.textEdit.setHtml(u"\n" + "
\n" + "