Merge pull request #680 from bkmeneguello/Languages-GUI

Adds language selector to preferences
This commit is contained in:
Veronica Berglyd Olsen
2021-02-17 10:04:41 +01:00
committed by GitHub
9 changed files with 80 additions and 452 deletions
+2
View File
@@ -7,6 +7,8 @@
*.egg-info
setup.iss
novelwriter.desktop
i18n/*.qm
i18n/*.qph
# Documentation
/docs/build/
BIN
View File
Binary file not shown.
-447
View File
@@ -1,447 +0,0 @@
<!DOCTYPE QPH>
<QPH sourcelanguage="en" language="pt">
<phrase>
<source>Point of View</source>
<target>Ponto de Vista</target>
</phrase>
<phrase>
<source>Characters</source>
<target>Personagens</target>
</phrase>
<phrase>
<source>Plot</source>
<target>Enredo</target>
</phrase>
<phrase>
<source>Timeline</source>
<target>Linha do Tempo</target>
</phrase>
<phrase>
<source>Locations</source>
<target>Lugares</target>
</phrase>
<phrase>
<source>Objects</source>
<target>Objetos</target>
</phrase>
<phrase>
<source>Entities</source>
<target>Entidades</target>
</phrase>
<phrase>
<source>None</source>
<target>Nenhum</target>
</phrase>
<phrase>
<source>Novel</source>
<target>Livro</target>
</phrase>
<phrase>
<source>Entity</source>
<target>Entidade</target>
</phrase>
<phrase>
<source>Outtakes</source>
<target>Removidos</target>
</phrase>
<phrase>
<source>Trash</source>
<target>Lixeira</target>
</phrase>
<phrase>
<source>Title Page</source>
<target>Página de Título</target>
</phrase>
<phrase>
<source>Book</source>
<target>Livro</target>
</phrase>
<phrase>
<source>Plain Page</source>
<target>Página</target>
</phrase>
<phrase>
<source>Partition</source>
<target>Partição</target>
</phrase>
<phrase>
<source>Unnumbered</source>
<target>Sem Numeração</target>
</phrase>
<phrase>
<source>Scene</source>
<target>Cena</target>
</phrase>
<phrase>
<source>Note</source>
<target>Nota</target>
</phrase>
<phrase>
<source>Title</source>
<target>Título</target>
</phrase>
<phrase>
<source>Level</source>
<target>Nível</target>
</phrase>
<phrase>
<source>Document</source>
<target>Documento</target>
</phrase>
<phrase>
<source>Line</source>
<target>Linha</target>
</phrase>
<phrase>
<source>Chars</source>
<target>Caracteres</target>
</phrase>
<phrase>
<source>Words</source>
<target>Palavras</target>
</phrase>
<phrase>
<source>Synopsis</source>
<target>Sinopse</target>
</phrase>
<phrase>
<source>About</source>
<target>Sobre</target>
</phrase>
<phrase>
<source>Release</source>
<target>Versões</target>
</phrase>
<phrase>
<source>About novelWriter</source>
<target>Sobre o novelWriter</target>
</phrase>
<phrase>
<source>Credits</source>
<target>Créditos</target>
</phrase>
<phrase>
<source>Author</source>
<target>Autor</target>
</phrase>
<phrase>
<source>Credit</source>
<target>Créditos</target>
</phrase>
<phrase>
<source>License</source>
<target>Licença</target>
</phrase>
<phrase>
<source>Theme</source>
<target>Tema</target>
</phrase>
<phrase>
<source>Icons</source>
<target>Ícones</target>
</phrase>
<phrase>
<source>Syntax</source>
<target>Sintaxe</target>
</phrase>
<phrase>
<source>Website</source>
<target>Website</target>
</phrase>
<phrase>
<source>Chapter</source>
<target>Capítulo</target>
</phrase>
<phrase>
<source>Section</source>
<target>Seção</target>
</phrase>
<phrase>
<source>Font family</source>
<target>Família da fonte</target>
</phrase>
<phrase>
<source>Font size</source>
<target>Tamanho da fonte</target>
</phrase>
<phrase>
<source>Justify text</source>
<target>Texto justificado</target>
</phrase>
<phrase>
<source>Print</source>
<target>Imprimir</target>
</phrase>
<phrase>
<source>Build Project</source>
<target>Construir o Projeto</target>
</phrase>
<phrase>
<source>Save As</source>
<target>Salvar Como</target>
</phrase>
<phrase>
<source>Close</source>
<target>Fechar</target>
</phrase>
<phrase>
<source>Plain Text</source>
<target>Texto Simples</target>
</phrase>
<phrase>
<source>Plain HTML</source>
<target>HTML Simples</target>
</phrase>
<phrase>
<source>Save Document As</source>
<target>Salvar Documento Como</target>
</phrase>
<phrase>
<source>Unknown</source>
<target>Desconhecido</target>
</phrase>
<phrase>
<source>Look and Feel</source>
<target>Aparência</target>
</phrase>
<phrase>
<source>Project Backup</source>
<target>Cópia de Segurança</target>
</phrase>
<phrase>
<source>Path</source>
<target>Caminho</target>
</phrase>
<phrase>
<source>Status</source>
<target>Estado</target>
</phrase>
<phrase>
<source>Replace</source>
<target>Substituir</target>
</phrase>
<phrase>
<source>Search</source>
<target>Pesquisa</target>
</phrase>
<phrase>
<source>Handle</source>
<target>Referência</target>
</phrase>
<phrase>
<source>References</source>
<target>Referências</target>
</phrase>
<phrase>
<source>Label</source>
<target>Rótulo</target>
</phrase>
<phrase>
<source>Class</source>
<target>Classe</target>
</phrase>
<phrase>
<source>Layout</source>
<target>Leiaute</target>
</phrase>
<phrase>
<source> Characters</source>
<target>Caracteres</target>
</phrase>
<phrase>
<source>Editor</source>
<target>Editor</target>
</phrase>
<phrase>
<source>Project</source>
<target>Projeto</target>
</phrase>
<phrase>
<source>Provider</source>
<target>Provedor</target>
</phrase>
<phrase>
<source>unknown</source>
<target>desconhecido</target>
</phrase>
<phrase>
<source>Paragraphs</source>
<target>Parágrafos</target>
</phrase>
<phrase>
<source>Default</source>
<target>Padrão</target>
</phrase>
<phrase>
<source>Working title</source>
<target>Nome do projeto</target>
</phrase>
<phrase>
<source>Project path</source>
<target>Caminho do projeto</target>
</phrase>
<phrase>
<source>Project Stats</source>
<target>Estatíticas do Projeto</target>
</phrase>
<phrase>
<source>Folders</source>
<target>Diretórios</target>
</phrase>
<phrase>
<source>Documents</source>
<target>Documentos</target>
</phrase>
<phrase>
<source>Word count</source>
<target>Contagem de palavras</target>
</phrase>
<phrase>
<source>Keyword</source>
<target>Palavra-chave</target>
</phrase>
<phrase>
<source>New</source>
<target>Novo</target>
</phrase>
<phrase>
<source>Delete</source>
<target>Remover</target>
</phrase>
<phrase>
<source>Save</source>
<target>Salvar</target>
</phrase>
<phrase>
<source>Name</source>
<target>Nome</target>
</phrase>
<phrase>
<source>New Item</source>
<target>Novo Item</target>
</phrase>
<phrase>
<source>Last Opened</source>
<target>Aberto Pela Última Vez</target>
</phrase>
<phrase>
<source>Settings</source>
<target>Configurações</target>
</phrase>
<phrase>
<source>Details</source>
<target>Detalhes</target>
</phrase>
<phrase>
<source>Importance</source>
<target>Importância</target>
</phrase>
<phrase>
<source>Auto-Replace</source>
<target>Substituir automaticamente</target>
</phrase>
<phrase>
<source>Flag</source>
<target>Opção</target>
</phrase>
<phrase>
<source>Flags</source>
<target>Opções</target>
</phrase>
<phrase>
<source>(New Entry)</source>
<target></target>
</phrase>
<phrase>
<source>New File</source>
<target>Novo Arquivo</target>
</phrase>
<phrase>
<source>New Folder</source>
<target>Novo Diretório</target>
</phrase>
<phrase>
<source>Histogram</source>
<target>Histograma</target>
</phrase>
<phrase>
<source>Finished</source>
<target>Finalizado</target>
</phrase>
<phrase>
<source>Done</source>
<target>Pronto</target>
</phrase>
<phrase>
<source>Finish</source>
<target>Terminar</target>
</phrase>
<phrase>
<source>Auto-Replace</source>
<target>Substituição Automática</target>
</phrase>
<phrase>
<source>No Suggestions</source>
<target>Sem Sugestões</target>
</phrase>
<phrase>
<source>Browse</source>
<target>Procurar</target>
</phrase>
<phrase>
<source>Tag</source>
<target>Etiqueta</target>
</phrase>
<phrase>
<source>Draft</source>
<target>Rascunho</target>
</phrase>
<phrase>
<source>Minor</source>
<target>Menor</target>
</phrase>
<phrase>
<source>Major</source>
<target>Maior</target>
</phrase>
<phrase>
<source>Backup</source>
<target>Cópia de Segurança</target>
</phrase>
<phrase>
<source>Undo</source>
<target>Desfazer</target>
</phrase>
<phrase>
<source>Release</source>
<target>Lançamento</target>
</phrase>
<phrase>
<source>Pages</source>
<target>Páginas</target>
</phrase>
<phrase>
<source>Page</source>
<target>Página</target>
</phrase>
<phrase>
<source>Progress</source>
<target>Progresso</target>
</phrase>
<phrase>
<source>Chapters</source>
<target>Capítulos</target>
</phrase>
<phrase>
<source>Scenes</source>
<target>Cenas</target>
</phrase>
<phrase>
<source>Revisions</source>
<target>Revisões</target>
</phrase>
<phrase>
<source>seconds</source>
<target>segundos</target>
</phrase>
</QPH>
+19
View File
@@ -393,6 +393,25 @@ class Config:
return
def listLanguages(self):
"""List localisation files in the i18n folder. The default GUI
language 'en_GB' is British English.
"""
langList = {
"en_GB": QLocale("en_GB").nativeLanguageName().title()
}
for qmFile in os.listdir(self.nwLangPath):
if not os.path.isfile(os.path.join(self.nwLangPath, qmFile)):
continue
if not qmFile.startswith("nw_") or not qmFile.endswith(".qm"):
continue
qmLang = qmFile[3:-3]
qmName = QLocale(qmLang).nativeLanguageName().title()
if qmLang and qmName:
langList[qmLang] = qmName
return sorted(langList.items(), key=lambda x: x[0])
def loadConfig(self):
"""Load preferences from file and replace default settings.
"""
+22 -2
View File
@@ -137,10 +137,27 @@ class GuiPreferencesGeneral(QWidget):
# Look and Feel
# =============
self.mainForm.addGroupLabel(self.tr("Look and Feel"))
minWidth = self.mainConf.pxInt(200)
## Select Locale
self.guiLang = QComboBox()
self.guiLang.setMinimumWidth(minWidth)
self.theLangs = self.mainConf.listLanguages()
for lang, langName in self.theLangs:
self.guiLang.addItem(langName, lang)
langIdx = self.guiLang.findData(self.mainConf.guiLang)
if langIdx != -1:
self.guiLang.setCurrentIndex(langIdx)
self.mainForm.addRow(
self.tr("Main GUI language"),
self.guiLang,
self.tr("Changing this requires restarting novelWriter.")
)
## Select Theme
self.guiTheme = QComboBox()
self.guiTheme.setMinimumWidth(self.mainConf.pxInt(200))
self.guiTheme.setMinimumWidth(minWidth)
self.theThemes = self.theTheme.listThemes()
for themeDir, themeName in self.theThemes:
self.guiTheme.addItem(themeName, themeDir)
@@ -156,7 +173,7 @@ class GuiPreferencesGeneral(QWidget):
## Select Icon Theme
self.guiIcons = QComboBox()
self.guiIcons.setMinimumWidth(self.mainConf.pxInt(200))
self.guiIcons.setMinimumWidth(minWidth)
self.theIcons = self.theTheme.theIcons.listThemes()
for iconDir, iconName in self.theIcons:
self.guiIcons.addItem(iconName, iconDir)
@@ -240,6 +257,7 @@ class GuiPreferencesGeneral(QWidget):
def saveValues(self):
"""Save the values set for this tab.
"""
guiLang = self.guiLang.currentData()
guiTheme = self.guiTheme.currentData()
guiIcons = self.guiIcons.currentData()
guiDark = self.guiDark.isChecked()
@@ -248,12 +266,14 @@ class GuiPreferencesGeneral(QWidget):
# Check if restart is needed
needsRestart = False
needsRestart |= self.mainConf.guiLang != guiLang
needsRestart |= self.mainConf.guiTheme != guiTheme
needsRestart |= self.mainConf.guiIcons != guiIcons
needsRestart |= self.mainConf.guiDark != guiDark
needsRestart |= self.mainConf.guiFont != guiFont
needsRestart |= self.mainConf.guiFontSize != guiFontSize
self.mainConf.guiLang = guiLang
self.mainConf.guiTheme = guiTheme
self.mainConf.guiIcons = guiIcons
self.mainConf.guiDark = guiDark
+8
View File
@@ -61,6 +61,14 @@ def refDir():
theDir = os.path.join(testDir, "reference")
return theDir
@pytest.fixture(scope="session")
def filesDir():
"""The folder where additional test files are stored.
"""
testDir = os.path.dirname(__file__)
theDir = os.path.join(testDir, "files")
return theDir
@pytest.fixture(scope="session")
def outDir(tmpDir):
"""An output folder for test results
+10
View File
@@ -91,6 +91,16 @@ class DummyStatusBar():
# END Class DummyStatusBar
class DummyApp:
def __init__(self):
return
def installTranslator(self, theLang):
return
# END Class DummyApp
# =========================================================================== #
# Error Functions
# Dummy functions that will raise errors instead.
+1
View File
@@ -0,0 +1 @@
<クd箆!ソ`。スン
+18 -3
View File
@@ -27,8 +27,8 @@ import configparser
from shutil import copyfile
from dummy import causeOSError
from tools import cmpFiles
from dummy import causeOSError, DummyApp
from tools import cmpFiles, writeFile
from nw.config import Config
from nw.constants import nwConst, nwFiles
@@ -85,7 +85,7 @@ def testBaseConfig_Constructor(monkeypatch):
# END Test testBaseConfig_Constructor
@pytest.mark.base
def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir):
def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
"""Test config intialisation.
"""
tstConf = Config()
@@ -192,6 +192,21 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir):
tstConf.doReplaceSQuote = orDoSng
assert tstConf.saveConfig()
# Localisation
i18nDir = os.path.join(fncDir, "i18n")
os.mkdir(i18nDir)
os.mkdir(os.path.join(i18nDir, "stuff"))
tstConf.nwLangPath = i18nDir
copyfile(os.path.join(filesDir, "nw_en_GB.qm"), os.path.join(fncDir, "nw_en_GB.qm"))
writeFile(os.path.join(i18nDir, "nw_en_GB.ts"), "")
writeFile(os.path.join(i18nDir, "nw_abcd.qm"), "")
tstApp = DummyApp()
tstConf.initLocalisation(tstApp)
theList = tstConf.listLanguages()
assert theList == [("en_GB", "British English")]
copyfile(confFile, testFile)
assert cmpFiles(testFile, compFile, [2, 9, 10])