diff --git a/.gitignore b/.gitignore
index 3d1b337e..5d442ef0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,8 @@
*.egg-info
setup.iss
novelwriter.desktop
+i18n/*.qm
+i18n/*.qph
# Documentation
/docs/build/
diff --git a/i18n/nw_pt.qm b/i18n/nw_pt.qm
deleted file mode 100644
index 81046adf..00000000
Binary files a/i18n/nw_pt.qm and /dev/null differ
diff --git a/i18n/phrases_pt.qph b/i18n/phrases_pt.qph
deleted file mode 100644
index 7b58cb0b..00000000
--- a/i18n/phrases_pt.qph
+++ /dev/null
@@ -1,447 +0,0 @@
-
-
-
- Point of View
- Ponto de Vista
-
-
- Characters
- Personagens
-
-
- Plot
- Enredo
-
-
- Timeline
- Linha do Tempo
-
-
- Locations
- Lugares
-
-
- Objects
- Objetos
-
-
- Entities
- Entidades
-
-
- None
- Nenhum
-
-
- Novel
- Livro
-
-
- Entity
- Entidade
-
-
- Outtakes
- Removidos
-
-
- Trash
- Lixeira
-
-
- Title Page
- Página de Título
-
-
- Book
- Livro
-
-
- Plain Page
- Página
-
-
- Partition
- Partição
-
-
- Unnumbered
- Sem Numeração
-
-
- Scene
- Cena
-
-
- Note
- Nota
-
-
- Title
- Título
-
-
- Level
- Nível
-
-
- Document
- Documento
-
-
- Line
- Linha
-
-
- Chars
- Caracteres
-
-
- Words
- Palavras
-
-
- Synopsis
- Sinopse
-
-
- About
- Sobre
-
-
- Release
- Versões
-
-
- About novelWriter
- Sobre o novelWriter
-
-
- Credits
- Créditos
-
-
- Author
- Autor
-
-
- Credit
- Créditos
-
-
- License
- Licença
-
-
- Theme
- Tema
-
-
- Icons
- Ícones
-
-
- Syntax
- Sintaxe
-
-
- Website
- Website
-
-
- Chapter
- Capítulo
-
-
- Section
- Seção
-
-
- Font family
- Família da fonte
-
-
- Font size
- Tamanho da fonte
-
-
- Justify text
- Texto justificado
-
-
- Print
- Imprimir
-
-
- Build Project
- Construir o Projeto
-
-
- Save As
- Salvar Como
-
-
- Close
- Fechar
-
-
- Plain Text
- Texto Simples
-
-
- Plain HTML
- HTML Simples
-
-
- Save Document As
- Salvar Documento Como
-
-
- Unknown
- Desconhecido
-
-
- Look and Feel
- Aparência
-
-
- Project Backup
- Cópia de Segurança
-
-
- Path
- Caminho
-
-
- Status
- Estado
-
-
- Replace
- Substituir
-
-
- Search
- Pesquisa
-
-
- Handle
- Referência
-
-
- References
- Referências
-
-
- Label
- Rótulo
-
-
- Class
- Classe
-
-
- Layout
- Leiaute
-
-
- Characters
- Caracteres
-
-
- Editor
- Editor
-
-
- Project
- Projeto
-
-
- Provider
- Provedor
-
-
- unknown
- desconhecido
-
-
- Paragraphs
- Parágrafos
-
-
- Default
- Padrão
-
-
- Working title
- Nome do projeto
-
-
- Project path
- Caminho do projeto
-
-
- Project Stats
- Estatíticas do Projeto
-
-
- Folders
- Diretórios
-
-
- Documents
- Documentos
-
-
- Word count
- Contagem de palavras
-
-
- Keyword
- Palavra-chave
-
-
- New
- Novo
-
-
- Delete
- Remover
-
-
- Save
- Salvar
-
-
- Name
- Nome
-
-
- New Item
- Novo Item
-
-
- Last Opened
- Aberto Pela Última Vez
-
-
- Settings
- Configurações
-
-
- Details
- Detalhes
-
-
- Importance
- Importância
-
-
- Auto-Replace
- Substituir automaticamente
-
-
- Flag
- Opção
-
-
- Flags
- Opções
-
-
- (New Entry)
-
-
-
- New File
- Novo Arquivo
-
-
- New Folder
- Novo Diretório
-
-
- Histogram
- Histograma
-
-
- Finished
- Finalizado
-
-
- Done
- Pronto
-
-
- Finish
- Terminar
-
-
- Auto-Replace
- Substituição Automática
-
-
- No Suggestions
- Sem Sugestões
-
-
- Browse
- Procurar
-
-
- Tag
- Etiqueta
-
-
- Draft
- Rascunho
-
-
- Minor
- Menor
-
-
- Major
- Maior
-
-
- Backup
- Cópia de Segurança
-
-
- Undo
- Desfazer
-
-
- Release
- Lançamento
-
-
- Pages
- Páginas
-
-
- Page
- Página
-
-
- Progress
- Progresso
-
-
- Chapters
- Capítulos
-
-
- Scenes
- Cenas
-
-
- Revisions
- Revisões
-
-
- seconds
- segundos
-
-
diff --git a/nw/config.py b/nw/config.py
index 5cf71b85..618bfd3c 100644
--- a/nw/config.py
+++ b/nw/config.py
@@ -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.
"""
diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py
index 8234ebf3..aa7946d6 100644
--- a/nw/gui/preferences.py
+++ b/nw/gui/preferences.py
@@ -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
diff --git a/tests/conftest.py b/tests/conftest.py
index 57956aff..59fd5c5d 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -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
diff --git a/tests/dummy.py b/tests/dummy.py
index 72ac5e21..653fca58 100644
--- a/tests/dummy.py
+++ b/tests/dummy.py
@@ -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.
diff --git a/tests/files/nw_en_GB.qm b/tests/files/nw_en_GB.qm
new file mode 100644
index 00000000..be651eed
--- /dev/null
+++ b/tests/files/nw_en_GB.qm
@@ -0,0 +1 @@
+