novelWriter i18n and portuguese translation

This commit is contained in:
Bruno Kühnen Meneguello
2021-02-09 10:12:59 -03:00
parent 861a847692
commit 98e3343808
41 changed files with 9379 additions and 1548 deletions
+36
View File
@@ -0,0 +1,36 @@
SOURCES += nw/error.py \
nw/constants/constants.py \
nw/constants/iso.py \
nw/core/document.py \
nw/core/index.py \
nw/core/project.py \
nw/core/tohtml.py \
nw/core/tokenizer.py \
nw/core/tree.py \
nw/guimain.py \
nw/gui/about.py \
nw/gui/build.py \
nw/gui/custom.py \
nw/gui/doceditor.py \
nw/gui/dochighlight.py \
nw/gui/docmerge.py \
nw/gui/docsplit.py \
nw/gui/docviewer.py \
nw/gui/itemdetails.py \
nw/gui/itemeditor.py \
nw/gui/mainmenu.py \
nw/gui/noveltree.py \
nw/gui/outlinedetails.py \
nw/gui/outline.py \
nw/gui/preferences.py \
nw/gui/projdetails.py \
nw/gui/projload.py \
nw/gui/projsettings.py \
nw/gui/projtree.py \
nw/gui/projwizard.py \
nw/gui/statusbar.py \
nw/gui/theme.py \
nw/gui/wordlist.py \
nw/gui/writingstats.py
TRANSLATIONS += nw/languages/nw_pt.ts
+31
View File
@@ -24,10 +24,13 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import sys
import getopt
import logging
import re
from PyQt5.QtCore import QLibraryInfo, QLocale, QTranslator
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QErrorMessage
@@ -109,6 +112,21 @@ logger = logging.getLogger(__name__)
# Load the main config as a global object
CONFIG = Config()
nw_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "languages")
qt_path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
translators = {}
def load_translation(app, path, prefix, lang, script = None, country = None):
filename = "_".join(filter(bool, [prefix,
lang and lang.lower(),
script and script.capitalize(),
country and country.upper()]))
if filename not in translators:
translator = QTranslator()
if translator.load(filename, path):
print(filename, path)
app.installTranslator(translator)
translators[filename] = translator
def main(sysArgs=None):
"""Parses command line, sets up logging, and launches main GUI.
@@ -284,6 +302,19 @@ def main(sysArgs=None):
# Connect the exception handler before making the main GUI
sys.excepthook = exceptionHandler
# Load translations
lang, script, country = re.match(
r"^([a-z]{2,3})(?:_([a-z]{4}))?(?:_([a-z]{2,3}))?$",
QLocale.system().name(), re.IGNORECASE).groups()
for path, prefix in ((qt_path, "qt"),
(qt_path, "qtbase"),
(nw_path, "nw")):
load_translation(nwApp, path, prefix, lang)
load_translation(nwApp, path, prefix, lang, script=script)
load_translation(nwApp, path, prefix, lang, country=country)
load_translation(nwApp, path, prefix, lang, script, country)
# Launch main GUI
nwGUI = GuiMain()
if not nwGUI.hasProject:
+62 -61
View File
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from PyQt5.QtCore import QT_TRANSLATE_NOOP
from nw.constants.enum import (
nwItemClass, nwItemLayout, nwItemType, nwOutline
)
@@ -41,8 +42,8 @@ class nwConst():
MAX_BUILDSIZE = 10000000 # Maxium size of a project build
# Spell Check Providers
SP_INTERNAL = "internal"
SP_ENCHANT = "enchant"
SP_INTERNAL = QT_TRANSLATE_NOOP("Constant", "internal")
SP_ENCHANT = QT_TRANSLATE_NOOP("Constant", "enchant")
# END Class nwConst
@@ -119,17 +120,17 @@ class nwKeyWords:
class nwLabels():
CLASS_NAME = {
nwItemClass.NO_CLASS : "None",
nwItemClass.NOVEL : "Novel",
nwItemClass.PLOT : "Plot",
nwItemClass.CHARACTER : "Characters",
nwItemClass.WORLD : "Locations",
nwItemClass.TIMELINE : "Timeline",
nwItemClass.OBJECT : "Objects",
nwItemClass.ENTITY : "Entity",
nwItemClass.CUSTOM : "Custom",
nwItemClass.ARCHIVE : "Outtakes",
nwItemClass.TRASH : "Trash",
nwItemClass.NO_CLASS : QT_TRANSLATE_NOOP("Constant", "None"),
nwItemClass.NOVEL : QT_TRANSLATE_NOOP("Constant", "Novel"),
nwItemClass.PLOT : QT_TRANSLATE_NOOP("Constant", "Plot"),
nwItemClass.CHARACTER : QT_TRANSLATE_NOOP("Constant", "Characters"),
nwItemClass.WORLD : QT_TRANSLATE_NOOP("Constant", "Locations"),
nwItemClass.TIMELINE : QT_TRANSLATE_NOOP("Constant", "Timeline"),
nwItemClass.OBJECT : QT_TRANSLATE_NOOP("Constant", "Objects"),
nwItemClass.ENTITY : QT_TRANSLATE_NOOP("Constant", "Entity"),
nwItemClass.CUSTOM : QT_TRANSLATE_NOOP("Constant", "Custom"),
nwItemClass.ARCHIVE : QT_TRANSLATE_NOOP("Constant", "Outtakes"),
nwItemClass.TRASH : QT_TRANSLATE_NOOP("Constant", "Trash"),
}
CLASS_FLAG = {
nwItemClass.NO_CLASS : "0",
@@ -158,15 +159,15 @@ class nwLabels():
nwItemClass.TRASH : "cls_trash",
}
LAYOUT_NAME = {
nwItemLayout.NO_LAYOUT : "None",
nwItemLayout.TITLE : "Title Page",
nwItemLayout.BOOK : "Book",
nwItemLayout.PAGE : "Plain Page",
nwItemLayout.PARTITION : "Partition",
nwItemLayout.UNNUMBERED : "Unnumbered",
nwItemLayout.CHAPTER : "Chapter",
nwItemLayout.SCENE : "Scene",
nwItemLayout.NOTE : "Note",
nwItemLayout.NO_LAYOUT : QT_TRANSLATE_NOOP("Constant", "None"),
nwItemLayout.TITLE : QT_TRANSLATE_NOOP("Constant", "Title Page"),
nwItemLayout.BOOK : QT_TRANSLATE_NOOP("Constant", "Book"),
nwItemLayout.PAGE : QT_TRANSLATE_NOOP("Constant", "Plain Page"),
nwItemLayout.PARTITION : QT_TRANSLATE_NOOP("Constant", "Partition"),
nwItemLayout.UNNUMBERED : QT_TRANSLATE_NOOP("Constant", "Unnumbered"),
nwItemLayout.CHAPTER : QT_TRANSLATE_NOOP("Constant", "Chapter"),
nwItemLayout.SCENE : QT_TRANSLATE_NOOP("Constant", "Scene"),
nwItemLayout.NOTE : QT_TRANSLATE_NOOP("Constant", "Note"),
}
LAYOUT_FLAG = {
nwItemLayout.NO_LAYOUT : "Xo",
@@ -180,27 +181,27 @@ class nwLabels():
nwItemLayout.NOTE : "Nt",
}
KEY_NAME = {
nwKeyWords.TAG_KEY : "Tag",
nwKeyWords.POV_KEY : "Point of View",
nwKeyWords.FOCUS_KEY : "Focus",
nwKeyWords.CHAR_KEY : "Characters",
nwKeyWords.PLOT_KEY : "Plot",
nwKeyWords.TIME_KEY : "Timeline",
nwKeyWords.WORLD_KEY : "Locations",
nwKeyWords.OBJECT_KEY : "Objects",
nwKeyWords.ENTITY_KEY : "Entities",
nwKeyWords.CUSTOM_KEY : "Custom",
nwKeyWords.TAG_KEY : QT_TRANSLATE_NOOP("Constant", "Tag"),
nwKeyWords.POV_KEY : QT_TRANSLATE_NOOP("Constant", "Point of View"),
nwKeyWords.FOCUS_KEY : QT_TRANSLATE_NOOP("Constant", "Focus"),
nwKeyWords.CHAR_KEY : QT_TRANSLATE_NOOP("Constant", "Characters"),
nwKeyWords.PLOT_KEY : QT_TRANSLATE_NOOP("Constant", "Plot"),
nwKeyWords.TIME_KEY : QT_TRANSLATE_NOOP("Constant", "Timeline"),
nwKeyWords.WORLD_KEY : QT_TRANSLATE_NOOP("Constant", "Locations"),
nwKeyWords.OBJECT_KEY : QT_TRANSLATE_NOOP("Constant", "Objects"),
nwKeyWords.ENTITY_KEY : QT_TRANSLATE_NOOP("Constant", "Entities"),
nwKeyWords.CUSTOM_KEY : QT_TRANSLATE_NOOP("Constant", "Custom"),
}
OUTLINE_COLS = {
nwOutline.TITLE : "Title",
nwOutline.LEVEL : "Level",
nwOutline.LABEL : "Document",
nwOutline.LINE : "Line",
nwOutline.CCOUNT : "Chars",
nwOutline.WCOUNT : "Words",
nwOutline.PCOUNT : "Pars",
nwOutline.POV : "POV",
nwOutline.FOCUS : "Focus",
nwOutline.TITLE : QT_TRANSLATE_NOOP("Constant", "Title"),
nwOutline.LEVEL : QT_TRANSLATE_NOOP("Constant", "Level"),
nwOutline.LABEL : QT_TRANSLATE_NOOP("Constant", "Document"),
nwOutline.LINE : QT_TRANSLATE_NOOP("Constant", "Line"),
nwOutline.CCOUNT : QT_TRANSLATE_NOOP("Constant", "Chars"),
nwOutline.WCOUNT : QT_TRANSLATE_NOOP("Constant", "Words"),
nwOutline.PCOUNT : QT_TRANSLATE_NOOP("Constant", "Pars"),
nwOutline.POV : QT_TRANSLATE_NOOP("Constant", "POV"),
nwOutline.FOCUS : QT_TRANSLATE_NOOP("Constant", "Focus"),
nwOutline.CHAR : KEY_NAME[nwKeyWords.CHAR_KEY],
nwOutline.PLOT : KEY_NAME[nwKeyWords.PLOT_KEY],
nwOutline.TIME : KEY_NAME[nwKeyWords.TIME_KEY],
@@ -208,7 +209,7 @@ class nwLabels():
nwOutline.OBJECT : KEY_NAME[nwKeyWords.OBJECT_KEY],
nwOutline.ENTITY : KEY_NAME[nwKeyWords.ENTITY_KEY],
nwOutline.CUSTOM : KEY_NAME[nwKeyWords.CUSTOM_KEY],
nwOutline.SYNOP : "Synopsis",
nwOutline.SYNOP : QT_TRANSLATE_NOOP("Constant", "Synopsis"),
}
# END Class nwLabels
@@ -218,28 +219,28 @@ class nwQuotes():
Source: https://en.wikipedia.org/wiki/Quotation_mark
"""
SYMBOLS = {
"\u0027" : "Straight single quotation mark",
"\u0022" : "Straight double quotation mark",
"\u0027" : QT_TRANSLATE_NOOP("Constant", "Straight single quotation mark"),
"\u0022" : QT_TRANSLATE_NOOP("Constant", "Straight double quotation mark"),
"\u2018" : "Left single quotation mark",
"\u2019" : "Right single quotation mark",
"\u201a" : "Single low-9 quotation mark",
"\u201b" : "Single high-reversed-9 quotation mark",
"\u201c" : "Left double quotation mark",
"\u201d" : "Right double quotation mark",
"\u201e" : "Double low-9 quotation mark",
"\u201f" : "Double high-reversed-9 quotation mark",
"\u2e42" : "Double low-reversed-9 quotation mark",
"\u2018" : QT_TRANSLATE_NOOP("Constant", "Left single quotation mark"),
"\u2019" : QT_TRANSLATE_NOOP("Constant", "Right single quotation mark"),
"\u201a" : QT_TRANSLATE_NOOP("Constant", "Single low-9 quotation mark"),
"\u201b" : QT_TRANSLATE_NOOP("Constant", "Single high-reversed-9 quotation mark"),
"\u201c" : QT_TRANSLATE_NOOP("Constant", "Left double quotation mark"),
"\u201d" : QT_TRANSLATE_NOOP("Constant", "Right double quotation mark"),
"\u201e" : QT_TRANSLATE_NOOP("Constant", "Double low-9 quotation mark"),
"\u201f" : QT_TRANSLATE_NOOP("Constant", "Double high-reversed-9 quotation mark"),
"\u2e42" : QT_TRANSLATE_NOOP("Constant", "Double low-reversed-9 quotation mark"),
"\u2039" : "Single left-pointing angle quotation mark",
"\u203a" : "Single right-pointing angle quotation mark",
"\u00ab" : "Left-pointing double angle quotation mark",
"\u00bb" : "Right-pointing double angle quotation mark",
"\u2039" : QT_TRANSLATE_NOOP("Constant", "Single left-pointing angle quotation mark"),
"\u203a" : QT_TRANSLATE_NOOP("Constant", "Single right-pointing angle quotation mark"),
"\u00ab" : QT_TRANSLATE_NOOP("Constant", "Left-pointing double angle quotation mark"),
"\u00bb" : QT_TRANSLATE_NOOP("Constant", "Right-pointing double angle quotation mark"),
"\u300c" : "Left corner bracket",
"\u300d" : "Right corner bracket",
"\u300e" : "Left white corner bracket",
"\u300f" : "Right white corner bracket",
"\u300c" : QT_TRANSLATE_NOOP("Constant", "Left corner bracket"),
"\u300d" : QT_TRANSLATE_NOOP("Constant", "Right corner bracket"),
"\u300e" : QT_TRANSLATE_NOOP("Constant", "Left white corner bracket"),
"\u300f" : QT_TRANSLATE_NOOP("Constant", "Right white corner bracket"),
}
# END Class nwQuotes
+436 -433
View File
@@ -24,193 +24,196 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from PyQt5.QtCore import QT_TRANSLATE_NOOP
class isoLanguage():
ISO_639_1 = {
"aa" : "Afar",
"ab" : "Abkhazian",
"ae" : "Avestan",
"af" : "Afrikaans",
"ak" : "Akan",
"am" : "Amharic",
"an" : "Aragonese",
"ar" : "Arabic",
"as" : "Assamese",
"av" : "Avaric",
"ay" : "Aymara",
"az" : "Azerbaijani",
"ba" : "Bashkir",
"be" : "Belarusian",
"bg" : "Bulgarian",
"bh" : "Bihari languages",
"bi" : "Bislama",
"bm" : "Bambara",
"bn" : "Bengali",
"bo" : "Tibetan",
"br" : "Breton",
"bs" : "Bosnian",
"ca" : "Catalan",
"ce" : "Chechen",
"ch" : "Chamorro",
"co" : "Corsican",
"cr" : "Cree",
"cs" : "Czech",
"cu" : "Church Slavic",
"cv" : "Chuvash",
"cy" : "Welsh",
"da" : "Danish",
"de" : "German",
"dv" : "Divehi",
"dz" : "Dzongkha",
"ee" : "Ewe",
"el" : "Modern Greek",
"en" : "English",
"eo" : "Esperanto",
"es" : "Spanish",
"et" : "Estonian",
"eu" : "Basque",
"fa" : "Persian",
"ff" : "Fulah",
"fi" : "Finnish",
"fj" : "Fijian",
"fo" : "Faroese",
"fr" : "French",
"fy" : "Western Frisian",
"ga" : "Irish",
"gd" : "Gaelic",
"gl" : "Galician",
"gn" : "Guarani",
"gu" : "Gujarati",
"gv" : "Manx",
"ha" : "Hausa",
"he" : "Hebrew",
"hi" : "Hindi",
"ho" : "Hiri Motu",
"hr" : "Croatian",
"ht" : "Haitian",
"hu" : "Hungarian",
"hy" : "Armenian",
"hz" : "Herero",
"ia" : "Interlingua",
"id" : "Indonesian",
"ie" : "Interlingue",
"ig" : "Igbo",
"ii" : "Sichuan Yi",
"ik" : "Inupiaq",
"io" : "Ido",
"is" : "Icelandic",
"it" : "Italian",
"iu" : "Inuktitut",
"ja" : "Japanese",
"jv" : "Javanese",
"ka" : "Georgian",
"kg" : "Kongo",
"ki" : "Kikuyu",
"kj" : "Kuanyama",
"kk" : "Kazakh",
"kl" : "Kalaallisut",
"km" : "Central Khmer",
"kn" : "Kannada",
"ko" : "Korean",
"kr" : "Kanuri",
"ks" : "Kashmiri",
"ku" : "Kurdish",
"kv" : "Komi",
"kw" : "Cornish",
"ky" : "Kirghiz",
"la" : "Latin",
"lb" : "Luxembourgish",
"lg" : "Ganda",
"li" : "Limburgan",
"ln" : "Lingala",
"lo" : "Lao",
"lt" : "Lithuanian",
"lu" : "Luba-Katanga",
"lv" : "Latvian",
"mg" : "Malagasy",
"mh" : "Marshallese",
"mi" : "Maori",
"mk" : "Macedonian",
"ml" : "Malayalam",
"mn" : "Mongolian",
"mr" : "Marathi",
"ms" : "Malay",
"mt" : "Maltese",
"my" : "Burmese",
"na" : "Nauru",
"nb" : "Norwegian Bokmål",
"nd" : "North Ndebele",
"ne" : "Nepali",
"ng" : "Ndonga",
"nl" : "Dutch",
"nn" : "Norwegian Nynorsk",
"no" : "Norwegian",
"nr" : "South Ndebele",
"nv" : "Navajo",
"ny" : "Chichewa",
"oc" : "Occitan",
"oj" : "Ojibwa",
"om" : "Oromo",
"or" : "Oriya",
"os" : "Ossetian",
"pa" : "Panjabi",
"pi" : "Pali",
"pl" : "Polish",
"ps" : "Pushto",
"pt" : "Portuguese",
"qu" : "Quechua",
"rm" : "Romansh",
"rn" : "Rundi",
"ro" : "Romanian",
"ru" : "Russian",
"rw" : "Kinyarwanda",
"sa" : "Sanskrit",
"sc" : "Sardinian",
"sd" : "Sindhi",
"se" : "Northern Sami",
"sg" : "Sango",
"si" : "Sinhala",
"sk" : "Slovak",
"sl" : "Slovenian",
"sm" : "Samoan",
"sn" : "Shona",
"so" : "Somali",
"sq" : "Albanian",
"sr" : "Serbian",
"ss" : "Swati",
"st" : "Southern Sotho",
"su" : "Sundanese",
"sv" : "Swedish",
"sw" : "Swahili",
"ta" : "Tamil",
"te" : "Telugu",
"tg" : "Tajik",
"th" : "Thai",
"ti" : "Tigrinya",
"tk" : "Turkmen",
"tl" : "Tagalog",
"tn" : "Tswana",
"to" : "Tonga",
"tr" : "Turkish",
"ts" : "Tsonga",
"tt" : "Tatar",
"tw" : "Twi",
"ty" : "Tahitian",
"ug" : "Uighur",
"uk" : "Ukrainian",
"ur" : "Urdu",
"uz" : "Uzbek",
"ve" : "Venda",
"vi" : "Vietnamese",
"vo" : "Volapük",
"wa" : "Walloon",
"wo" : "Wolof",
"xh" : "Xhosa",
"yi" : "Yiddish",
"yo" : "Yoruba",
"za" : "Zhuang",
"zh" : "Chinese",
"zu" : "Zulu",
"aa" : QT_TRANSLATE_NOOP("ISO", "Afar"),
"ab" : QT_TRANSLATE_NOOP("ISO", "Abkhazian"),
"ae" : QT_TRANSLATE_NOOP("ISO", "Avestan"),
"af" : QT_TRANSLATE_NOOP("ISO", "Afrikaans"),
"ak" : QT_TRANSLATE_NOOP("ISO", "Akan"),
"am" : QT_TRANSLATE_NOOP("ISO", "Amharic"),
"an" : QT_TRANSLATE_NOOP("ISO", "Aragonese"),
"ar" : QT_TRANSLATE_NOOP("ISO", "Arabic"),
"as" : QT_TRANSLATE_NOOP("ISO", "Assamese"),
"av" : QT_TRANSLATE_NOOP("ISO", "Avaric"),
"ay" : QT_TRANSLATE_NOOP("ISO", "Aymara"),
"az" : QT_TRANSLATE_NOOP("ISO", "Azerbaijani"),
"ba" : QT_TRANSLATE_NOOP("ISO", "Bashkir"),
"be" : QT_TRANSLATE_NOOP("ISO", "Belarusian"),
"bg" : QT_TRANSLATE_NOOP("ISO", "Bulgarian"),
"bh" : QT_TRANSLATE_NOOP("ISO", "Bihari languages"),
"bi" : QT_TRANSLATE_NOOP("ISO", "Bislama"),
"bm" : QT_TRANSLATE_NOOP("ISO", "Bambara"),
"bn" : QT_TRANSLATE_NOOP("ISO", "Bengali"),
"bo" : QT_TRANSLATE_NOOP("ISO", "Tibetan"),
"br" : QT_TRANSLATE_NOOP("ISO", "Breton"),
"bs" : QT_TRANSLATE_NOOP("ISO", "Bosnian"),
"ca" : QT_TRANSLATE_NOOP("ISO", "Catalan"),
"ce" : QT_TRANSLATE_NOOP("ISO", "Chechen"),
"ch" : QT_TRANSLATE_NOOP("ISO", "Chamorro"),
"co" : QT_TRANSLATE_NOOP("ISO", "Corsican"),
"cr" : QT_TRANSLATE_NOOP("ISO", "Cree"),
"cs" : QT_TRANSLATE_NOOP("ISO", "Czech"),
"cu" : QT_TRANSLATE_NOOP("ISO", "Church Slavic"),
"cv" : QT_TRANSLATE_NOOP("ISO", "Chuvash"),
"cy" : QT_TRANSLATE_NOOP("ISO", "Welsh"),
"da" : QT_TRANSLATE_NOOP("ISO", "Danish"),
"de" : QT_TRANSLATE_NOOP("ISO", "German"),
"dv" : QT_TRANSLATE_NOOP("ISO", "Divehi"),
"dz" : QT_TRANSLATE_NOOP("ISO", "Dzongkha"),
"ee" : QT_TRANSLATE_NOOP("ISO", "Ewe"),
"el" : QT_TRANSLATE_NOOP("ISO", "Modern Greek"),
"en" : QT_TRANSLATE_NOOP("ISO", "English"),
"eo" : QT_TRANSLATE_NOOP("ISO", "Esperanto"),
"es" : QT_TRANSLATE_NOOP("ISO", "Spanish"),
"et" : QT_TRANSLATE_NOOP("ISO", "Estonian"),
"eu" : QT_TRANSLATE_NOOP("ISO", "Basque"),
"fa" : QT_TRANSLATE_NOOP("ISO", "Persian"),
"ff" : QT_TRANSLATE_NOOP("ISO", "Fulah"),
"fi" : QT_TRANSLATE_NOOP("ISO", "Finnish"),
"fj" : QT_TRANSLATE_NOOP("ISO", "Fijian"),
"fo" : QT_TRANSLATE_NOOP("ISO", "Faroese"),
"fr" : QT_TRANSLATE_NOOP("ISO", "French"),
"fy" : QT_TRANSLATE_NOOP("ISO", "Western Frisian"),
"ga" : QT_TRANSLATE_NOOP("ISO", "Irish"),
"gd" : QT_TRANSLATE_NOOP("ISO", "Gaelic"),
"gl" : QT_TRANSLATE_NOOP("ISO", "Galician"),
"gn" : QT_TRANSLATE_NOOP("ISO", "Guarani"),
"gu" : QT_TRANSLATE_NOOP("ISO", "Gujarati"),
"gv" : QT_TRANSLATE_NOOP("ISO", "Manx"),
"ha" : QT_TRANSLATE_NOOP("ISO", "Hausa"),
"he" : QT_TRANSLATE_NOOP("ISO", "Hebrew"),
"hi" : QT_TRANSLATE_NOOP("ISO", "Hindi"),
"ho" : QT_TRANSLATE_NOOP("ISO", "Hiri Motu"),
"hr" : QT_TRANSLATE_NOOP("ISO", "Croatian"),
"ht" : QT_TRANSLATE_NOOP("ISO", "Haitian"),
"hu" : QT_TRANSLATE_NOOP("ISO", "Hungarian"),
"hy" : QT_TRANSLATE_NOOP("ISO", "Armenian"),
"hz" : QT_TRANSLATE_NOOP("ISO", "Herero"),
"ia" : QT_TRANSLATE_NOOP("ISO", "Interlingua"),
"id" : QT_TRANSLATE_NOOP("ISO", "Indonesian"),
"ie" : QT_TRANSLATE_NOOP("ISO", "Interlingue"),
"ig" : QT_TRANSLATE_NOOP("ISO", "Igbo"),
"ii" : QT_TRANSLATE_NOOP("ISO", "Sichuan Yi"),
"ik" : QT_TRANSLATE_NOOP("ISO", "Inupiaq"),
"io" : QT_TRANSLATE_NOOP("ISO", "Ido"),
"is" : QT_TRANSLATE_NOOP("ISO", "Icelandic"),
"it" : QT_TRANSLATE_NOOP("ISO", "Italian"),
"iu" : QT_TRANSLATE_NOOP("ISO", "Inuktitut"),
"ja" : QT_TRANSLATE_NOOP("ISO", "Japanese"),
"jv" : QT_TRANSLATE_NOOP("ISO", "Javanese"),
"ka" : QT_TRANSLATE_NOOP("ISO", "Georgian"),
"kg" : QT_TRANSLATE_NOOP("ISO", "Kongo"),
"ki" : QT_TRANSLATE_NOOP("ISO", "Kikuyu"),
"kj" : QT_TRANSLATE_NOOP("ISO", "Kuanyama"),
"kk" : QT_TRANSLATE_NOOP("ISO", "Kazakh"),
"kl" : QT_TRANSLATE_NOOP("ISO", "Kalaallisut"),
"km" : QT_TRANSLATE_NOOP("ISO", "Central Khmer"),
"kn" : QT_TRANSLATE_NOOP("ISO", "Kannada"),
"ko" : QT_TRANSLATE_NOOP("ISO", "Korean"),
"kr" : QT_TRANSLATE_NOOP("ISO", "Kanuri"),
"ks" : QT_TRANSLATE_NOOP("ISO", "Kashmiri"),
"ku" : QT_TRANSLATE_NOOP("ISO", "Kurdish"),
"kv" : QT_TRANSLATE_NOOP("ISO", "Komi"),
"kw" : QT_TRANSLATE_NOOP("ISO", "Cornish"),
"ky" : QT_TRANSLATE_NOOP("ISO", "Kirghiz"),
"la" : QT_TRANSLATE_NOOP("ISO", "Latin"),
"lb" : QT_TRANSLATE_NOOP("ISO", "Luxembourgish"),
"lg" : QT_TRANSLATE_NOOP("ISO", "Ganda"),
"li" : QT_TRANSLATE_NOOP("ISO", "Limburgan"),
"ln" : QT_TRANSLATE_NOOP("ISO", "Lingala"),
"lo" : QT_TRANSLATE_NOOP("ISO", "Lao"),
"lt" : QT_TRANSLATE_NOOP("ISO", "Lithuanian"),
"lu" : QT_TRANSLATE_NOOP("ISO", "Luba-Katanga"),
"lv" : QT_TRANSLATE_NOOP("ISO", "Latvian"),
"mg" : QT_TRANSLATE_NOOP("ISO", "Malagasy"),
"mh" : QT_TRANSLATE_NOOP("ISO", "Marshallese"),
"mi" : QT_TRANSLATE_NOOP("ISO", "Maori"),
"mk" : QT_TRANSLATE_NOOP("ISO", "Macedonian"),
"ml" : QT_TRANSLATE_NOOP("ISO", "Malayalam"),
"mn" : QT_TRANSLATE_NOOP("ISO", "Mongolian"),
"mr" : QT_TRANSLATE_NOOP("ISO", "Marathi"),
"ms" : QT_TRANSLATE_NOOP("ISO", "Malay"),
"mt" : QT_TRANSLATE_NOOP("ISO", "Maltese"),
"my" : QT_TRANSLATE_NOOP("ISO", "Burmese"),
"na" : QT_TRANSLATE_NOOP("ISO", "Nauru"),
"nb" : QT_TRANSLATE_NOOP("ISO", "Norwegian Bokm\u0229l"),
"nd" : QT_TRANSLATE_NOOP("ISO", "North Ndebele"),
"ne" : QT_TRANSLATE_NOOP("ISO", "Nepali"),
"ng" : QT_TRANSLATE_NOOP("ISO", "Ndonga"),
"nl" : QT_TRANSLATE_NOOP("ISO", "Dutch"),
"nn" : QT_TRANSLATE_NOOP("ISO", "Norwegian Nynorsk"),
"no" : QT_TRANSLATE_NOOP("ISO", "Norwegian"),
"nr" : QT_TRANSLATE_NOOP("ISO", "South Ndebele"),
"nv" : QT_TRANSLATE_NOOP("ISO", "Navajo"),
"ny" : QT_TRANSLATE_NOOP("ISO", "Chichewa"),
"oc" : QT_TRANSLATE_NOOP("ISO", "Occitan"),
"oj" : QT_TRANSLATE_NOOP("ISO", "Ojibwa"),
"om" : QT_TRANSLATE_NOOP("ISO", "Oromo"),
"or" : QT_TRANSLATE_NOOP("ISO", "Oriya"),
"os" : QT_TRANSLATE_NOOP("ISO", "Ossetian"),
"pa" : QT_TRANSLATE_NOOP("ISO", "Panjabi"),
"pi" : QT_TRANSLATE_NOOP("ISO", "Pali"),
"pl" : QT_TRANSLATE_NOOP("ISO", "Polish"),
"ps" : QT_TRANSLATE_NOOP("ISO", "Pushto"),
"pt" : QT_TRANSLATE_NOOP("ISO", "Portuguese"),
"qu" : QT_TRANSLATE_NOOP("ISO", "Quechua"),
"rm" : QT_TRANSLATE_NOOP("ISO", "Romansh"),
"rn" : QT_TRANSLATE_NOOP("ISO", "Rundi"),
"ro" : QT_TRANSLATE_NOOP("ISO", "Romanian"),
"ru" : QT_TRANSLATE_NOOP("ISO", "Russian"),
"rw" : QT_TRANSLATE_NOOP("ISO", "Kinyarwanda"),
"sa" : QT_TRANSLATE_NOOP("ISO", "Sanskrit"),
"sc" : QT_TRANSLATE_NOOP("ISO", "Sardinian"),
"sd" : QT_TRANSLATE_NOOP("ISO", "Sindhi"),
"se" : QT_TRANSLATE_NOOP("ISO", "Northern Sami"),
"sg" : QT_TRANSLATE_NOOP("ISO", "Sango"),
"si" : QT_TRANSLATE_NOOP("ISO", "Sinhala"),
"sk" : QT_TRANSLATE_NOOP("ISO", "Slovak"),
"sl" : QT_TRANSLATE_NOOP("ISO", "Slovenian"),
"sm" : QT_TRANSLATE_NOOP("ISO", "Samoan"),
"sn" : QT_TRANSLATE_NOOP("ISO", "Shona"),
"so" : QT_TRANSLATE_NOOP("ISO", "Somali"),
"sq" : QT_TRANSLATE_NOOP("ISO", "Albanian"),
"sr" : QT_TRANSLATE_NOOP("ISO", "Serbian"),
"ss" : QT_TRANSLATE_NOOP("ISO", "Swati"),
"st" : QT_TRANSLATE_NOOP("ISO", "Southern Sotho"),
"su" : QT_TRANSLATE_NOOP("ISO", "Sundanese"),
"sv" : QT_TRANSLATE_NOOP("ISO", "Swedish"),
"sw" : QT_TRANSLATE_NOOP("ISO", "Swahili"),
"ta" : QT_TRANSLATE_NOOP("ISO", "Tamil"),
"te" : QT_TRANSLATE_NOOP("ISO", "Telugu"),
"tg" : QT_TRANSLATE_NOOP("ISO", "Tajik"),
"th" : QT_TRANSLATE_NOOP("ISO", "Thai"),
"ti" : QT_TRANSLATE_NOOP("ISO", "Tigrinya"),
"tk" : QT_TRANSLATE_NOOP("ISO", "Turkmen"),
"tl" : QT_TRANSLATE_NOOP("ISO", "Tagalog"),
"tn" : QT_TRANSLATE_NOOP("ISO", "Tswana"),
"to" : QT_TRANSLATE_NOOP("ISO", "Tonga"),
"tr" : QT_TRANSLATE_NOOP("ISO", "Turkish"),
"ts" : QT_TRANSLATE_NOOP("ISO", "Tsonga"),
"tt" : QT_TRANSLATE_NOOP("ISO", "Tatar"),
"tw" : QT_TRANSLATE_NOOP("ISO", "Twi"),
"ty" : QT_TRANSLATE_NOOP("ISO", "Tahitian"),
"ug" : QT_TRANSLATE_NOOP("ISO", "Uighur"),
"uk" : QT_TRANSLATE_NOOP("ISO", "Ukrainian"),
"ur" : QT_TRANSLATE_NOOP("ISO", "Urdu"),
"uz" : QT_TRANSLATE_NOOP("ISO", "Uzbek"),
"ve" : QT_TRANSLATE_NOOP("ISO", "Venda"),
"vi" : QT_TRANSLATE_NOOP("ISO", "Vietnamese"),
"vo" : QT_TRANSLATE_NOOP("ISO", "Volap\u00fck"),
"wa" : QT_TRANSLATE_NOOP("ISO", "Walloon"),
"wo" : QT_TRANSLATE_NOOP("ISO", "Wolof"),
"xh" : QT_TRANSLATE_NOOP("ISO", "Xhosa"),
"yi" : QT_TRANSLATE_NOOP("ISO", "Yiddish"),
"yo" : QT_TRANSLATE_NOOP("ISO", "Yoruba"),
"za" : QT_TRANSLATE_NOOP("ISO", "Zhuang"),
"zh" : QT_TRANSLATE_NOOP("ISO", "Chinese"),
"zu" : QT_TRANSLATE_NOOP("ISO", "Zulu"),
}
# END Class isoLanguage
@@ -218,255 +221,255 @@ class isoLanguage():
class isoCountry():
ISO_3166_1_alpha_2 = {
"AD" : "Andorra",
"AE" : "United Arab Emirates",
"AF" : "Afghanistan",
"AG" : "Antigua and Barbuda",
"AI" : "Anguilla",
"AL" : "Albania",
"AM" : "Armenia",
"AO" : "Angola",
"AQ" : "Antarctica",
"AR" : "Argentina",
"AS" : "American Samoa",
"AT" : "Austria",
"AU" : "Australia",
"AW" : "Aruba",
"AX" : "Åland Islands",
"AZ" : "Azerbaijan",
"BA" : "Bosnia and Herzegovina",
"BB" : "Barbados",
"BD" : "Bangladesh",
"BE" : "Belgium",
"BF" : "Burkina Faso",
"BG" : "Bulgaria",
"BH" : "Bahrain",
"BI" : "Burundi",
"BJ" : "Benin",
"BL" : "Saint Barthélemy",
"BM" : "Bermuda",
"BN" : "Brunei Darussalam",
"BO" : "Plurinational State of Bolivia",
"BQ" : "Sint Eustatius and Saba Bonaire",
"BR" : "Brazil",
"BS" : "Bahamas",
"BT" : "Bhutan",
"BV" : "Bouvet Island",
"BW" : "Botswana",
"BY" : "Belarus",
"BZ" : "Belize",
"CA" : "Canada",
"CC" : "Cocos (Keeling) Islands",
"CD" : "The Democratic Republic of the Congo",
"CF" : "Central African Republic",
"CG" : "Congo",
"CH" : "Switzerland",
"CI" : "te d'Ivoire",
"CK" : "Cook Islands",
"CL" : "Chile",
"CM" : "Cameroon",
"CN" : "China",
"CO" : "Colombia",
"CR" : "Costa Rica",
"CU" : "Cuba",
"CV" : "Cape Verde",
"CW" : "Curaçao",
"CX" : "Christmas Island",
"CY" : "Cyprus",
"CZ" : "Czech Republic",
"DE" : "Germany",
"DJ" : "Djibouti",
"DK" : "Denmark",
"DM" : "Dominica",
"DO" : "Dominican Republic",
"DZ" : "Algeria",
"EC" : "Ecuador",
"EE" : "Estonia",
"EG" : "Egypt",
"EH" : "Western Sahara",
"ER" : "Eritrea",
"ES" : "Spain",
"ET" : "Ethiopia",
"FI" : "Finland",
"FJ" : "Fiji",
"FK" : "Falkland Islands (Malvinas)",
"FM" : "Federated States of Micronesia",
"FO" : "Faroe Islands",
"FR" : "France",
"GA" : "Gabon",
"GB" : "United Kingdom",
"GD" : "Grenada",
"GE" : "Georgia",
"GF" : "French Guiana",
"GG" : "Guernsey",
"GH" : "Ghana",
"GI" : "Gibraltar",
"GL" : "Greenland",
"GM" : "Gambia",
"GN" : "Guinea",
"GP" : "Guadeloupe",
"GQ" : "Equatorial Guinea",
"GR" : "Greece",
"GS" : "South Georgia and the South Sandwich Islands",
"GT" : "Guatemala",
"GU" : "Guam",
"GW" : "Guinea-Bissau",
"GY" : "Guyana",
"HK" : "Hong Kong",
"HM" : "Heard Island and McDonald Islands",
"HN" : "Honduras",
"HR" : "Croatia",
"HT" : "Haiti",
"HU" : "Hungary",
"ID" : "Indonesia",
"IE" : "Ireland",
"IL" : "Israel",
"IM" : "Isle of Man",
"IN" : "India",
"IO" : "British Indian Ocean Territory",
"IQ" : "Iraq",
"IR" : "Islamic Republic of Iran",
"IS" : "Iceland",
"IT" : "Italy",
"JE" : "Jersey",
"JM" : "Jamaica",
"JO" : "Jordan",
"JP" : "Japan",
"KE" : "Kenya",
"KG" : "Kyrgyzstan",
"KH" : "Cambodia",
"KI" : "Kiribati",
"KM" : "Comoros",
"KN" : "Saint Kitts and Nevis",
"KP" : "Democratic People's Republic of Korea",
"KR" : "Republic of Korea",
"KW" : "Kuwait",
"KY" : "Cayman Islands",
"KZ" : "Kazakhstan",
"LA" : "Lao People's Democratic Republic",
"LB" : "Lebanon",
"LC" : "Saint Lucia",
"LI" : "Liechtenstein",
"LK" : "Sri Lanka",
"LR" : "Liberia",
"LS" : "Lesotho",
"LT" : "Lithuania",
"LU" : "Luxembourg",
"LV" : "Latvia",
"LY" : "Libya",
"MA" : "Morocco",
"MC" : "Monaco",
"MD" : "Republic of Moldova",
"ME" : "Montenegro",
"MF" : "Saint Martin (French part)",
"MG" : "Madagascar",
"MH" : "Marshall Islands",
"MK" : "The Former Yugoslav Republic of Macedonia",
"ML" : "Mali",
"MM" : "Myanmar",
"MN" : "Mongolia",
"MO" : "Macao",
"MP" : "Northern Mariana Islands",
"MQ" : "Martinique",
"MR" : "Mauritania",
"MS" : "Montserrat",
"MT" : "Malta",
"MU" : "Mauritius",
"MV" : "Maldives",
"MW" : "Malawi",
"MX" : "Mexico",
"MY" : "Malaysia",
"MZ" : "Mozambique",
"NA" : "Namibia",
"NC" : "New Caledonia",
"NE" : "Niger",
"NF" : "Norfolk Island",
"NG" : "Nigeria",
"NI" : "Nicaragua",
"NL" : "Netherlands",
"NO" : "Norway",
"NP" : "Nepal",
"NR" : "Nauru",
"NU" : "Niue",
"NZ" : "New Zealand",
"OM" : "Oman",
"PA" : "Panama",
"PE" : "Peru",
"PF" : "French Polynesia",
"PG" : "Papua New Guinea",
"PH" : "Philippines",
"PK" : "Pakistan",
"PL" : "Poland",
"PM" : "Saint Pierre and Miquelon",
"PN" : "Pitcairn",
"PR" : "Puerto Rico",
"PS" : "State of Palestine",
"PT" : "Portugal",
"PW" : "Palau",
"PY" : "Paraguay",
"QA" : "Qatar",
"RE" : "Réunion",
"RO" : "Romania",
"RS" : "Serbia",
"RU" : "Russian Federation",
"RW" : "Rwanda",
"SA" : "Saudi Arabia",
"SB" : "Solomon Islands",
"SC" : "Seychelles",
"SD" : "Sudan",
"SE" : "Sweden",
"SG" : "Singapore",
"SH" : "Saint Helena, Ascension and Tristan da Cunha",
"SI" : "Slovenia",
"SJ" : "Svalbard and Jan Mayen",
"SK" : "Slovakia",
"SL" : "Sierra Leone",
"SM" : "San Marino",
"SN" : "Senegal",
"SO" : "Somalia",
"SR" : "Suriname",
"SS" : "South Sudan",
"ST" : "Sao Tome and Principe",
"SV" : "El Salvador",
"SX" : "Sint Maarten",
"SY" : "Syrian Arab Republic",
"SZ" : "Swaziland",
"TC" : "Turks and Caicos Islands",
"TD" : "Chad",
"TF" : "French Southern Territories",
"TG" : "Togo",
"TH" : "Thailand",
"TJ" : "Tajikistan",
"TK" : "Tokelau",
"TL" : "Timor-Leste",
"TM" : "Turkmenistan",
"TN" : "Tunisia",
"TO" : "Tonga",
"TR" : "Turkey",
"TT" : "Trinidad and Tobago",
"TV" : "Tuvalu",
"TW" : "Taiwan, Province of China",
"TZ" : "United Republic of Tanzania",
"UA" : "Ukraine",
"UG" : "Uganda",
"UM" : "United States Minor Outlying Islands",
"US" : "United States",
"UY" : "Uruguay",
"UZ" : "Uzbekistan",
"VA" : "Holy See (Vatican City State)",
"VC" : "Saint Vincent and the Grenadines",
"VE" : "Bolivarian Republic of Venezuela",
"VG" : "British Virgin Islands",
"VI" : "U.S. Virgin Islands",
"VN" : "Viet Nam",
"VU" : "Vanuatu",
"WF" : "Wallis and Futuna",
"WS" : "Samoa",
"YE" : "Yemen",
"YT" : "Mayotte",
"ZA" : "South Africa",
"ZM" : "Zambia",
"ZW" : "Zimbabwe",
"AD" : QT_TRANSLATE_NOOP("ISO", "Andorra"),
"AE" : QT_TRANSLATE_NOOP("ISO", "United Arab Emirates"),
"AF" : QT_TRANSLATE_NOOP("ISO", "Afghanistan"),
"AG" : QT_TRANSLATE_NOOP("ISO", "Antigua and Barbuda"),
"AI" : QT_TRANSLATE_NOOP("ISO", "Anguilla"),
"AL" : QT_TRANSLATE_NOOP("ISO", "Albania"),
"AM" : QT_TRANSLATE_NOOP("ISO", "Armenia"),
"AO" : QT_TRANSLATE_NOOP("ISO", "Angola"),
"AQ" : QT_TRANSLATE_NOOP("ISO", "Antarctica"),
"AR" : QT_TRANSLATE_NOOP("ISO", "Argentina"),
"AS" : QT_TRANSLATE_NOOP("ISO", "American Samoa"),
"AT" : QT_TRANSLATE_NOOP("ISO", "Austria"),
"AU" : QT_TRANSLATE_NOOP("ISO", "Australia"),
"AW" : QT_TRANSLATE_NOOP("ISO", "Aruba"),
"AX" : QT_TRANSLATE_NOOP("ISO", "\u0197land Islands"),
"AZ" : QT_TRANSLATE_NOOP("ISO", "Azerbaijan"),
"BA" : QT_TRANSLATE_NOOP("ISO", "Bosnia and Herzegovina"),
"BB" : QT_TRANSLATE_NOOP("ISO", "Barbados"),
"BD" : QT_TRANSLATE_NOOP("ISO", "Bangladesh"),
"BE" : QT_TRANSLATE_NOOP("ISO", "Belgium"),
"BF" : QT_TRANSLATE_NOOP("ISO", "Burkina Faso"),
"BG" : QT_TRANSLATE_NOOP("ISO", "Bulgaria"),
"BH" : QT_TRANSLATE_NOOP("ISO", "Bahrain"),
"BI" : QT_TRANSLATE_NOOP("ISO", "Burundi"),
"BJ" : QT_TRANSLATE_NOOP("ISO", "Benin"),
"BL" : QT_TRANSLATE_NOOP("ISO", "Saint Barth\u00e9lemy"),
"BM" : QT_TRANSLATE_NOOP("ISO", "Bermuda"),
"BN" : QT_TRANSLATE_NOOP("ISO", "Brunei Darussalam"),
"BO" : QT_TRANSLATE_NOOP("ISO", "Plurinational State of Bolivia"),
"BQ" : QT_TRANSLATE_NOOP("ISO", "Sint Eustatius and Saba Bonaire"),
"BR" : QT_TRANSLATE_NOOP("ISO", "Brazil"),
"BS" : QT_TRANSLATE_NOOP("ISO", "Bahamas"),
"BT" : QT_TRANSLATE_NOOP("ISO", "Bhutan"),
"BV" : QT_TRANSLATE_NOOP("ISO", "Bouvet Island"),
"BW" : QT_TRANSLATE_NOOP("ISO", "Botswana"),
"BY" : QT_TRANSLATE_NOOP("ISO", "Belarus"),
"BZ" : QT_TRANSLATE_NOOP("ISO", "Belize"),
"CA" : QT_TRANSLATE_NOOP("ISO", "Canada"),
"CC" : QT_TRANSLATE_NOOP("ISO", "Cocos (Keeling) Islands"),
"CD" : QT_TRANSLATE_NOOP("ISO", "The Democratic Republic of the Congo"),
"CF" : QT_TRANSLATE_NOOP("ISO", "Central African Republic"),
"CG" : QT_TRANSLATE_NOOP("ISO", "Congo"),
"CH" : QT_TRANSLATE_NOOP("ISO", "Switzerland"),
"CI" : QT_TRANSLATE_NOOP("ISO", "C\u00f4te d'Ivoire"),
"CK" : QT_TRANSLATE_NOOP("ISO", "Cook Islands"),
"CL" : QT_TRANSLATE_NOOP("ISO", "Chile"),
"CM" : QT_TRANSLATE_NOOP("ISO", "Cameroon"),
"CN" : QT_TRANSLATE_NOOP("ISO", "China"),
"CO" : QT_TRANSLATE_NOOP("ISO", "Colombia"),
"CR" : QT_TRANSLATE_NOOP("ISO", "Costa Rica"),
"CU" : QT_TRANSLATE_NOOP("ISO", "Cuba"),
"CV" : QT_TRANSLATE_NOOP("ISO", "Cape Verde"),
"CW" : QT_TRANSLATE_NOOP("ISO", "Cura\u00e7ao"),
"CX" : QT_TRANSLATE_NOOP("ISO", "Christmas Island"),
"CY" : QT_TRANSLATE_NOOP("ISO", "Cyprus"),
"CZ" : QT_TRANSLATE_NOOP("ISO", "Czech Republic"),
"DE" : QT_TRANSLATE_NOOP("ISO", "Germany"),
"DJ" : QT_TRANSLATE_NOOP("ISO", "Djibouti"),
"DK" : QT_TRANSLATE_NOOP("ISO", "Denmark"),
"DM" : QT_TRANSLATE_NOOP("ISO", "Dominica"),
"DO" : QT_TRANSLATE_NOOP("ISO", "Dominican Republic"),
"DZ" : QT_TRANSLATE_NOOP("ISO", "Algeria"),
"EC" : QT_TRANSLATE_NOOP("ISO", "Ecuador"),
"EE" : QT_TRANSLATE_NOOP("ISO", "Estonia"),
"EG" : QT_TRANSLATE_NOOP("ISO", "Egypt"),
"EH" : QT_TRANSLATE_NOOP("ISO", "Western Sahara"),
"ER" : QT_TRANSLATE_NOOP("ISO", "Eritrea"),
"ES" : QT_TRANSLATE_NOOP("ISO", "Spain"),
"ET" : QT_TRANSLATE_NOOP("ISO", "Ethiopia"),
"FI" : QT_TRANSLATE_NOOP("ISO", "Finland"),
"FJ" : QT_TRANSLATE_NOOP("ISO", "Fiji"),
"FK" : QT_TRANSLATE_NOOP("ISO", "Falkland Islands (Malvinas)"),
"FM" : QT_TRANSLATE_NOOP("ISO", "Federated States of Micronesia"),
"FO" : QT_TRANSLATE_NOOP("ISO", "Faroe Islands"),
"FR" : QT_TRANSLATE_NOOP("ISO", "France"),
"GA" : QT_TRANSLATE_NOOP("ISO", "Gabon"),
"GB" : QT_TRANSLATE_NOOP("ISO", "United Kingdom"),
"GD" : QT_TRANSLATE_NOOP("ISO", "Grenada"),
"GE" : QT_TRANSLATE_NOOP("ISO", "Georgia"),
"GF" : QT_TRANSLATE_NOOP("ISO", "French Guiana"),
"GG" : QT_TRANSLATE_NOOP("ISO", "Guernsey"),
"GH" : QT_TRANSLATE_NOOP("ISO", "Ghana"),
"GI" : QT_TRANSLATE_NOOP("ISO", "Gibraltar"),
"GL" : QT_TRANSLATE_NOOP("ISO", "Greenland"),
"GM" : QT_TRANSLATE_NOOP("ISO", "Gambia"),
"GN" : QT_TRANSLATE_NOOP("ISO", "Guinea"),
"GP" : QT_TRANSLATE_NOOP("ISO", "Guadeloupe"),
"GQ" : QT_TRANSLATE_NOOP("ISO", "Equatorial Guinea"),
"GR" : QT_TRANSLATE_NOOP("ISO", "Greece"),
"GS" : QT_TRANSLATE_NOOP("ISO", "South Georgia and the South Sandwich Islands"),
"GT" : QT_TRANSLATE_NOOP("ISO", "Guatemala"),
"GU" : QT_TRANSLATE_NOOP("ISO", "Guam"),
"GW" : QT_TRANSLATE_NOOP("ISO", "Guinea-Bissau"),
"GY" : QT_TRANSLATE_NOOP("ISO", "Guyana"),
"HK" : QT_TRANSLATE_NOOP("ISO", "Hong Kong"),
"HM" : QT_TRANSLATE_NOOP("ISO", "Heard Island and McDonald Islands"),
"HN" : QT_TRANSLATE_NOOP("ISO", "Honduras"),
"HR" : QT_TRANSLATE_NOOP("ISO", "Croatia"),
"HT" : QT_TRANSLATE_NOOP("ISO", "Haiti"),
"HU" : QT_TRANSLATE_NOOP("ISO", "Hungary"),
"ID" : QT_TRANSLATE_NOOP("ISO", "Indonesia"),
"IE" : QT_TRANSLATE_NOOP("ISO", "Ireland"),
"IL" : QT_TRANSLATE_NOOP("ISO", "Israel"),
"IM" : QT_TRANSLATE_NOOP("ISO", "Isle of Man"),
"IN" : QT_TRANSLATE_NOOP("ISO", "India"),
"IO" : QT_TRANSLATE_NOOP("ISO", "British Indian Ocean Territory"),
"IQ" : QT_TRANSLATE_NOOP("ISO", "Iraq"),
"IR" : QT_TRANSLATE_NOOP("ISO", "Islamic Republic of Iran"),
"IS" : QT_TRANSLATE_NOOP("ISO", "Iceland"),
"IT" : QT_TRANSLATE_NOOP("ISO", "Italy"),
"JE" : QT_TRANSLATE_NOOP("ISO", "Jersey"),
"JM" : QT_TRANSLATE_NOOP("ISO", "Jamaica"),
"JO" : QT_TRANSLATE_NOOP("ISO", "Jordan"),
"JP" : QT_TRANSLATE_NOOP("ISO", "Japan"),
"KE" : QT_TRANSLATE_NOOP("ISO", "Kenya"),
"KG" : QT_TRANSLATE_NOOP("ISO", "Kyrgyzstan"),
"KH" : QT_TRANSLATE_NOOP("ISO", "Cambodia"),
"KI" : QT_TRANSLATE_NOOP("ISO", "Kiribati"),
"KM" : QT_TRANSLATE_NOOP("ISO", "Comoros"),
"KN" : QT_TRANSLATE_NOOP("ISO", "Saint Kitts and Nevis"),
"KP" : QT_TRANSLATE_NOOP("ISO", "Democratic People's Republic of Korea"),
"KR" : QT_TRANSLATE_NOOP("ISO", "Republic of Korea"),
"KW" : QT_TRANSLATE_NOOP("ISO", "Kuwait"),
"KY" : QT_TRANSLATE_NOOP("ISO", "Cayman Islands"),
"KZ" : QT_TRANSLATE_NOOP("ISO", "Kazakhstan"),
"LA" : QT_TRANSLATE_NOOP("ISO", "Lao People's Democratic Republic"),
"LB" : QT_TRANSLATE_NOOP("ISO", "Lebanon"),
"LC" : QT_TRANSLATE_NOOP("ISO", "Saint Lucia"),
"LI" : QT_TRANSLATE_NOOP("ISO", "Liechtenstein"),
"LK" : QT_TRANSLATE_NOOP("ISO", "Sri Lanka"),
"LR" : QT_TRANSLATE_NOOP("ISO", "Liberia"),
"LS" : QT_TRANSLATE_NOOP("ISO", "Lesotho"),
"LT" : QT_TRANSLATE_NOOP("ISO", "Lithuania"),
"LU" : QT_TRANSLATE_NOOP("ISO", "Luxembourg"),
"LV" : QT_TRANSLATE_NOOP("ISO", "Latvia"),
"LY" : QT_TRANSLATE_NOOP("ISO", "Libya"),
"MA" : QT_TRANSLATE_NOOP("ISO", "Morocco"),
"MC" : QT_TRANSLATE_NOOP("ISO", "Monaco"),
"MD" : QT_TRANSLATE_NOOP("ISO", "Republic of Moldova"),
"ME" : QT_TRANSLATE_NOOP("ISO", "Montenegro"),
"MF" : QT_TRANSLATE_NOOP("ISO", "Saint Martin (French part)"),
"MG" : QT_TRANSLATE_NOOP("ISO", "Madagascar"),
"MH" : QT_TRANSLATE_NOOP("ISO", "Marshall Islands"),
"MK" : QT_TRANSLATE_NOOP("ISO", "The Former Yugoslav Republic of Macedonia"),
"ML" : QT_TRANSLATE_NOOP("ISO", "Mali"),
"MM" : QT_TRANSLATE_NOOP("ISO", "Myanmar"),
"MN" : QT_TRANSLATE_NOOP("ISO", "Mongolia"),
"MO" : QT_TRANSLATE_NOOP("ISO", "Macao"),
"MP" : QT_TRANSLATE_NOOP("ISO", "Northern Mariana Islands"),
"MQ" : QT_TRANSLATE_NOOP("ISO", "Martinique"),
"MR" : QT_TRANSLATE_NOOP("ISO", "Mauritania"),
"MS" : QT_TRANSLATE_NOOP("ISO", "Montserrat"),
"MT" : QT_TRANSLATE_NOOP("ISO", "Malta"),
"MU" : QT_TRANSLATE_NOOP("ISO", "Mauritius"),
"MV" : QT_TRANSLATE_NOOP("ISO", "Maldives"),
"MW" : QT_TRANSLATE_NOOP("ISO", "Malawi"),
"MX" : QT_TRANSLATE_NOOP("ISO", "Mexico"),
"MY" : QT_TRANSLATE_NOOP("ISO", "Malaysia"),
"MZ" : QT_TRANSLATE_NOOP("ISO", "Mozambique"),
"NA" : QT_TRANSLATE_NOOP("ISO", "Namibia"),
"NC" : QT_TRANSLATE_NOOP("ISO", "New Caledonia"),
"NE" : QT_TRANSLATE_NOOP("ISO", "Niger"),
"NF" : QT_TRANSLATE_NOOP("ISO", "Norfolk Island"),
"NG" : QT_TRANSLATE_NOOP("ISO", "Nigeria"),
"NI" : QT_TRANSLATE_NOOP("ISO", "Nicaragua"),
"NL" : QT_TRANSLATE_NOOP("ISO", "Netherlands"),
"NO" : QT_TRANSLATE_NOOP("ISO", "Norway"),
"NP" : QT_TRANSLATE_NOOP("ISO", "Nepal"),
"NR" : QT_TRANSLATE_NOOP("ISO", "Nauru"),
"NU" : QT_TRANSLATE_NOOP("ISO", "Niue"),
"NZ" : QT_TRANSLATE_NOOP("ISO", "New Zealand"),
"OM" : QT_TRANSLATE_NOOP("ISO", "Oman"),
"PA" : QT_TRANSLATE_NOOP("ISO", "Panama"),
"PE" : QT_TRANSLATE_NOOP("ISO", "Peru"),
"PF" : QT_TRANSLATE_NOOP("ISO", "French Polynesia"),
"PG" : QT_TRANSLATE_NOOP("ISO", "Papua New Guinea"),
"PH" : QT_TRANSLATE_NOOP("ISO", "Philippines"),
"PK" : QT_TRANSLATE_NOOP("ISO", "Pakistan"),
"PL" : QT_TRANSLATE_NOOP("ISO", "Poland"),
"PM" : QT_TRANSLATE_NOOP("ISO", "Saint Pierre and Miquelon"),
"PN" : QT_TRANSLATE_NOOP("ISO", "Pitcairn"),
"PR" : QT_TRANSLATE_NOOP("ISO", "Puerto Rico"),
"PS" : QT_TRANSLATE_NOOP("ISO", "State of Palestine"),
"PT" : QT_TRANSLATE_NOOP("ISO", "Portugal"),
"PW" : QT_TRANSLATE_NOOP("ISO", "Palau"),
"PY" : QT_TRANSLATE_NOOP("ISO", "Paraguay"),
"QA" : QT_TRANSLATE_NOOP("ISO", "Qatar"),
"RE" : QT_TRANSLATE_NOOP("ISO", "R\u00e9union"),
"RO" : QT_TRANSLATE_NOOP("ISO", "Romania"),
"RS" : QT_TRANSLATE_NOOP("ISO", "Serbia"),
"RU" : QT_TRANSLATE_NOOP("ISO", "Russian Federation"),
"RW" : QT_TRANSLATE_NOOP("ISO", "Rwanda"),
"SA" : QT_TRANSLATE_NOOP("ISO", "Saudi Arabia"),
"SB" : QT_TRANSLATE_NOOP("ISO", "Solomon Islands"),
"SC" : QT_TRANSLATE_NOOP("ISO", "Seychelles"),
"SD" : QT_TRANSLATE_NOOP("ISO", "Sudan"),
"SE" : QT_TRANSLATE_NOOP("ISO", "Sweden"),
"SG" : QT_TRANSLATE_NOOP("ISO", "Singapore"),
"SH" : QT_TRANSLATE_NOOP("ISO", "Saint Helena, Ascension and Tristan da Cunha"),
"SI" : QT_TRANSLATE_NOOP("ISO", "Slovenia"),
"SJ" : QT_TRANSLATE_NOOP("ISO", "Svalbard and Jan Mayen"),
"SK" : QT_TRANSLATE_NOOP("ISO", "Slovakia"),
"SL" : QT_TRANSLATE_NOOP("ISO", "Sierra Leone"),
"SM" : QT_TRANSLATE_NOOP("ISO", "San Marino"),
"SN" : QT_TRANSLATE_NOOP("ISO", "Senegal"),
"SO" : QT_TRANSLATE_NOOP("ISO", "Somalia"),
"SR" : QT_TRANSLATE_NOOP("ISO", "Suriname"),
"SS" : QT_TRANSLATE_NOOP("ISO", "South Sudan"),
"ST" : QT_TRANSLATE_NOOP("ISO", "Sao Tome and Principe"),
"SV" : QT_TRANSLATE_NOOP("ISO", "El Salvador"),
"SX" : QT_TRANSLATE_NOOP("ISO", "Sint Maarten"),
"SY" : QT_TRANSLATE_NOOP("ISO", "Syrian Arab Republic"),
"SZ" : QT_TRANSLATE_NOOP("ISO", "Swaziland"),
"TC" : QT_TRANSLATE_NOOP("ISO", "Turks and Caicos Islands"),
"TD" : QT_TRANSLATE_NOOP("ISO", "Chad"),
"TF" : QT_TRANSLATE_NOOP("ISO", "French Southern Territories"),
"TG" : QT_TRANSLATE_NOOP("ISO", "Togo"),
"TH" : QT_TRANSLATE_NOOP("ISO", "Thailand"),
"TJ" : QT_TRANSLATE_NOOP("ISO", "Tajikistan"),
"TK" : QT_TRANSLATE_NOOP("ISO", "Tokelau"),
"TL" : QT_TRANSLATE_NOOP("ISO", "Timor-Leste"),
"TM" : QT_TRANSLATE_NOOP("ISO", "Turkmenistan"),
"TN" : QT_TRANSLATE_NOOP("ISO", "Tunisia"),
"TO" : QT_TRANSLATE_NOOP("ISO", "Tonga"),
"TR" : QT_TRANSLATE_NOOP("ISO", "Turkey"),
"TT" : QT_TRANSLATE_NOOP("ISO", "Trinidad and Tobago"),
"TV" : QT_TRANSLATE_NOOP("ISO", "Tuvalu"),
"TW" : QT_TRANSLATE_NOOP("ISO", "Taiwan, Province of China"),
"TZ" : QT_TRANSLATE_NOOP("ISO", "United Republic of Tanzania"),
"UA" : QT_TRANSLATE_NOOP("ISO", "Ukraine"),
"UG" : QT_TRANSLATE_NOOP("ISO", "Uganda"),
"UM" : QT_TRANSLATE_NOOP("ISO", "United States Minor Outlying Islands"),
"US" : QT_TRANSLATE_NOOP("ISO", "United States"),
"UY" : QT_TRANSLATE_NOOP("ISO", "Uruguay"),
"UZ" : QT_TRANSLATE_NOOP("ISO", "Uzbekistan"),
"VA" : QT_TRANSLATE_NOOP("ISO", "Holy See (Vatican City State)"),
"VC" : QT_TRANSLATE_NOOP("ISO", "Saint Vincent and the Grenadines"),
"VE" : QT_TRANSLATE_NOOP("ISO", "Bolivarian Republic of Venezuela"),
"VG" : QT_TRANSLATE_NOOP("ISO", "British Virgin Islands"),
"VI" : QT_TRANSLATE_NOOP("ISO", "U.S. Virgin Islands"),
"VN" : QT_TRANSLATE_NOOP("ISO", "Viet Nam"),
"VU" : QT_TRANSLATE_NOOP("ISO", "Vanuatu"),
"WF" : QT_TRANSLATE_NOOP("ISO", "Wallis and Futuna"),
"WS" : QT_TRANSLATE_NOOP("ISO", "Samoa"),
"YE" : QT_TRANSLATE_NOOP("ISO", "Yemen"),
"YT" : QT_TRANSLATE_NOOP("ISO", "Mayotte"),
"ZA" : QT_TRANSLATE_NOOP("ISO", "South Africa"),
"ZM" : QT_TRANSLATE_NOOP("ISO", "Zambia"),
"ZW" : QT_TRANSLATE_NOOP("ISO", "Zimbabwe"),
}
# END Class isoCountry
+16 -5
View File
@@ -24,9 +24,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from functools import partial
import logging
import os
from PyQt5.QtCore import QCoreApplication
from nw.constants import nwAlert
from nw.common import isHandle
from nw.constants import nwItemLayout, nwItemClass
@@ -48,6 +51,7 @@ class NWDoc():
# Internal Mapping
self.makeAlert = self.theParent.makeAlert
self.tr = partial(QCoreApplication.translate, self.__class__.__name__)
return
@@ -111,7 +115,7 @@ class NWDoc():
theText += inFile.read()
except Exception as e:
self.makeAlert(["Failed to open document file.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Failed to open document file."), str(e)], nwAlert.ERROR)
# Note: Document must be cleared in case of an io error,
# or else the auto-save or save will try to overwrite it
# with an empty file. Return None to alert the caller.
@@ -124,7 +128,10 @@ class NWDoc():
return ""
if showStatus and not isOrphan:
self.theParent.setStatus("Opened Document: %s" % self._theItem.itemName)
self.theParent.setStatus(
self.tr("{0}: {1}").format(
self.tr("Opened Document"),
self._theItem.itemName))
return theText
@@ -158,7 +165,7 @@ class NWDoc():
outFile.write(docMeta)
outFile.write(docText)
except Exception as e:
self.makeAlert(["Could not save document.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Could not save document."), str(e)], nwAlert.ERROR)
return False
# If we're here, the file was successfully saved, so we can
@@ -168,7 +175,10 @@ class NWDoc():
os.rename(docTemp, docPath)
if self._theItem is not None:
self.theParent.setStatus("Saved Document: %s" % self._theItem.itemName)
self.theParent.setStatus(
self.tr("{0}: {1}").format(
self.tr("Saved Document"),
self._theItem.itemName))
return True
@@ -191,7 +201,8 @@ class NWDoc():
os.unlink(chkFile)
logger.debug("Deleted: %s" % chkFile)
except Exception as e:
self.makeAlert(["Could not delete document file.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Could not delete document file."), str(e)],
nwAlert.ERROR)
return False
return True
+9 -2
View File
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from functools import partial
import nw
import logging
import json
@@ -31,6 +32,8 @@ import os
from time import time
from PyQt5.QtCore import QCoreApplication
from nw.constants import (
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert
)
@@ -62,9 +65,13 @@ class NWIndex():
# TimeStamps
self._timeNovel = 0
self._timeNotes = 0
self._timeNotes = 0
self._timeIndex = 0
self.tr = partial(QCoreApplication.translate, self.__class__.__name__)
self.clearIndex()
return
##
@@ -229,7 +236,7 @@ class NWIndex():
if self.indexBroken:
self.clearIndex()
self.theParent.makeAlert(
"The project index is outdated or broken. Rebuilding index.",
self.tr("The project index is outdated or broken. Rebuilding index."),
nwAlert.WARN
)
+127 -107
View File
@@ -24,6 +24,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from functools import partial
from PyQt5.QtCore import QCoreApplication
import nw
import logging
import os
@@ -97,11 +100,12 @@ class NWProject():
self.notesWCount = 0 # Total number of words in note files
self.doBackup = True # Run project backup on exit
# Set Defaults
self.clearProject()
# Internal Mapping
self.makeAlert = self.theParent.makeAlert
self.tr = partial(QCoreApplication.translate, self.__class__.__name__)
# Set Defaults
self.clearProject()
return
@@ -157,7 +161,7 @@ class NWProject():
trashHandle = self.projTree.trashRoot()
if trashHandle is None:
newItem = NWItem(self)
newItem.setName("Trash")
newItem.setName(self.tr("Trash"))
newItem.setType(nwItemType.TRASH)
newItem.setClass(nwItemClass.TRASH)
self.projTree.append(None, None, newItem)
@@ -197,7 +201,7 @@ class NWProject():
self.autoReplace = {}
self.titleFormat = {
"title" : r"%title%",
"chapter" : r"Chapter %ch%: %title%",
"chapter" : self.tr(r"Chapter %ch%: %title%"),
"unnumbered" : r"%title%",
"scene" : r"* * *",
"section" : r"",
@@ -205,15 +209,15 @@ class NWProject():
self.spellCheck = False
self.autoOutline = True
self.statusItems = NWStatus()
self.statusItems.addEntry("New", (100, 100, 100))
self.statusItems.addEntry("Note", (200, 50, 0))
self.statusItems.addEntry("Draft", (200, 150, 0))
self.statusItems.addEntry("Finished", (50, 200, 0))
self.statusItems.addEntry(self.tr("New"), (100, 100, 100))
self.statusItems.addEntry(self.tr("Note"), (200, 50, 0))
self.statusItems.addEntry(self.tr("Draft"), (200, 150, 0))
self.statusItems.addEntry(self.tr("Finished"), (50, 200, 0))
self.importItems = NWStatus()
self.importItems.addEntry("New", (100, 100, 100))
self.importItems.addEntry("Minor", (200, 50, 0))
self.importItems.addEntry("Major", (200, 150, 0))
self.importItems.addEntry("Main", (50, 200, 0))
self.importItems.addEntry(self.tr("New"), (100, 100, 100))
self.importItems.addEntry(self.tr("Minor"), (200, 50, 0))
self.importItems.addEntry(self.tr("Major"), (200, 150, 0))
self.importItems.addEntry(self.tr("Main"), (50, 200, 0))
self.lastEdited = None
self.lastViewed = None
self.lastWCount = 0
@@ -239,7 +243,7 @@ class NWProject():
# Project Settings
projPath = projData.get("projPath", None)
projName = projData.get("projName", "New Project")
projName = projData.get("projName", self.tr("New Project"))
projTitle = projData.get("projTitle", "")
projAuthors = projData.get("projAuthors", "")
@@ -256,7 +260,7 @@ class NWProject():
titlePage = "# %s\n\n" % (self.bookTitle if self.bookTitle else self.projName)
if self.bookAuthors:
titlePage = "%sBy %s\n" % (titlePage, ", ".join(self.bookAuthors))
titlePage = "%s%s %s\n" % (titlePage, self.tr("By"), ", ".join(self.bookAuthors))
# Document object for writing files
aDoc = NWDoc(self, self.theParent)
@@ -265,14 +269,14 @@ class NWProject():
# Creating a minimal project with a few root folders and a
# single chapter folder with a single file.
xHandle = {}
xHandle[1] = self.newRoot("Novel", nwItemClass.NOVEL)
xHandle[2] = self.newRoot("Plot", nwItemClass.PLOT)
xHandle[3] = self.newRoot("Characters", nwItemClass.CHARACTER)
xHandle[4] = self.newRoot("World", nwItemClass.WORLD)
xHandle[5] = self.newFile("Title Page", nwItemClass.NOVEL, xHandle[1])
xHandle[6] = self.newFolder("New Chapter", nwItemClass.NOVEL, xHandle[1])
xHandle[7] = self.newFile("New Chapter", nwItemClass.NOVEL, xHandle[6])
xHandle[8] = self.newFile("New Scene", nwItemClass.NOVEL, xHandle[6])
xHandle[1] = self.newRoot(self.tr("Novel"), nwItemClass.NOVEL)
xHandle[2] = self.newRoot(self.tr("Plot"), nwItemClass.PLOT)
xHandle[3] = self.newRoot(self.tr("Characters"), nwItemClass.CHARACTER)
xHandle[4] = self.newRoot(self.tr("World"), nwItemClass.WORLD)
xHandle[5] = self.newFile(self.tr("Title Page"), nwItemClass.NOVEL, xHandle[1])
xHandle[6] = self.newFolder(self.tr("New Chapter"), nwItemClass.NOVEL, xHandle[1])
xHandle[7] = self.newFile(self.tr("New Chapter"), nwItemClass.NOVEL, xHandle[6])
xHandle[8] = self.newFile(self.tr("New Scene"), nwItemClass.NOVEL, xHandle[6])
self.projTree.setFileItemLayout(xHandle[5], nwItemLayout.TITLE)
self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER)
@@ -282,11 +286,11 @@ class NWProject():
aDoc.clearDocument()
aDoc.openDocument(xHandle[7], showStatus=False)
aDoc.saveDocument("## New Chapter\n\n")
aDoc.saveDocument("## %s\n\n" % self.tr("New Chapter"))
aDoc.clearDocument()
aDoc.openDocument(xHandle[8], showStatus=False)
aDoc.saveDocument("### New Scene\n\n")
aDoc.saveDocument("### %s\n\n" % self.tr("New Scene"))
aDoc.clearDocument()
elif popCustom:
@@ -295,13 +299,14 @@ class NWProject():
# wizard's custom page.
# Create root folders
nHandle = self.newRoot("Novel", nwItemClass.NOVEL)
nHandle = self.newRoot(self.tr("Novel"), nwItemClass.NOVEL)
for newRoot in projData.get("addRoots", []):
if newRoot in nwItemClass:
self.newRoot(nwLabels.CLASS_NAME[newRoot], newRoot)
self.newRoot(QCoreApplication.translate(
"Constant", nwLabels.CLASS_NAME[newRoot]), newRoot)
# Create a title page
tHandle = self.newFile("Title Page", nwItemClass.NOVEL, nHandle)
tHandle = self.newFile(self.tr("Title Page"), nwItemClass.NOVEL, nHandle)
self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE)
aDoc.openDocument(tHandle, showStatus=False)
@@ -316,7 +321,7 @@ class NWProject():
# Create chapters
if numChapters > 0:
for ch in range(numChapters):
chTitle = "Chapter %d" % (ch+1)
chTitle = self.tr("Chapter {0}").format(f"{ch+1:d}")
pHandle = nHandle
if chFolders:
pHandle = self.newFolder(chTitle, nwItemClass.NOVEL, nHandle)
@@ -331,7 +336,7 @@ class NWProject():
# Create chapter scenes
if numScenes > 0:
for sc in range(numScenes):
scTitle = "Scene %d.%d" % (ch+1, sc+1)
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, pHandle)
aDoc.openDocument(sHandle, showStatus=False)
@@ -341,7 +346,7 @@ class NWProject():
# Create scenes (no chapters)
elif numScenes > 0:
for sc in range(numScenes):
scTitle = "Scene %d" % (sc+1)
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, nHandle)
aDoc.openDocument(sHandle, showStatus=False)
@@ -365,7 +370,7 @@ class NWProject():
if not os.path.isfile(fileName):
fileName = os.path.join(fileName, nwFiles.PROJ_FILE)
if not os.path.isfile(fileName):
self.makeAlert("File not found: %s" % fileName, nwAlert.ERROR)
self.makeAlert(self.tr("File not found: {0}").format(fileName), nwAlert.ERROR)
return False
self.clearProject()
@@ -414,16 +419,18 @@ class NWProject():
try:
nwXML = etree.parse(fileName)
except Exception as e:
self.makeAlert(["Failed to parse project xml.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Failed to parse project xml."), str(e)], nwAlert.ERROR)
# Trying to open backup file instead
backFile = fileName[:-3]+"bak"
if os.path.isfile(backFile):
self.makeAlert("Attempting to open backup project file instead.", nwAlert.INFO)
self.makeAlert(self.tr("Attempting to open backup project file instead."),
nwAlert.INFO)
try:
nwXML = etree.parse(backFile)
except Exception as e:
self.makeAlert(["Failed to parse project xml.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Failed to parse project xml."), str(e)],
nwAlert.ERROR)
self.clearProject()
return False
else:
@@ -433,9 +440,9 @@ class NWProject():
xRoot = nwXML.getroot()
nwxRoot = xRoot.tag
appVersion = xRoot.attrib.get("appVersion", "Unknown")
appVersion = xRoot.attrib.get("appVersion", self.tr("Unknown"))
hexVersion = xRoot.attrib.get("hexVersion", "0x0")
fileVersion = xRoot.attrib.get("fileVersion", "Unknown")
fileVersion = xRoot.attrib.get("fileVersion", self.tr("Unknown"))
# The following are deprecated and will be removed
# The settings have been moved to the <project> tag
@@ -451,7 +458,7 @@ class NWProject():
if not nwxRoot == "novelWriterXML":
self.makeAlert(
"Project file does not appear to be a novelWriterXML file.",
self.tr("Project file does not appear to be a novelWriterXML file."),
nwAlert.ERROR
)
self.clearProject()
@@ -470,24 +477,23 @@ class NWProject():
# read the file. Introduced in version 0.10.
if fileVersion == "1.0":
msgYes = self.theParent.askQuestion("Old Project Version", (
"The project file and data is created by a novelWriter version "
"lower than 0.7. Do you want to upgrade the project to the "
"most recent format?<br><br>Note that after the upgrade, you "
"cannot open the project with an older version of novelWriter "
"any more, so make sure you have a recent backup."
))
msgYes = self.theParent.askQuestion(self.tr("Old Project Version"), (
"%s<br><br>%s" % (
self.tr("The project file and data is created by a novelWriter version "
"lower than 0.7. Do you want to upgrade the project to the "
"most recent format?"),
self.tr("Note that after the upgrade, you "
"cannot open the project with an older version of novelWriter "
"any more, so make sure you have a recent backup."))))
if not msgYes:
self.clearProject()
return False
elif fileVersion != "1.1" and fileVersion != "1.2":
self.makeAlert((
"Unknown or unsupported novelWriter project file format. "
"The project cannot be opened by this version of novelWriter. "
"The file was saved with novelWriter version {vers:s}."
).format(
vers = appVersion,
self.tr("Unknown or unsupported novelWriter project file format. "
"The project cannot be opened by this version of novelWriter. "
"The file was saved with novelWriter version {0}.").format(appVersion)
), nwAlert.ERROR)
self.clearProject()
return False
@@ -496,13 +502,14 @@ class NWProject():
# =========================
if hexToInt(hexVersion) > hexToInt(nw.__hexversion__):
msgYes = self.theParent.askQuestion("Version Conflict", (
"This project was saved by a newer version of novelWriter, version %s. "
"This is version %s. If you continue to open the project, some attributes "
"and settings may not be preserved, but the overall project should be fine. "
"Continue opening the project?"
) % (
appVersion, nw.__version__
msgYes = self.theParent.askQuestion(self.tr("Version Conflict"), (
self.tr("This project was saved by a newer version of novelWriter, version "
"{new_version}. This is version {version}. If you continue to open the "
"project, some attributes and settings may not be preserved, but the "
"overall project should be fine. Continue opening the project?")
).format(
new_version = appVersion,
version = nw.__version__
))
if not msgYes:
self.clearProject()
@@ -602,7 +609,9 @@ class NWProject():
self.mainConf.updateRecentCache(self.projPath, self.projName, self.lastWCount, time())
self.mainConf.saveRecentCache()
self.theParent.setStatus("Opened Project: %s" % self.projName)
self.theParent.setStatus(self.tr("{0}: {1}").format(
self.tr("Opened Project"),
self.projName))
self._scanProjectFolder()
@@ -623,7 +632,7 @@ class NWProject():
"""
if self.projPath is None:
self.makeAlert(
"Project path not set, cannot save project.", nwAlert.ERROR
self.tr("Project path not set, cannot save project."), nwAlert.ERROR
)
return False
@@ -702,7 +711,7 @@ class NWProject():
xml_declaration = True
))
except Exception as e:
self.makeAlert(["Failed to save project.", str(e)], nwAlert.ERROR)
self.makeAlert([self.tr("Failed to save project."), str(e)], nwAlert.ERROR)
return False
# If we're here, the file was successfully saved,
@@ -721,7 +730,9 @@ class NWProject():
self.mainConf.saveRecentCache()
self._writeLockFile()
self.theParent.setStatus("Saved Project: %s" % self.projName)
self.theParent.setStatus(self.tr("{0}: {1}").format(
self.tr("Saved Project"),
self.projName))
self.setProjectChanged(False)
return True
@@ -773,26 +784,26 @@ class NWProject():
return False
logger.info("Backing up project")
self.theParent.setStatus("Backing up project ...")
self.theParent.setStatus(self.tr("Backing up project ..."))
if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
self.theParent.makeAlert((
"Cannot backup project because no backup path is set. "
"Please set a valid backup location in Tools > Preferences."
self.tr("Cannot backup project because no backup path is set. "
"Please set a valid backup location in Tools > Preferences.")
), nwAlert.ERROR)
return False
if self.projName is None or self.projName == "":
self.theParent.makeAlert((
"Cannot backup project because no project name is set. "
"Please set a Working Title in Project > Project Settings."
self.tr("Cannot backup project because no project name is set. "
"Please set a Working Title in Project > Project Settings.")
), nwAlert.ERROR)
return False
if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences."
self.tr("Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences.")
), nwAlert.ERROR)
return False
@@ -804,20 +815,20 @@ class NWProject():
logger.debug("Created folder %s" % baseDir)
except Exception as e:
self.theParent.makeAlert(
["Could not create backup folder.", str(e)],
[self.tr("Could not create backup folder."), str(e)],
nwAlert.ERROR
)
return False
if os.path.commonpath([self.projPath, baseDir]) == self.projPath:
self.theParent.makeAlert((
"Cannot backup project because the backup path is within the "
"project folder to be backed up. Please choose a different "
"backup path in Tools > Preferences."
self.tr("Cannot backup project because the backup path is within the "
"project folder to be backed up. Please choose a different "
"backup path in Tools > Preferences.")
), nwAlert.ERROR)
return False
archName = "Backup from %s" % formatTimeStamp(time(), fileSafe=True)
archName = self.tr("Backup from {0}").format(formatTimeStamp(time(), fileSafe=True))
baseName = os.path.join(baseDir, archName)
try:
@@ -827,18 +838,19 @@ class NWProject():
logger.info("Backup written to: %s" % archName)
if doNotify:
self.theParent.makeAlert(
"Backup archive file written to: %s.zip" % os.path.join(cleanName, archName),
self.tr("Backup archive file written to: {0}").format(
f"{os.path.join(cleanName, archName)}.zip"),
nwAlert.INFO
)
except Exception as e:
self.theParent.makeAlert(
["Could not write backup archive.", str(e)],
[self.tr("Could not write backup archive."), str(e)],
nwAlert.ERROR
)
return False
self.theParent.setStatus("Project backed up to '%s.zip'" % baseName)
self.theParent.setStatus(self.tr("Project backed up to '{0}'").format(f"{baseName}.zip"))
return True
@@ -853,8 +865,9 @@ class NWProject():
logger.error("No project path set for the example project")
return False
srcSample = os.path.abspath(os.path.join(self.mainConf.appRoot, "sample"))
pkgSample = os.path.join(self.mainConf.assetPath, "sample.zip")
srcSample = os.path.abspath(os.path.join(self.mainConf.appRoot,
self.tr("sample")))
pkgSample = os.path.join(self.mainConf.assetPath, "%s.zip" % self.tr("sample"))
isSuccess = False
if os.path.isfile(pkgSample):
@@ -865,7 +878,7 @@ class NWProject():
isSuccess = True
except Exception as e:
self.makeAlert(
["Failed to create a new example project.", str(e)], nwAlert.ERROR
[self.tr("Failed to create a new example project."), str(e)], nwAlert.ERROR
)
elif os.path.isdir(srcSample):
@@ -876,8 +889,8 @@ class NWProject():
dstProj = os.path.join(projPath, nwFiles.PROJ_FILE)
shutil.copyfile(srcProj, dstProj)
srcContent = os.path.join(srcSample, "content")
dstContent = os.path.join(projPath, "content")
srcContent = os.path.join(srcSample, self.tr("content"))
dstContent = os.path.join(projPath, self.tr("content"))
for srcFile in os.listdir(srcContent):
srcDoc = os.path.join(srcContent, srcFile)
dstDoc = os.path.join(dstContent, srcFile)
@@ -887,13 +900,13 @@ class NWProject():
except Exception as e:
self.makeAlert(
["Failed to create a new example project.", str(e)], nwAlert.ERROR
[self.tr("Failed to create a new example project."), str(e)], nwAlert.ERROR
)
else:
self.makeAlert((
"Failed to create a new example project. Could not find the "
"necessary files. They seem to be missing from this installation."
self.tr("Failed to create a new example project. Could not find the "
"necessary files. They seem to be missing from this installation.")
), nwAlert.ERROR)
if isSuccess:
@@ -925,15 +938,15 @@ class NWProject():
logger.debug("Created folder %s" % projPath)
except Exception as e:
self.theParent.makeAlert((
["Could not create new project folder.", str(e)]
[self.tr("Could not create new project folder."), str(e)]
), nwAlert.ERROR)
return False
if os.path.isdir(projPath):
if os.listdir(self.projPath):
self.theParent.makeAlert((
"New project folder is not empty. "
"Each project requires a dedicated project folder."
self.tr("New project folder is not empty. "
"Each project requires a dedicated project folder.")
), nwAlert.ERROR)
return False
@@ -982,15 +995,15 @@ class NWProject():
if doBackup:
if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"You must set a valid backup path in preferences to use "
"the automatic project backup feature."
self.tr("You must set a valid backup path in preferences to use "
"the automatic project backup feature.")
), nwAlert.WARN)
return False
if self.projName == "":
self.theParent.makeAlert((
"You must set a valid project name in project settings to "
"use the automatic project backup feature."
self.tr("You must set a valid project name in project settings to "
"use the automatic project backup feature.")
), nwAlert.WARN)
return False
@@ -1330,7 +1343,7 @@ class NWProject():
# Report status
if len(orphanFiles) > 0:
self.makeAlert(
"Found %d orphaned file(s) in project folder." % len(orphanFiles),
self.tr("Found {0} orphaned file(s) in project folder.").format(len(orphanFiles)),
nwAlert.WARN
)
else:
@@ -1352,10 +1365,12 @@ class NWProject():
oName, oParent, oClass, oLayout = aDoc.getMeta()
if oName:
oName = "Recovered: %s" % oName.lstrip("Recovered: ")
oName = self.tr("{0}: {1}").format(
self.tr("Recovered"),
oName.lstrip(self.tr("{0}: ").format(self.tr("Recovered"))))
else:
nOrph += 1
oName = "Recovered File %d" % nOrph
oName = self.tr("Recovered File {0}").format(nOrph)
# Recover file meta data
if oClass is None:
@@ -1383,8 +1398,8 @@ class NWProject():
if noWhere:
self.makeAlert((
"One or more orphaned files could not be added back into the "
"project. Make sure at least a Novel root folder exists."
self.tr("One or more orphaned files could not be added back into the "
"project. Make sure at least a Novel root folder exists.")
), nwAlert.WARN)
return True
@@ -1403,9 +1418,13 @@ class NWProject():
if not isFile:
# It's a new file, so add a header
if self.lastWCount > 0:
outFile.write("# Offset %d\n" % self.lastWCount)
outFile.write("# %s\n" % self.tr("Offset {0}").format(self.lastWCount))
outFile.write("# %-17s %-19s %8s %8s %8s\n" % (
"Start Time", "End Time", "Novel", "Notes", "Idle"
self.tr("Start Time"),
self.tr("End Time"),
self.tr("Novel"),
self.tr("Notes"),
self.tr("Idle"),
))
outFile.write("%-19s %-19s %8d %8d %8d\n" % (
@@ -1432,7 +1451,7 @@ class NWProject():
"""
theData = os.path.join(self.projPath, theFolder)
if not os.path.isdir(theData):
errList.append("Not a folder: %s" % theData)
errList.append(self.tr("Not a folder: {0}").format(theData))
return errList
logger.info("Old data folder %s found" % theFolder)
@@ -1452,10 +1471,10 @@ class NWProject():
newPath = os.path.join(self.projContent, tHandle+".nwd")
try:
os.rename(theFile, newPath)
logger.info("Moved file: %s" % theFile)
logger.info("New location: %s" % newPath)
logger.info(self.tr("{0}: {1}").format(self.tr("Moved file"), theFile))
logger.info(self.tr("{0}: {1}").format(self.tr("New location"), newPath))
except Exception:
errList.append("Could not move: %s" % theFile)
errList.append(self.tr("{0}: {1}").format(self.tr("Could not move"), theFile))
logger.error("Could not move: %s" % theFile)
nw.logException()
@@ -1464,7 +1483,8 @@ class NWProject():
os.unlink(theFile)
logger.info("Deleted file: %s" % theFile)
except Exception:
errList.append("Could not delete: %s" % theFile)
errList.append(self.tr("{0}: {1}").format(
self.tr("Could not delete"), theFile))
logger.error("Could not delete: %s" % theFile)
nw.logException()
@@ -1479,7 +1499,7 @@ class NWProject():
os.rmdir(theData)
logger.info("Removed folder: %s" % theFolder)
except Exception:
errList.append("Failed to remove: %s" % theFolder)
errList.append(self.tr("{0}: {1}").format(self.tr("Failed to remove"), theFolder))
logger.error("Failed to remove: %s" % theFolder)
nw.logException()
@@ -1489,9 +1509,9 @@ class NWProject():
"""Move an item that doesn't belong in the project folder to
a junk folder.
"""
theJunk = os.path.join(self.projPath, "junk")
theJunk = os.path.join(self.projPath, self.tr("junk"))
if not self._checkFolder(theJunk):
return "Could not make folder: %s" % theJunk
return self.tr("{0}: {1}").format(self.tr("Could not make folder"), theJunk)
theSrc = os.path.join(theDir, theItem)
theDst = os.path.join(theJunk, theItem)
@@ -1502,7 +1522,7 @@ class NWProject():
except Exception:
logger.error("Could not move item %s to junk." % theSrc)
nw.logException()
return "Could not move item %s to junk." % theSrc
return self.tr("Could not move item {0} to junk.").format(theSrc)
return ""
+6 -3
View File
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from PyQt5.QtCore import QCoreApplication
import nw
import logging
import os
@@ -94,7 +95,7 @@ class NWSpellCheck():
"""Translate a language tag to something more user friendly.
"""
spBits = spTag.split("_")
spLang = isoLanguage.ISO_639_1.get(spBits[0], spBits[0])
spLang = QCoreApplication.translate("ISO", isoLanguage.ISO_639_1.get(spBits[0], spBits[0]))
if len(spBits) > 1:
spLang += " (%s)" % spBits[1]
return spLang
@@ -332,7 +333,9 @@ class NWSpellSimple(NWSpellCheck):
if fExt != ".dict":
continue
spName = "%s [%s]" % (self.expandLanguage(fRoot), nwConst.SP_INTERNAL)
spName = "%s [%s]" % (
self.expandLanguage(fRoot),
QCoreApplication.translate("Constant", nwConst.SP_INTERNAL))
retList.append((fRoot, spName))
return retList
@@ -341,6 +344,6 @@ class NWSpellSimple(NWSpellCheck):
"""Return the tag and provider of the currently loaded
dictionary.
"""
return self.theLang, nwConst.SP_INTERNAL
return self.theLang, QCoreApplication.translate("Constant", nwConst.SP_INTERNAL)
# END Class NWSpellSimple
+9 -3
View File
@@ -406,9 +406,15 @@ class ToHtml(Tokenizer):
"""Apply HTML formatting to synopsis.
"""
if self.genMode == self.M_PREVIEW:
return "<p class='comment'><span class='synopsis'>Synopsis:</span> %s</p>\n" % tText
return "<p class='comment'><span class='synopsis'>%s:</span> %s</p>\n" % (
self.tr("Synopsis"),
tText
)
else:
return "<p class='synopsis'><strong>Synopsis:</strong> %s</p>\n" % tText
return "<p class='synopsis'><strong>%s:</strong> %s</p>\n" % (
self.tr("Synopsis"),
tText
)
def _formatComments(self, tText):
"""Apply HTML formatting to comments.
@@ -416,7 +422,7 @@ class ToHtml(Tokenizer):
if self.genMode == self.M_PREVIEW:
return "<p class='comment'>%s</p>\n" % tText
else:
return "<p class='comment'><strong>Comment:</strong> %s</p>\n" % tText
return "<p class='comment'><strong>%s:</strong> %s</p>\n" % (self.tr("Comment"), tText)
def _formatKeywords(self, tText):
"""Apply HTML formatting to keywords.
+9 -5
View File
@@ -24,11 +24,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from functools import partial
import logging
import re
from operator import itemgetter
from PyQt5.QtCore import QRegularExpression
from PyQt5.QtCore import QCoreApplication, QRegularExpression
from nw.core.document import NWDoc
from nw.core.tools import numberToWord, numberToRoman
@@ -141,6 +142,8 @@ class Tokenizer():
# Error Handling
self.errData = []
self.tr = partial(QCoreApplication.translate, self.__class__.__name__)
return
##
@@ -249,7 +252,7 @@ class Tokenizer():
if theItem.itemType != nwItemType.ROOT:
return False
theTitle = "Notes: %s" % theItem.itemName
theTitle = self.tr("{0}: {1}").format(self.tr("Notes"), theItem.itemName)
self.theTokens = []
self.theTokens.append((
self.T_TITLE, 0, theTitle, None, self.A_PBB | self.A_CENTRE
@@ -278,10 +281,11 @@ class Tokenizer():
docSize = len(self.theText)
if docSize > nwConst.MAX_DOCSIZE:
errVal = "Document '%s' is too big (%.2f MB). Skipping." % (
self.theItem.itemName, docSize/1.0e6
errVal = self.tr("Document '{doc_name}' is too big ({doc_size}). Skipping.").format(
doc_name = self.theItem.itemName,
doc_size = f"{docSize/1.0e6:.2f} MB"
)
self.theText = "# ERROR\n\n%s\n\n" % errVal
self.theText = "# %s\n\n%s\n\n" % (self.tr("ERROR"), errVal)
self.errData.append(errVal)
self.isNone = self.theItem.itemLayout == nwItemLayout.NO_LAYOUT
+1 -1
View File
@@ -127,7 +127,7 @@ def numberToWord(numVal, theLanguage):
"""Wrapper for converting numbers to words for chapter headings.
"""
numWord = ""
if theLanguage == "en":
if theLanguage == "en": # TODO: I18N
numWord = _numberToWordEN(numVal)
else:
numWord = _numberToWordEN(numVal)
+10 -2
View File
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from functools import partial
import nw
import logging
import os
@@ -32,6 +33,8 @@ from lxml import etree
from hashlib import sha256
from time import time
from PyQt5.QtCore import QCoreApplication
from nw.core.item import NWItem
from nw.common import checkHandle
from nw.constants import (
@@ -79,6 +82,8 @@ class NWTree():
self._handleSeed = None # Used for generating handles for testing
self.tr = partial(QCoreApplication.translate, self.__class__.__name__)
return
##
@@ -195,11 +200,14 @@ class NWTree():
tocText = os.path.join(self.theProject.projPath, nwFiles.TOC_TXT)
with open(tocText, mode="w", encoding="utf8") as outFile:
outFile.write("\n")
outFile.write("Table of Contents\n")
outFile.write("%s\n" % self.tr("Table of Contents"))
outFile.write("=================\n")
outFile.write("\n")
outFile.write("%-25s %-9s %-10s %s\n" % (
"File Name", "Class", "Layout", "Document Label"
self.tr("File Name"),
self.tr("Class"),
self.tr("Layout"),
self.tr("Document Label"),
))
outFile.write("-"*tocLen + "\n")
outFile.write("\n".join(tocList))
+1
View File
@@ -68,6 +68,7 @@ class NWErrorMessage(QDialog):
self.msgBody.setReadOnly(True)
self.btnBox = QDialogButtonBox(QDialogButtonBox.Close)
self.btnBox.button(QDialogButtonBox.Close).setText(self.tr("Close"))
self.btnBox.rejected.connect(self._doClose)
# Assemble
+71 -66
View File
@@ -55,14 +55,14 @@ class GuiAbout(QDialog):
self.innerBox = QHBoxLayout()
self.innerBox.setSpacing(self.mainConf.pxInt(16))
self.setWindowTitle("About novelWriter")
self.setWindowTitle(self.tr("About novelWriter"))
self.setMinimumWidth(self.mainConf.pxInt(650))
self.setMinimumHeight(self.mainConf.pxInt(600))
nPx = self.mainConf.pxInt(96)
self.nwIcon = QLabel()
self.nwIcon.setPixmap(self.theParent.theTheme.getPixmap("novelwriter", (nPx, nPx)))
self.lblName = QLabel("<b>novelWriter</b>")
self.lblName = QLabel("<b>%s</b>" % self.tr("novelWriter"))
self.lblVers = QLabel("v%s" % nw.__version__)
self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x"))
@@ -90,13 +90,14 @@ class GuiAbout(QDialog):
# Main Tab Area
self.tabBox = QTabWidget()
self.tabBox.addTab(self.pageAbout, "About")
self.tabBox.addTab(self.pageNotes, "Release")
self.tabBox.addTab(self.pageLicense, "License")
self.tabBox.addTab(self.pageAbout, self.tr("About"))
self.tabBox.addTab(self.pageNotes, self.tr("Release"))
self.tabBox.addTab(self.pageLicense, self.tr("License"))
self.innerBox.addWidget(self.tabBox)
# OK Button
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("OK"))
self.buttonBox.accepted.connect(self._doClose)
self.outerBox.addLayout(self.innerBox)
@@ -132,28 +133,30 @@ class GuiAbout(QDialog):
"""Generate the content for the About page.
"""
listPrefix = "&nbsp;&nbsp;&bull;&nbsp;&nbsp;"
aboutMsg = (
"<h2>About novelWriter</h2>"
"<p>{copyright:s}.</p>"
"<p>Website: <a href='{website:s}'>{domain:s}</a></p>"
"<p>novelWriter is a markdown-like text editor designed for "
"organising and writing novels. It is written in Python 3 with a "
"Qt5 GUI, using PyQt5.</p>"
"<p>novelWriter is free software: you can redistribute it and/or "
"modify it under the terms of the GNU General Public License as "
"published by the Free Software Foundation, either version 3 of "
"the License, or (at your option) any later version.</p>"
"<p>novelWriter is distributed in the hope that it will be "
"useful, but WITHOUT ANY WARRANTY; without even the implied "
"warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR "
"PURPOSE.</p>"
"<p>See the License tab for the full license text, or visit the "
"GNU website at "
"<a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a> "
"for more details.</p>"
"<h3>Credits</h3>"
"<p>{credits:s}</p>"
).format(
aboutMsg = "".join([
"<h2>%s</h2>" % self.tr("About novelWriter"),
"<p>{copyright:s}.</p>",
"<p>%s</p>" % (self.tr("{0}: {1}").format(
self.tr("Website"),
"<a href=\"{website:s}\">{domain:s}</a>"
)),
"<p>%s</p>" % self.tr("novelWriter is a markdown-like text editor designed for "
"organising and writing novels. It is written in Python 3 with "
"a Qt5 GUI, using PyQt5."),
"<p>%s</p>" % self.tr("novelWriter is free software: you can redistribute it and/or "
"modify it under the terms of the GNU General Public License as "
"published by the Free Software Foundation, either version 3 of "
"the License, or (at your option) any later version."),
"<p>%s</p>" % self.tr("novelWriter is distributed in the hope that it will be "
"useful, but WITHOUT ANY WARRANTY; without even the implied "
"warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR "
"PURPOSE."),
"<p>%s</p>" % (self.tr("See the License tab for the full license text, or visit the "
"GNU website at {0} for more details.").format(
"<a href=\"https://www.gnu.org/licenses/gpl-3.0.html\">GPL v3.0</a>")),
"<h3>%s</h3>" % self.tr("Credits"),
"<p>{credits:s}</p>",
]).format(
copyright = nw.__copyright__,
website = nw.__url__,
domain = nw.__domain__,
@@ -163,50 +166,52 @@ class GuiAbout(QDialog):
theTheme = self.theParent.theTheme
theIcons = self.theParent.theTheme.theIcons
if theTheme.themeName:
aboutMsg += (
"<h4>Theme: {name:s}</h4>"
"<p>"
"<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
aboutMsg += "".join([
("<h4>%s</h4>" % self.tr("{0}: {1}").format(self.tr("Theme"), theTheme.themeName)),
"<p>",
("%s<br/>" % self.tr("<b>{0}:</b> {1}").format(
self.tr("Author"), theTheme.themeAuthor)),
("%s<br/>" % self.tr("<b>{0}:</b> {1}").format(
self.tr("Credit"), theTheme.themeCredit)),
(self.tr("<b>{0}:</b> {1}").format(
self.tr("License"),
"<a href=\"{0}\">{1}</a>".format(
theTheme.themeLicenseUrl, theTheme.themeLicense)
)),
"</p>"
).format(
name = theTheme.themeName,
author = theTheme.themeAuthor,
credit = theTheme.themeCredit,
license = theTheme.themeLicense,
lic_url = theTheme.themeLicenseUrl,
)
])
if theIcons.themeName:
aboutMsg += (
"<h4>Icons: {name:s}</h4>"
"<p>"
"<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
aboutMsg += "".join([
("<h4>%s</h4>" % self.tr("{0}: {1}").format(self.tr("Icons"), theIcons.themeName)),
"<p>",
("%s<br/>" % self.tr("<b>{0}:</b> {1}").format(
self.tr("Author"), theIcons.themeAuthor)),
("%s<br/>" % self.tr("<b>{0}:</b> {1}").format(
self.tr("Credit"), theIcons.themeCredit)),
(self.tr("<b>{0}:</b> {1}").format(
self.tr("License"),
"<a href=\"{0}\">{1}</a>".format(
theIcons.themeLicenseUrl, theIcons.themeLicense)
)),
"</p>"
).format(
name = theIcons.themeName,
author = theIcons.themeAuthor,
credit = theIcons.themeCredit,
license = theIcons.themeLicense,
lic_url = theIcons.themeLicenseUrl,
)
])
if theTheme.syntaxName:
aboutMsg += (
"<h4>Syntax: {name:s}</h4>"
"<p>"
"<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
aboutMsg += "".join([
("<h4>%s</h4>" % self.tr("{0}: {1}").format(
self.tr("Syntax"),
theTheme.syntaxName)),
"<p>",
("%s<br/>" % self.tr("<b>{0}:</b> {1}").format(
self.tr("Author"), theTheme.syntaxAuthor)),
("%s<br/>" % self.tr("<b>{0{0}</b> {{1}").format(
self.tr("Credit"), theTheme.syntaxCredit)),
(self.tr("<b>{0}:</b> {1}").format(
self.tr("License"),
"<a href=\"{0}\">{1}</a>".format(
theTheme.syntaxLicenseUrl, theTheme.syntaxLicense)
)),
"</p>"
).format(
name = theTheme.syntaxName,
author = theTheme.syntaxAuthor,
credit = theTheme.syntaxCredit,
license = theTheme.syntaxLicense,
lic_url = theTheme.syntaxLicenseUrl,
)
])
self.pageAbout.setHtml(aboutMsg)
+92 -84
View File
@@ -84,7 +84,7 @@ class GuiBuildNovel(QDialog):
self.htmlSize = 0 # Size of the html document
self.buildTime = 0 # The timestamp of the last build
self.setWindowTitle("Build Novel Project")
self.setWindowTitle(self.tr("Build Novel Project"))
self.setMinimumWidth(self.mainConf.pxInt(700))
self.setMinimumHeight(self.mainConf.pxInt(600))
@@ -101,26 +101,26 @@ class GuiBuildNovel(QDialog):
# Title Formats
# =============
self.titleGroup = QGroupBox("Title Formats for Novel Files", self)
self.titleGroup = QGroupBox(self.tr("Title Formats for Novel Files"), self)
self.titleForm = QGridLayout(self)
self.titleGroup.setLayout(self.titleForm)
fmtHelp = (
r"<b>Formatting Codes:</b><br>"
r"%title% for the title as set in the document<br>"
r"%ch% for chapter number (1, 2, 3)<br>"
r"%chw% for chapter number as a word (one, two)<br>"
r"%chI% for chapter number in upper case Roman<br>"
r"%chi% for chapter number in lower case Roman<br>"
r"%sc% for scene number within chapter<br>"
r"%sca% for scene number within novel"
fmtHelp = "<br>".join(
"<b>%s</b>" % self.tr("{0}:").format("Formatting Codes"),
self.tr("{0} for the title as set in the document").format(r"%title%"),
self.tr("{0} for chapter number (1, 2, 3)").format(r"%ch%"),
self.tr("{0} for chapter number as a word (one, two)").format(r"%chw%"),
self.tr("{0} for chapter number in upper case Roman").format(r"%chI%"),
self.tr("{0} for chapter number in lower case Roman").format(r"%chi%"),
self.tr("{0} for scene number within chapter").format(r"%sc%"),
self.tr("{0} for scene number within novel").format(r"%sca%"),
)
fmtScHelp = (
r"<br><br>"
r"Leave blank to skip this heading, or set to a static text, like "
r"for instance '* * *', to make a separator. The separator will "
r"be centred automatically and only appear between sections of "
r"the same type."
"<br><br>%s" %
self.tr("Leave blank to skip this heading, or set to a static text, like "
"for instance '{0}', to make a separator. The separator will "
"be centred automatically and only appear between sections of "
"the same type.").format("* * *")
)
xFmt = self.mainConf.pxInt(100)
@@ -176,11 +176,11 @@ class GuiBuildNovel(QDialog):
self.boxSection = QHBoxLayout()
self.boxSection.addWidget(self.fmtSection)
titleLabel = QLabel("Title")
chapterLabel = QLabel("Chapter")
unnumbLabel = QLabel("Unnumbered")
sceneLabel = QLabel("Scene")
sectionLabel = QLabel("Section")
titleLabel = QLabel(self.tr("Title"))
chapterLabel = QLabel(self.tr("Chapter"))
unnumbLabel = QLabel(self.tr("Unnumbered"))
sceneLabel = QLabel(self.tr("Scene"))
sectionLabel = QLabel(self.tr("Section"))
self.titleForm.addWidget(titleLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.titleForm.addLayout(self.boxTitle, 0, 1, 1, 1, Qt.AlignRight)
@@ -199,7 +199,7 @@ class GuiBuildNovel(QDialog):
# Font Options
# ============
self.fontGroup = QGroupBox("Font Options", self)
self.fontGroup = QGroupBox(self.tr("Font Options"), self)
self.fontForm = QGridLayout(self)
self.fontGroup.setLayout(self.fontForm)
@@ -237,11 +237,11 @@ class GuiBuildNovel(QDialog):
self.boxFont = QHBoxLayout()
self.boxFont.addWidget(self.textFont)
fontFamilyLabel = QLabel("Font family")
fontSizeLabel = QLabel("Font size")
lineHeightLabel = QLabel("Line height")
justifyLabel = QLabel("Justify text")
stylingLabel = QLabel("Disable styling")
fontFamilyLabel = QLabel(self.tr("Font family"))
fontSizeLabel = QLabel(self.tr("Font size"))
lineHeightLabel = QLabel(self.tr("Line height"))
justifyLabel = QLabel(self.tr("Justify text"))
stylingLabel = QLabel(self.tr("Disable styling"))
self.fontForm.addWidget(fontFamilyLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.fontForm.addLayout(self.boxFont, 0, 1, 1, 1, Qt.AlignRight)
@@ -283,7 +283,7 @@ class GuiBuildNovel(QDialog):
# Include Options
# ===============
self.textGroup = QGroupBox("Include Options", self)
self.textGroup = QGroupBox(self.tr("Include Options"), self)
self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm)
@@ -307,10 +307,10 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "incBodyText", True)
)
synopsisLabel = QLabel("Include synopsis")
commentsLabel = QLabel("Include comments")
keywordsLabel = QLabel("Include keywords")
bodyLabel = QLabel("Include body text")
synopsisLabel = QLabel(self.tr("Include synopsis"))
commentsLabel = QLabel(self.tr("Include comments"))
keywordsLabel = QLabel(self.tr("Include keywords"))
bodyLabel = QLabel(self.tr("Include body text"))
self.textForm.addWidget(synopsisLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
@@ -327,37 +327,37 @@ class GuiBuildNovel(QDialog):
# File Filter Options
# ===================
self.fileGroup = QGroupBox("File Filter Options", self)
self.fileGroup = QGroupBox(self.tr("File Filter Options"), self)
self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm)
self.novelFiles = QSwitch(width=wS, height=hS)
self.novelFiles.setToolTip(
"Include files with layouts 'Book', 'Page', 'Partition', "
"'Chapter', 'Unnumbered', and 'Scene'."
self.tr("Include files with layouts 'Book', 'Page', 'Partition', "
"'Chapter', 'Unnumbered', and 'Scene'.")
)
self.novelFiles.setChecked(
self.optState.getBool("GuiBuildNovel", "addNovel", True)
)
self.noteFiles = QSwitch(width=wS, height=hS)
self.noteFiles.setToolTip("Include files with layout 'Note'.")
self.noteFiles.setToolTip(self.tr("Include files with layout 'Note'."))
self.noteFiles.setChecked(
self.optState.getBool("GuiBuildNovel", "addNotes", False)
)
self.ignoreFlag = QSwitch(width=wS, height=hS)
self.ignoreFlag.setToolTip(
"Ignore the 'Include when building project' setting and include "
"all files in the output."
self.tr("Ignore the 'Include when building project' setting and include "
"all files in the output.")
)
self.ignoreFlag.setChecked(
self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
)
novelLabel = QLabel("Include novel files")
notesLabel = QLabel("Include note files")
exportLabel = QLabel("Ignore export flag")
novelLabel = QLabel(self.tr("Include novel files"))
notesLabel = QLabel(self.tr("Include note files"))
exportLabel = QLabel(self.tr("Ignore export flag"))
self.fileForm.addWidget(novelLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
@@ -372,7 +372,7 @@ class GuiBuildNovel(QDialog):
# Export Options
# ==============
self.exportGroup = QGroupBox("Export Options", self)
self.exportGroup = QGroupBox(self.tr("Export Options"), self)
self.exportForm = QGridLayout(self)
self.exportGroup.setLayout(self.exportForm)
@@ -386,8 +386,8 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "replaceUCode", False)
)
tabsLabel = QLabel("Replace tabs with spaces")
uCodeLabel = QLabel("Replace Unicode in HTML")
tabsLabel = QLabel(self.tr("Replace tabs with spaces"))
uCodeLabel = QLabel(self.tr("Replace Unicode in HTML"))
self.exportForm.addWidget(tabsLabel, 0, 0, 1, 1, Qt.AlignLeft)
self.exportForm.addWidget(self.replaceTabs, 0, 1, 1, 1, Qt.AlignRight)
@@ -402,7 +402,7 @@ class GuiBuildNovel(QDialog):
self.buildProgress = QProgressBar()
self.buildNovel = QPushButton("Build Preview")
self.buildNovel = QPushButton(self.tr("Build Preview"))
self.buildNovel.clicked.connect(self._buildPreview)
# Action Buttons
@@ -413,14 +413,14 @@ class GuiBuildNovel(QDialog):
# Printing
self.printMenu = QMenu(self)
self.btnPrint = QPushButton("Print")
self.btnPrint = QPushButton(self.tr("Print"))
self.btnPrint.setMenu(self.printMenu)
self.printSend = QAction("Print Preview", self)
self.printSend = QAction(self.tr("Print Preview"), self)
self.printSend.triggered.connect(self._printDocument)
self.printMenu.addAction(self.printSend)
self.printFile = QAction("Print to PDF", self)
self.printFile = QAction(self.tr("Print to PDF"), self)
self.printFile.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
self.printMenu.addAction(self.printFile)
@@ -430,39 +430,46 @@ class GuiBuildNovel(QDialog):
self.btnSave = QPushButton("Save As")
self.btnSave.setMenu(self.saveMenu)
self.saveODT = QAction("Open Document (.odt)", self)
self.saveODT = QAction(self.tr("{0} ({1})").format(self.tr("Open Document"), ".odt"), self)
self.saveODT.triggered.connect(lambda: self._saveDocument(self.FMT_ODT))
self.saveMenu.addAction(self.saveODT)
self.saveFODT = QAction("Flat Open Document (.fodt)", self)
self.saveFODT = QAction(
self.tr("{0} ({1})").format(self.tr("Flat Open Document"), ".fodt"), self)
self.saveFODT.triggered.connect(lambda: self._saveDocument(self.FMT_FODT))
self.saveMenu.addAction(self.saveFODT)
self.saveHTM = QAction("novelWriter HTML (.htm)", self)
self.saveHTM = QAction(self.tr("{0} ({1})").format(
self.tr("novelWriter HTML"), ".htm"), self)
self.saveHTM.triggered.connect(lambda: self._saveDocument(self.FMT_HTM))
self.saveMenu.addAction(self.saveHTM)
self.saveNWD = QAction("novelWriter Markdown (.nwd)", self)
self.saveNWD = QAction(self.tr("{0} ({1})").format(
self.tr("novelWriter Markdown"), ".nwd"), self)
self.saveNWD.triggered.connect(lambda: self._saveDocument(self.FMT_NWD))
self.saveMenu.addAction(self.saveNWD)
self.saveMD = QAction("Standard Markdown (.md)", self)
self.saveMD = QAction(
self.tr("{0} ({1})").format(self.tr("Standard Markdown"), ".md"), self)
self.saveMD.triggered.connect(lambda: self._saveDocument(self.FMT_MD))
self.saveMenu.addAction(self.saveMD)
self.saveGH = QAction("GitHub Markdown (.md)", self)
self.saveGH = QAction(
self.tr("{0} ({1})").format(self.tr("GitHub Markdown"), ".md"), self)
self.saveGH.triggered.connect(lambda: self._saveDocument(self.FMT_GH))
self.saveMenu.addAction(self.saveGH)
self.saveJsonH = QAction("JSON + novelWriter HTML (.json)", self)
self.saveJsonH = QAction(self.tr("{0} ({1})").format(
self.tr("JSON + novelWriter HTML"), ".json"), self)
self.saveJsonH.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_H))
self.saveMenu.addAction(self.saveJsonH)
self.saveJsonM = QAction("JSON + novelWriters Markdown (.json)", self)
self.saveJsonM = QAction(self.tr("{0} ({1})").format(
self.tr("JSON + novelWriters Markdown"), ".json"), self)
self.saveJsonM.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_M))
self.saveMenu.addAction(self.saveJsonM)
self.btnClose = QPushButton("Close")
self.btnClose = QPushButton(self.tr("Close"))
self.btnClose.clicked.connect(self._doClose)
self.buttonBox.addWidget(self.btnSave)
@@ -567,7 +574,7 @@ class GuiBuildNovel(QDialog):
self.docView.setContent(self.htmlText, self.buildTime)
else:
self.docView.setText(
"Failed to generate preview. The result is too big."
self.tr("Failed to generate preview. The result is too big.")
)
else:
@@ -736,10 +743,9 @@ class GuiBuildNovel(QDialog):
logger.debug("Built project in %.3f ms" % (1000*(tEnd - tStart)))
if bldObj.errData:
self.theParent.makeAlert((
"There were problems when building the project:"
"<br>-&nbsp;%s"
) % "<br>-&nbsp;".join(bldObj.errData), nwAlert.ERROR)
self.theParent.makeAlert("%s:<br>-&nbsp;%s" % (
self.tr("There were problems when building the project"),
"<br>-&nbsp;".join(bldObj.errData)), nwAlert.ERROR)
return
@@ -796,39 +802,39 @@ class GuiBuildNovel(QDialog):
if theFmt == self.FMT_ODT:
fileExt = "odt"
textFmt = "Open Document"
textFmt = self.tr("Open Document")
elif theFmt == self.FMT_FODT:
fileExt = "fodt"
textFmt = "Flat Open Document"
textFmt = self.tr("Flat Open Document")
elif theFmt == self.FMT_HTM:
fileExt = "htm"
textFmt = "Plain HTML"
textFmt = self.tr("Plain HTML")
elif theFmt == self.FMT_NWD:
fileExt = "nwd"
textFmt = "novelWriter Markdown"
textFmt = self.tr("novelWriter Markdown")
elif theFmt == self.FMT_MD:
fileExt = "md"
textFmt = "Standard Markdown"
textFmt = self.tr("Standard Markdown")
elif theFmt == self.FMT_GH:
fileExt = "md"
textFmt = "GitHub Markdown"
textFmt = self.tr("GitHub Markdown")
elif theFmt == self.FMT_JSON_H:
fileExt = "json"
textFmt = "JSON + novelWriter HTML"
textFmt = self.tr("JSON + novelWriter HTML")
elif theFmt == self.FMT_JSON_M:
fileExt = "json"
textFmt = "JSON + novelWriter Markdown"
textFmt = self.tr("JSON + novelWriter Markdown")
elif theFmt == self.FMT_PDF:
fileExt = "pdf"
textFmt = "PDF"
textFmt = self.tr("PDF")
else:
return False
@@ -848,7 +854,7 @@ class GuiBuildNovel(QDialog):
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.DontUseNativeDialog
savePath, _ = QFileDialog.getSaveFileName(
self, "Save Document As", savePath, options=dlgOpt
self, self.tr("Save Document As"), savePath, options=dlgOpt
)
if not savePath:
return False
@@ -985,20 +991,20 @@ class GuiBuildNovel(QDialog):
errMsg - str(e)
else:
errMsg = "Unknown format"
errMsg = self.tr("Unknown format")
# Report to user
if wSuccess:
self.theParent.makeAlert(
"%s file successfully written to:<br> %s" % (
textFmt, savePath
"%s<br> %s" % (
self.tr("{0} file successfully written to:").format(textFmt),
savePath
), nwAlert.INFO
)
else:
self.theParent.makeAlert(
"Failed to write %s file. %s" % (
textFmt, errMsg
), nwAlert.ERROR
self.tr("Failed to write {0} file. {1}").format(
textFmt, errMsg), nwAlert.ERROR
)
return wSuccess
@@ -1194,9 +1200,9 @@ class GuiBuildNovelDocView(QTextBrowser):
self.qDocument = self.document()
self.qDocument.setDocumentMargin(self.mainConf.getTextMargin())
self.setPlaceholderText(
"This area will show the content of the document to be "
"exported or printed. Press the \"Build Preview\" button "
"to generate content."
self.tr("This area will show the content of the document to be "
"exported or printed. Press the \"Build Preview\" button "
"to generate content.")
)
theFont = QFont()
@@ -1227,7 +1233,8 @@ class GuiBuildNovelDocView(QTextBrowser):
fPx = int(1.1*self.theTheme.fontPixelSize)
self.theTitle = QLabel("<b>Build Time:</b> Unknown", self)
self.theTitle = QLabel(self.tr("<b>{0}:</b> {1}".format(
self.tr("Build Time"), self.tr("Unknown"))), self)
self.theTitle.setIndent(0)
self.theTitle.setAutoFillBackground(True)
self.theTitle.setAlignment(Qt.AlignCenter)
@@ -1341,8 +1348,9 @@ class GuiBuildNovelDocView(QTextBrowser):
fuzzyTime(time() - self.buildTime)
)
else:
strBuildTime = "Unknown"
self.theTitle.setText("<b>Build Time:</b> %s" % strBuildTime)
strBuildTime = self.tr("Unknown")
self.theTitle.setText(self.tr("<b>{0}:</b> {1}").format(
self.tr("Build Time"), strBuildTime))
def _updateDocMargins(self):
"""Automatically adjust the header to fill the top of the
+2
View File
@@ -500,6 +500,8 @@ class QuotesDialog(QDialog):
# Buttons
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doAccept)
self.buttonBox.rejected.connect(self._doReject)
+85 -62
View File
@@ -36,7 +36,7 @@ import logging
from time import time
from PyQt5.QtCore import (
Qt, QSize, QTimer, pyqtSlot, pyqtSignal, QRegExp, QRegularExpression,
QCoreApplication, Qt, QSize, QTimer, pyqtSlot, pyqtSignal, QRegExp, QRegularExpression,
QPointF, QObject, QRunnable, QPropertyAnimation
)
from PyQt5.QtGui import (
@@ -294,10 +294,14 @@ class GuiDocEditor(QTextEdit):
docSize = len(theDoc)
if docSize > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert((
"The document you are trying to open is too big. "
"The document size is %.2f\u202fMB. "
"The maximum size allowed is %.2f\u202fMB."
) % (docSize/1.0e6, nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR)
self.tr("The document you are trying to open is too big. "
"The document size is {doc_size}. "
"The maximum size allowed is {max_size}.").
format(
doc_size=self.tr("{0}\u202fMB").format(f"{docSize/1.0e6:.2f}"),
max_size=self.tr("{0}\u202fMB").format(f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}")
)
), nwAlert.ERROR)
self.clearEditor()
return False
@@ -381,10 +385,14 @@ class GuiDocEditor(QTextEdit):
docSize = len(theText)
if docSize > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert((
"The text you are trying to add is too big. "
"The text size is %.2f\u202fMB. "
"The maximum size allowed is %.2f\u202fMB."
) % (docSize/1.0e6, nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR)
self.tr("The text you are trying to add is too big. "
"The text size is {text_size}. "
"The maximum size allowed is {max_size}.").
format(
text_size=self.tr("{0}\u202fMB").format(f"{docSize/1.0e6:.2f}"),
max_size=self.tr("{0}\u202fMB").format(f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}")
)
), nwAlert.ERROR)
return False
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
@@ -594,7 +602,10 @@ class GuiDocEditor(QTextEdit):
aLang, aName = self.theDict.describeDict()
self.theParent.statusBar.setLanguage(
aLang, "%s [%s]" % (self.mainConf.spellTool.title(), aName.title())
aLang,
self.tr("{0} [{1}]").format(
self.mainConf.spellTool.title(),
aName.title())
)
if not self.bigDoc:
@@ -644,7 +655,7 @@ class GuiDocEditor(QTextEdit):
logger.debug(
"Document highlighted in %.3f ms" % (1000*(afTime-bfTime))
)
self.theParent.statusBar.showMessage("Spell check complete")
self.theParent.statusBar.showMessage(self.tr("Spell check complete"))
return True
@@ -743,11 +754,12 @@ class GuiDocEditor(QTextEdit):
return False
msgBox = QMessageBox()
msgBox.information(self, "File Location", (
"File details for the currently open file<br>"
"Handle: {handle:s}<br>"
"Location: {fileLoc:s}"
).format(
msgBox.information(self, self.tr("File Location"), "".join([
(self.tr("{0}<br>").format(self.tr("File details for the currently open file"))),
(self.tr("{0}<br>").format(
self.tr("{0}: {1}").format(self.tr("Handle"), "{handle:s}"))),
(self.tr("{0}: {1}").format(self.tr("Location"), "{fileLoc:s}"))
]).format(
handle = self.theHandle,
fileLoc = str(self.nwDocument.getFileLocation())
))
@@ -934,9 +946,10 @@ class GuiDocEditor(QTextEdit):
if self.qDocument.characterCount() > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert((
"The document has grown too big and you cannot add more text to it. "
"The maximum size of a single novelWriter document is %.2f\u202fMB."
) % (nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR)
self.tr("The document has grown too big and you cannot add more text to it. "
"The maximum size of a single novelWriter document is {max_size}.").
format(max_size=self.tr("{0}\u202fMB").format(f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"))
), nwAlert.ERROR)
self.undo()
return
@@ -966,21 +979,21 @@ class GuiDocEditor(QTextEdit):
# ===========================
if self._followTag(theCursor=posCursor, loadTag=False):
mnuTag = QAction("Follow Tag", mnuContext)
mnuTag = QAction(self.tr("Follow Tag"), mnuContext)
mnuTag.triggered.connect(lambda: self._followTag(theCursor=posCursor))
mnuContext.addAction(mnuTag)
mnuContext.addSeparator()
if userSelection:
mnuCut = QAction("Cut", mnuContext)
mnuCut = QAction(self.tr("Cut"), mnuContext)
mnuCut.triggered.connect(lambda: self.docAction(nwDocAction.CUT))
mnuContext.addAction(mnuCut)
mnuCopy = QAction("Copy", mnuContext)
mnuCopy = QAction(self.tr("Copy"), mnuContext)
mnuCopy.triggered.connect(lambda: self.docAction(nwDocAction.COPY))
mnuContext.addAction(mnuCopy)
mnuPaste = QAction("Paste", mnuContext)
mnuPaste = QAction(self.tr("Paste"), mnuContext)
mnuPaste.triggered.connect(lambda: self.docAction(nwDocAction.PASTE))
mnuContext.addAction(mnuPaste)
@@ -989,17 +1002,17 @@ class GuiDocEditor(QTextEdit):
# Selections
# ==========
mnuSelAll = QAction("Select All", mnuContext)
mnuSelAll = QAction(self.tr("Select All"), mnuContext)
mnuSelAll.triggered.connect(lambda: self.docAction(nwDocAction.SEL_ALL))
mnuContext.addAction(mnuSelAll)
mnuSelWord = QAction("Select Word", mnuContext)
mnuSelWord = QAction(self.tr("Select Word"), mnuContext)
mnuSelWord.triggered.connect(
lambda: self._makePosSelection(QTextCursor.WordUnderCursor, thePos)
)
mnuContext.addAction(mnuSelWord)
mnuSelPara = QAction("Select Paragraph", mnuContext)
mnuSelPara = QAction(self.tr("Select Paragraph"), mnuContext)
mnuSelPara.triggered.connect(
lambda: self._makePosSelection(QTextCursor.BlockUnderCursor, thePos)
)
@@ -1025,7 +1038,7 @@ class GuiDocEditor(QTextEdit):
if spellCheck:
mnuContext.addSeparator()
mnuHead = QAction("Spelling Suggestion(s)", mnuContext)
mnuHead = QAction(self.tr("Spelling Suggestion(s)"), mnuContext)
mnuContext.addAction(mnuHead)
theSuggest = self.theDict.suggestWords(theWord)[:15]
@@ -1037,11 +1050,12 @@ class GuiDocEditor(QTextEdit):
)
mnuContext.addAction(mnuWord)
else:
mnuHead = QAction("%s No Suggestions" % nwUnicode.U_ENDASH, mnuContext)
mnuHead = QAction("%s %s" % (nwUnicode.U_ENDASH, self.tr("No Suggestions")),
mnuContext)
mnuContext.addAction(mnuHead)
mnuContext.addSeparator()
mnuAdd = QAction("Add Word to Dictionary", mnuContext)
mnuAdd = QAction(self.tr("Add Word to Dictionary"), mnuContext)
mnuAdd.triggered.connect(lambda thePos: self._addWord(posCursor))
mnuContext.addAction(mnuAdd)
@@ -1317,7 +1331,8 @@ class GuiDocEditor(QTextEdit):
else:
self.theParent.makeAlert(
"Please selection some text before calling replace quotes.", nwAlert.ERROR
self.tr("Please selection some text before calling replace quotes."),
nwAlert.ERROR
)
return
@@ -1817,12 +1832,12 @@ class GuiDocEditSearch(QFrame):
# ==========
self.searchBox = QLineEdit(self)
self.searchBox.setFont(boxFont)
self.searchBox.setPlaceholderText("Search")
self.searchBox.setPlaceholderText(self.tr("Search"))
self.searchBox.returnPressed.connect(self._doSearch)
self.replaceBox = QLineEdit(self)
self.replaceBox.setFont(boxFont)
self.replaceBox.setPlaceholderText("Replace")
self.replaceBox.setPlaceholderText(self.tr("Replace"))
self.replaceBox.returnPressed.connect(self._doReplace)
self.searchOpt = QToolBar(self)
@@ -1831,44 +1846,45 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.searchOpt.setStyleSheet(r"QToolBar {padding: 0;}")
self.searchLabel = QLabel("Search")
self.searchLabel = QLabel(self.tr("Search"))
self.searchLabel.setFont(boxFont)
self.searchLabel.setIndent(self.mainConf.pxInt(6))
self.toggleCase = QAction("Case Sensitive", self)
self.toggleCase.setToolTip("Match case")
self.toggleCase = QAction(self.tr("Case Sensitive"), self)
self.toggleCase.setToolTip(self.tr("Match case"))
self.toggleCase.setIcon(self.theTheme.getIcon("search_case"))
self.toggleCase.setCheckable(True)
self.toggleCase.setChecked(self.isCaseSense)
self.toggleCase.toggled.connect(self._doToggleCase)
self.searchOpt.addAction(self.toggleCase)
self.toggleWord = QAction("Whole Words Only", self)
self.toggleWord.setToolTip("Match whole words")
self.toggleWord = QAction(self.tr("Whole Words Only"), self)
self.toggleWord.setToolTip(self.tr("Match whole words"))
self.toggleWord.setIcon(self.theTheme.getIcon("search_word"))
self.toggleWord.setCheckable(True)
self.toggleWord.setChecked(self.isWholeWord)
self.toggleWord.toggled.connect(self._doToggleWord)
self.searchOpt.addAction(self.toggleWord)
self.toggleRegEx = QAction("RegEx Mode", self)
self.toggleRegEx.setToolTip("Use regular expressions (requires Qt 5.3)")
self.toggleRegEx = QAction(self.tr("RegEx Mode"), self)
self.toggleRegEx.setToolTip(self.tr("Use regular expressions (requires Qt {0})").format(
"5.3"))
self.toggleRegEx.setIcon(self.theTheme.getIcon("search_regex"))
self.toggleRegEx.setCheckable(True)
self.toggleRegEx.setChecked(self.isRegEx)
self.toggleRegEx.toggled.connect(self._doToggleRegEx)
self.searchOpt.addAction(self.toggleRegEx)
self.toggleLoop = QAction("Loop Search", self)
self.toggleLoop.setToolTip("Loop the search when reaching the end")
self.toggleLoop = QAction(self.tr("Loop Search"), self)
self.toggleLoop.setToolTip(self.tr("Loop the search when reaching the end"))
self.toggleLoop.setIcon(self.theTheme.getIcon("search_loop"))
self.toggleLoop.setCheckable(True)
self.toggleLoop.setChecked(self.doLoop)
self.toggleLoop.toggled.connect(self._doToggleLoop)
self.searchOpt.addAction(self.toggleLoop)
self.toggleProject = QAction("Search Next File", self)
self.toggleProject.setToolTip("Continue searching in the next file")
self.toggleProject = QAction(self.tr("Search Next File"), self)
self.toggleProject.setToolTip(self.tr("Continue searching in the next file"))
self.toggleProject.setIcon(self.theTheme.getIcon("search_project"))
self.toggleProject.setCheckable(True)
self.toggleProject.setChecked(self.doNextFile)
@@ -1877,8 +1893,8 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.addSeparator()
self.toggleMatchCap = QAction("Preserve Case", self)
self.toggleMatchCap.setToolTip("Preserve case on replace")
self.toggleMatchCap = QAction(self.tr("Preserve Case"), self)
self.toggleMatchCap.setToolTip(self.tr("Preserve case on replace"))
self.toggleMatchCap.setIcon(self.theTheme.getIcon("search_preserve"))
self.toggleMatchCap.setCheckable(True)
self.toggleMatchCap.setChecked(self.doMatchCap)
@@ -1887,8 +1903,8 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.addSeparator()
self.cancelSearch = QAction("Close Search", self)
self.cancelSearch.setToolTip("Close the search box [Esc]")
self.cancelSearch = QAction(self.tr("Close Search"), self)
self.cancelSearch.setToolTip(self.tr("Close the search box [{0}]").format("Esc"))
self.cancelSearch.setIcon(self.theTheme.getIcon("search_cancel"))
self.cancelSearch.triggered.connect(self._doClose)
self.searchOpt.addAction(self.cancelSearch)
@@ -1900,18 +1916,18 @@ class GuiDocEditSearch(QFrame):
self.showReplace = QToolButton(self)
self.showReplace.setArrowType(Qt.RightArrow)
self.showReplace.setCheckable(True)
self.showReplace.setToolTip("Show/hide the replace text box")
self.showReplace.setToolTip(self.tr("Show/hide the replace text box"))
self.showReplace.setStyleSheet(r"QToolButton {border: none; background: transparent;}")
self.showReplace.toggled.connect(self._doToggleReplace)
self.searchButton = QPushButton(self.theTheme.getIcon("search"), "")
self.searchButton.setFixedSize(QSize(bPx, bPx))
self.searchButton.setToolTip("Find in current document")
self.searchButton.setToolTip(self.tr("Find in current document"))
self.searchButton.clicked.connect(self._doSearch)
self.replaceButton = QPushButton(self.theTheme.getIcon("search-replace"), "")
self.replaceButton.setFixedSize(QSize(bPx, bPx))
self.replaceButton.setToolTip("Find and replace in current document")
self.replaceButton.setToolTip(self.tr("Find and replace in current document"))
self.replaceButton.clicked.connect(self._doReplace)
self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignLeft)
@@ -2204,7 +2220,7 @@ class GuiDocEditHeader(QWidget):
self.editButton.setStyleSheet(buttonStyle)
self.editButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.editButton.setVisible(False)
self.editButton.setToolTip("Edit document meta")
self.editButton.setToolTip(self.tr("Edit document meta"))
self.editButton.clicked.connect(self._editDocument)
self.searchButton = QToolButton(self)
@@ -2215,7 +2231,7 @@ class GuiDocEditHeader(QWidget):
self.searchButton.setStyleSheet(buttonStyle)
self.searchButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.searchButton.setVisible(False)
self.searchButton.setToolTip("Search document")
self.searchButton.setToolTip(self.tr("Search document"))
self.searchButton.clicked.connect(self._searchDocument)
self.minmaxButton = QToolButton(self)
@@ -2226,7 +2242,7 @@ class GuiDocEditHeader(QWidget):
self.minmaxButton.setStyleSheet(buttonStyle)
self.minmaxButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.minmaxButton.setVisible(False)
self.minmaxButton.setToolTip("Toggle Focus Mode")
self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode"))
self.minmaxButton.clicked.connect(self._minmaxDocument)
self.closeButton = QToolButton(self)
@@ -2237,7 +2253,7 @@ class GuiDocEditHeader(QWidget):
self.closeButton.setStyleSheet(buttonStyle)
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.closeButton.setVisible(False)
self.closeButton.setToolTip("Close the document")
self.closeButton.setToolTip(self.tr("Close the document"))
self.closeButton.clicked.connect(self._closeDocument)
# Assemble Layout
@@ -2413,7 +2429,7 @@ class GuiDocEditFooter(QWidget):
self.statusIcon.setFixedHeight(self.sPx)
self.statusIcon.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.statusText = QLabel("Status")
self.statusText = QLabel(self.tr("Status"))
self.statusText.setIndent(0)
self.statusText.setMargin(0)
self.statusText.setContentsMargins(0, 0, 0, 0)
@@ -2429,7 +2445,7 @@ class GuiDocEditFooter(QWidget):
self.linesIcon.setFixedHeight(self.sPx)
self.linesIcon.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.linesText = QLabel("Line: 0")
self.linesText = QLabel(self.tr("{0}: {1}").format(self.tr("Line"), "0"))
self.linesText.setIndent(0)
self.linesText.setMargin(0)
self.linesText.setContentsMargins(0, 0, 0, 0)
@@ -2445,7 +2461,7 @@ class GuiDocEditFooter(QWidget):
self.wordsIcon.setFixedHeight(self.sPx)
self.wordsIcon.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.wordsText = QLabel("Words: 0")
self.wordsText = QLabel(self.tr("{0}: {1}").format(self.tr("Words"), "0"))
self.wordsText.setIndent(0)
self.wordsText.setMargin(0)
self.wordsText.setContentsMargins(0, 0, 0, 0)
@@ -2532,8 +2548,10 @@ class GuiDocEditFooter(QWidget):
theIcon = self.theParent.importIcons[iStatus]
sIcon = theIcon.pixmap(self.sPx, self.sPx)
sClass = nwLabels.CLASS_NAME[self.theItem.itemClass]
sLayout = nwLabels.LAYOUT_NAME[self.theItem.itemLayout]
sClass = QCoreApplication.translate(
"Constant", nwLabels.CLASS_NAME[self.theItem.itemClass])
sLayout = QCoreApplication.translate(
"Constant", nwLabels.LAYOUT_NAME[self.theItem.itemLayout])
sText = f"{self.theItem.itemStatus} / {sClass} / {sLayout}"
self.statusIcon.setPixmap(sIcon)
@@ -2552,7 +2570,9 @@ class GuiDocEditFooter(QWidget):
iLine = theCursor.blockNumber() + 1
iDist = 100*iLine/self.docEditor.qDocument.blockCount()
self.linesText.setText(f"Line: {iLine:n} ({iDist:.0f}\u202f%)")
self.linesText.setText(
self.tr("{0}: {1} ({2}\u202f%%)".format(
self.tr("Line"), f"{iLine:n}", f"{iDist:.0f}")))
return
@@ -2566,10 +2586,13 @@ class GuiDocEditFooter(QWidget):
wCount = self.theItem.wordCount
wDiff = wCount - self.theItem.initCount
self.wordsText.setText(f"Words: {wCount:n} ({wDiff:+n})")
self.wordsText.setText(
self.tr("{0}: {1} ({2})".format(
self.tr("Words"), f"{wCount:n}", f"{wDiff:+n}")))
byteSize = self.docEditor.qDocument.characterCount()
self.wordsText.setToolTip(f"Document size is {byteSize:n} bytes")
self.wordsText.setToolTip(
(self.tr("Document size is {0} bytes").format(f"{byteSize:n}")))
return
+9 -7
View File
@@ -53,11 +53,11 @@ class GuiDocMerge(QDialog):
self.sourceItem = None
self.outerBox = QVBoxLayout()
self.setWindowTitle("Merge Documents")
self.setWindowTitle(self.tr("Merge Documents"))
self.headLabel = QLabel("<b>Documents to Merge</b>")
self.headLabel = QLabel("<b>%s</b>" % self.tr("Documents to Merge"))
self.helpLabel = QHelpLabel(
"Drag and drop items to change the order.", self.theParent.theTheme.helpText
self.tr("Drag and drop items to change the order."), self.theParent.theTheme.helpText
)
self.listBox = QListWidget()
@@ -66,6 +66,8 @@ class GuiDocMerge(QDialog):
self.listBox.setMinimumHeight(self.mainConf.pxInt(180))
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doMerge)
self.buttonBox.rejected.connect(self._doClose)
@@ -103,7 +105,7 @@ class GuiDocMerge(QDialog):
if len(finalOrder) == 0:
self.theParent.makeAlert((
"No source documents found. Nothing to do."
self.tr("No source documents found. Nothing to do.")
), nwAlert.ERROR)
return
@@ -115,14 +117,14 @@ class GuiDocMerge(QDialog):
if self.sourceItem is None:
self.theParent.makeAlert((
"No source document selected. Nothing to do."
self.tr("No source document selected. Nothing to do.")
), nwAlert.ERROR)
return
srcItem = self.theProject.projTree[self.sourceItem]
if srcItem is None:
self.theParent.makeAlert((
"Could not parse source document."
self.tr("Could not parse source document.")
), nwAlert.ERROR)
return
@@ -165,7 +167,7 @@ class GuiDocMerge(QDialog):
return
if nwItem.itemType is not nwItemType.FOLDER:
self.theParent.makeAlert((
"Element selected in the project tree must be a folder."
self.tr("Element selected in the project tree must be a folder.")
), nwAlert.ERROR)
return
+22 -19
View File
@@ -56,11 +56,12 @@ class GuiDocSplit(QDialog):
self.sourceItem = None
self.outerBox = QVBoxLayout()
self.setWindowTitle("Split Document")
self.setWindowTitle(self.tr("Split Document"))
self.headLabel = QLabel("<b>Document Headers</b>")
self.headLabel = QLabel("<b>%s</b>" % self.tr("Document Headers"))
self.helpLabel = QHelpLabel(
"Select the maximum level to split into files.", self.theParent.theTheme.helpText
self.tr("Select the maximum level to split into files."),
self.theParent.theTheme.helpText
)
self.listBox = QListWidget()
@@ -69,10 +70,10 @@ class GuiDocSplit(QDialog):
self.listBox.setMinimumHeight(self.mainConf.pxInt(180))
self.splitLevel = QComboBox(self)
self.splitLevel.addItem("Split on Header Level 1 (Title)", 1)
self.splitLevel.addItem("Split up to Header Level 2 (Chapter)", 2)
self.splitLevel.addItem("Split up to Header Level 3 (Scene)", 3)
self.splitLevel.addItem("Split up to Header Level 4 (Section)", 4)
self.splitLevel.addItem(self.tr("Split on Header Level 1 (Title)"), 1)
self.splitLevel.addItem(self.tr("Split up to Header Level 2 (Chapter)"), 2)
self.splitLevel.addItem(self.tr("Split up to Header Level 3 (Scene)"), 3)
self.splitLevel.addItem(self.tr("Split up to Header Level 4 (Section)"), 4)
spIndex = self.splitLevel.findData(
self.optState.getInt("GuiDocSplit", "spLevel", 3)
)
@@ -81,6 +82,8 @@ class GuiDocSplit(QDialog):
self.splitLevel.currentIndexChanged.connect(self._populateList)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doSplit)
self.buttonBox.rejected.connect(self._doClose)
@@ -116,14 +119,14 @@ class GuiDocSplit(QDialog):
if self.sourceItem is None:
self.theParent.makeAlert((
"No source document selected. Nothing to do."
self.tr("No source document selected. Nothing to do.")
), nwAlert.ERROR)
return
srcItem = self.theProject.projTree[self.sourceItem]
if srcItem is None:
self.theParent.makeAlert((
"Could not parse source document."
self.tr("Could not parse source document.")
), nwAlert.ERROR)
return
@@ -148,7 +151,7 @@ class GuiDocSplit(QDialog):
nFiles = len(finalOrder)
if nFiles == 0:
self.theParent.makeAlert((
"No headers found. Nothing to do."
self.tr("No headers found. Nothing to do.")
), nwAlert.ERROR)
return
@@ -156,17 +159,17 @@ class GuiDocSplit(QDialog):
parTree = self.theProject.projTree.getItemPath(srcItem.itemParent)
if len(parTree) >= nwConst.MAX_DEPTH - 1:
self.theParent.makeAlert((
"Cannot add new folder for the document split. "
"Maximum folder depth has been reached. "
"Please move the file to another level in the project tree."
self.tr("Cannot add new folder for the document split. "
"Maximum folder depth has been reached. "
"Please move the file to another level in the project tree.")
), nwAlert.ERROR)
return
msgYes = self.theParent.askQuestion("Split Document", (
"The document will be split into %d file(s) in a new folder. "
"The original document will remain intact.<br><br>"
"Continue with the splitting process?"
) % nFiles)
msgYes = self.theParent.askQuestion(self.tr("Split Document"), "%s<br><br>%s" % (
self.tr("The document will be split into {0} file(s) in a new folder. "
"The original document will remain intact.", n=nFiles).format(nFiles),
self.tr("Continue with the splitting process?")
))
if not msgYes:
return
@@ -243,7 +246,7 @@ class GuiDocSplit(QDialog):
return
if nwItem.itemType is not nwItemType.FILE:
self.theParent.makeAlert((
"Element selected in the project tree must be a file."
self.tr("Element selected in the project tree must be a file.")
), nwAlert.ERROR)
return
+23 -22
View File
@@ -183,7 +183,7 @@ class GuiDocViewer(QTextBrowser):
except Exception:
logger.error("Failed to generate preview for document with handle '%s'" % tHandle)
nw.logException()
self.setText("An error occurred while generating the preview.")
self.setText(self.tr("An error occurred while generating the preview."))
return False
# Refresh the tab stops
@@ -243,11 +243,11 @@ class GuiDocViewer(QTextBrowser):
logger.debug("Loading document from tag '%s'" % theTag)
tHandle, _, sTitle = self.theParent.theIndex.getTagSource(theTag)
if tHandle is None:
self.theParent.makeAlert((
"Could not find the reference for tag '%s'. It either doesn't "
"exist, or the index is out of date. The index can be updated "
"from the Tools menu, or by pressing F9."
) % theTag, nwAlert.ERROR)
self.theParent.makeAlert(
self.tr("Could not find the reference for tag '{0}'. It either doesn't "
"exist, or the index is out of date. The index can be updated "
"from the Tools menu, or by pressing {1}.").
format(theTag, "F9"), nwAlert.ERROR)
return False
else:
# Let the parent handle the opening as it also ensures that
@@ -415,7 +415,7 @@ class GuiDocViewer(QTextBrowser):
# ===================
if userSelection:
mnuCopy = QAction("Copy", mnuContext)
mnuCopy = QAction(self.tr("Copy"), mnuContext)
mnuCopy.triggered.connect(lambda: self.docAction(nwDocAction.COPY))
mnuContext.addAction(mnuCopy)
@@ -424,17 +424,17 @@ class GuiDocViewer(QTextBrowser):
# Selections
# ==========
mnuSelAll = QAction("Select All", mnuContext)
mnuSelAll = QAction(self.tr("Select All"), mnuContext)
mnuSelAll.triggered.connect(lambda: self.docAction(nwDocAction.SEL_ALL))
mnuContext.addAction(mnuSelAll)
mnuSelWord = QAction("Select Word", mnuContext)
mnuSelWord = QAction(self.tr("Select Word"), mnuContext)
mnuSelWord.triggered.connect(
lambda: self._makePosSelection(QTextCursor.WordUnderCursor, thePos)
)
mnuContext.addAction(mnuSelWord)
mnuSelPara = QAction("Select Paragraph", mnuContext)
mnuSelPara = QAction(self.tr("Select Paragraph"), mnuContext)
mnuSelPara.triggered.connect(
lambda: self._makePosSelection(QTextCursor.BlockUnderCursor, thePos)
)
@@ -740,7 +740,7 @@ class GuiDocViewHeader(QWidget):
self.backButton.setStyleSheet(buttonStyle)
self.backButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.backButton.setVisible(False)
self.backButton.setToolTip("Go backward")
self.backButton.setToolTip(self.tr("Go backward"))
self.backButton.clicked.connect(self.docViewer.navBackward)
self.forwardButton = QToolButton(self)
@@ -751,7 +751,7 @@ class GuiDocViewHeader(QWidget):
self.forwardButton.setStyleSheet(buttonStyle)
self.forwardButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.forwardButton.setVisible(False)
self.forwardButton.setToolTip("Go forward")
self.forwardButton.setToolTip(self.tr("Go forward"))
self.forwardButton.clicked.connect(self.docViewer.navForward)
self.refreshButton = QToolButton(self)
@@ -762,7 +762,7 @@ class GuiDocViewHeader(QWidget):
self.refreshButton.setStyleSheet(buttonStyle)
self.refreshButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.refreshButton.setVisible(False)
self.refreshButton.setToolTip("Reload the document")
self.refreshButton.setToolTip(self.tr("Reload the document"))
self.refreshButton.clicked.connect(self._refreshDocument)
self.closeButton = QToolButton(self)
@@ -773,7 +773,7 @@ class GuiDocViewHeader(QWidget):
self.closeButton.setStyleSheet(buttonStyle)
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.closeButton.setVisible(False)
self.closeButton.setToolTip("Close the document")
self.closeButton.setToolTip(self.tr("Close the document"))
self.closeButton.clicked.connect(self._closeDocument)
# Assemble Layout
@@ -944,7 +944,7 @@ class GuiDocViewFooter(QWidget):
self.showHide.setIconSize(QSize(fPx, fPx))
self.showHide.setFixedSize(QSize(fPx, fPx))
self.showHide.clicked.connect(self._doShowHide)
self.showHide.setToolTip("Show/hide the references panel")
self.showHide.setToolTip(self.tr("Show/hide the references panel"))
# Sticky Button
self.stickyRefs = QToolButton(self)
@@ -956,7 +956,8 @@ class GuiDocViewFooter(QWidget):
self.stickyRefs.setFixedSize(QSize(fPx, fPx))
self.stickyRefs.toggled.connect(self._doToggleSticky)
self.stickyRefs.setToolTip(
"Activate to freeze the content of the references panel when changing document"
self.tr("Activate to freeze the content of the references panel when "
"changing document")
)
# Show Comments
@@ -969,7 +970,7 @@ class GuiDocViewFooter(QWidget):
self.showComments.setIconSize(QSize(fPx, fPx))
self.showComments.setFixedSize(QSize(fPx, fPx))
self.showComments.toggled.connect(self._doToggleComments)
self.showComments.setToolTip("Show comments")
self.showComments.setToolTip(self.tr("Show comments"))
# Show Synopsis
self.showSynopsis = QToolButton(self)
@@ -981,10 +982,10 @@ class GuiDocViewFooter(QWidget):
self.showSynopsis.setIconSize(QSize(fPx, fPx))
self.showSynopsis.setFixedSize(QSize(fPx, fPx))
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
self.showSynopsis.setToolTip("Show synopsis comments")
self.showSynopsis.setToolTip(self.tr("Show synopsis comments"))
# Labels
self.lblRefs = QLabel("References")
self.lblRefs = QLabel(self.tr("References"))
self.lblRefs.setBuddy(self.showHide)
self.lblRefs.setIndent(0)
self.lblRefs.setMargin(0)
@@ -993,7 +994,7 @@ class GuiDocViewFooter(QWidget):
self.lblRefs.setFixedHeight(fPx)
self.lblRefs.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblSticky = QLabel("Sticky")
self.lblSticky = QLabel(self.tr("Sticky"))
self.lblSticky.setBuddy(self.stickyRefs)
self.lblSticky.setIndent(0)
self.lblSticky.setMargin(0)
@@ -1002,7 +1003,7 @@ class GuiDocViewFooter(QWidget):
self.lblSticky.setFixedHeight(fPx)
self.lblSticky.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblComments = QLabel("Comments")
self.lblComments = QLabel(self.tr("Comments"))
self.lblComments.setBuddy(self.showComments)
self.lblComments.setIndent(0)
self.lblComments.setMargin(0)
@@ -1011,7 +1012,7 @@ class GuiDocViewFooter(QWidget):
self.lblComments.setFixedHeight(fPx)
self.lblComments.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblSynopsis = QLabel("Synopsis")
self.lblSynopsis = QLabel(self.tr("Synopsis"))
self.lblSynopsis.setBuddy(self.showSynopsis)
self.lblSynopsis.setIndent(0)
self.lblSynopsis.setMargin(0)
+14 -12
View File
@@ -27,7 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import nw
import logging
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QFont, QPixmap
from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel
@@ -67,7 +67,7 @@ class GuiItemDetails(QWidget):
self.fntValue.setPointSizeF(0.9*fPt)
# Label
self.labelName = QLabel("Label")
self.labelName = QLabel(self.tr("Label"))
self.labelName.setFont(self.fntLabel)
self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
@@ -80,7 +80,7 @@ class GuiItemDetails(QWidget):
self.labelData.setWordWrap(True)
# Status
self.statusName = QLabel("Status")
self.statusName = QLabel(self.tr("Status"))
self.statusName.setFont(self.fntLabel)
self.statusName.setAlignment(Qt.AlignLeft)
@@ -92,7 +92,7 @@ class GuiItemDetails(QWidget):
self.statusData.setAlignment(Qt.AlignLeft)
# Class
self.className = QLabel("Class")
self.className = QLabel(self.tr("Class"))
self.className.setFont(self.fntLabel)
self.className.setAlignment(Qt.AlignLeft)
@@ -105,7 +105,7 @@ class GuiItemDetails(QWidget):
self.classData.setAlignment(Qt.AlignLeft)
# Layout
self.layoutName = QLabel("Layout")
self.layoutName = QLabel(self.tr("Layout"))
self.layoutName.setFont(self.fntLabel)
self.layoutName.setAlignment(Qt.AlignLeft)
@@ -118,7 +118,7 @@ class GuiItemDetails(QWidget):
self.layoutData.setAlignment(Qt.AlignLeft)
# Character Count
self.cCountName = QLabel(" Characters")
self.cCountName = QLabel(self.tr(" Characters"))
self.cCountName.setFont(self.fntLabel)
self.cCountName.setAlignment(Qt.AlignRight)
@@ -127,7 +127,7 @@ class GuiItemDetails(QWidget):
self.cCountData.setAlignment(Qt.AlignRight)
# Word Count
self.wCountName = QLabel(" Words")
self.wCountName = QLabel(self.tr(" Words"))
self.wCountName.setFont(self.fntLabel)
self.wCountName.setAlignment(Qt.AlignRight)
@@ -136,7 +136,7 @@ class GuiItemDetails(QWidget):
self.wCountData.setAlignment(Qt.AlignRight)
# Paragraph Count
self.pCountName = QLabel(" Paragraphs")
self.pCountName = QLabel(self.tr(" Paragraphs"))
self.pCountName.setFont(self.fntLabel)
self.pCountName.setAlignment(Qt.AlignRight)
@@ -259,17 +259,19 @@ class GuiItemDetails(QWidget):
iPx = int(round(0.8*self.theTheme.baseIconSize))
self.statusFlag.setPixmap(flagIcon.pixmap(iPx, iPx))
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass])
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass]) # NO-I18N
if nwItem.itemLayout == nwItemLayout.NO_LAYOUT:
self.layoutFlag.setText("-")
else:
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout])
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout]) # NO-I18N
self.labelData.setText(theLabel)
self.statusData.setText(nwItem.itemStatus)
self.classData.setText(nwLabels.CLASS_NAME[nwItem.itemClass])
self.layoutData.setText(nwLabels.LAYOUT_NAME[nwItem.itemLayout])
self.classData.setText(QCoreApplication.translate(
"Constant", nwLabels.CLASS_NAME[nwItem.itemClass]))
self.layoutData.setText(QCoreApplication.translate(
"Constant", nwLabels.LAYOUT_NAME[nwItem.itemLayout]))
if nwItem.itemType == nwItemType.FILE:
self.cCountData.setText(f"{nwItem.charCount:n}")
+10 -7
View File
@@ -27,7 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import nw
import logging
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QCoreApplication, pyqtSlot
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QGridLayout, QLineEdit, QComboBox, QLabel,
QDialogButtonBox
@@ -58,7 +58,7 @@ class GuiItemEditor(QDialog):
if self.theItem is None:
self._doClose()
self.setWindowTitle("Item Settings")
self.setWindowTitle(self.tr("Item Settings"))
mVd = self.mainConf.pxInt(220)
mSp = self.mainConf.pxInt(16)
@@ -103,10 +103,11 @@ class GuiItemEditor(QDialog):
for itemLayout in nwItemLayout:
if itemLayout in validLayouts:
self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout], itemLayout)
self.editLayout.addItem(QCoreApplication.translate(
"Constant", nwLabels.LAYOUT_NAME[itemLayout]), itemLayout)
# Export Switch
self.textExport = QLabel("Include when building project")
self.textExport = QLabel(self.tr("Include when building project"))
self.editExport = QSwitch()
if self.theItem.itemType == nwItemType.FILE:
self.editExport.setEnabled(True)
@@ -117,6 +118,8 @@ class GuiItemEditor(QDialog):
# Buttons
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
@@ -139,11 +142,11 @@ class GuiItemEditor(QDialog):
self.mainForm = QGridLayout()
self.mainForm.setVerticalSpacing(vSp)
self.mainForm.setHorizontalSpacing(mSp)
self.mainForm.addWidget(QLabel("Label"), 0, 0, 1, 1)
self.mainForm.addWidget(QLabel(self.tr("Label")), 0, 0, 1, 1)
self.mainForm.addWidget(self.editName, 0, 1, 1, 2)
self.mainForm.addWidget(QLabel("Status"), 1, 0, 1, 1)
self.mainForm.addWidget(QLabel(self.tr("Status")), 1, 0, 1, 1)
self.mainForm.addWidget(self.editStatus, 1, 1, 1, 2)
self.mainForm.addWidget(QLabel("Layout"), 2, 0, 1, 1)
self.mainForm.addWidget(QLabel(self.tr("Layout")), 2, 0, 1, 1)
self.mainForm.addWidget(self.editLayout, 2, 1, 1, 2)
self.mainForm.addWidget(self.textExport, 3, 0, 1, 2)
self.mainForm.addWidget(self.editExport, 3, 2, 1, 1)
+239 -226
View File
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -63,7 +63,11 @@ class GuiNovelTree(QTreeWidget):
self.setIconSize(QSize(iPx, iPx))
self.setIndentation(iPx)
self.setColumnCount(3)
self.setHeaderLabels(["Title", "Words", "POV"])
self.setHeaderLabels([
self.tr("Title"),
self.tr("Words"),
self.tr("POV")
])
self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._itemSelected)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
@@ -73,9 +77,9 @@ class GuiNovelTree(QTreeWidget):
treeHeadItem = self.headerItem()
treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
treeHeadItem.setToolTip(self.C_TITLE, "Section title")
treeHeadItem.setToolTip(self.C_WORDS, "Word count")
treeHeadItem.setToolTip(self.C_POV, "Point-of-view character")
treeHeadItem.setToolTip(self.C_TITLE, self.tr("Section title"))
treeHeadItem.setToolTip(self.C_WORDS, self.tr("Word count"))
treeHeadItem.setToolTip(self.C_POV, self.tr("Point-of-view character"))
treeHeader = self.header()
treeHeader.setStretchLastSection(True)
+8 -5
View File
@@ -29,7 +29,7 @@ import logging
from time import time
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtCore import QCoreApplication, Qt, QSize
from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView
)
@@ -149,7 +149,8 @@ class GuiOutline(QTreeWidget):
"""
self.clear()
self.setColumnCount(1)
self.setHeaderLabel(nwLabels.OUTLINE_COLS[nwOutline.TITLE])
self.setHeaderLabel(
QCoreApplication.translate("Constant", nwLabels.OUTLINE_COLS[nwOutline.TITLE]))
self.treeOrder = []
self.colWidth = {}
@@ -355,7 +356,8 @@ class GuiOutline(QTreeWidget):
if self.firstView:
theLabels = []
for i, hItem in enumerate(self.treeOrder):
theLabels.append(nwLabels.OUTLINE_COLS[hItem])
theLabels.append(
QCoreApplication.translate("Constant", nwLabels.OUTLINE_COLS[hItem]))
self.colIndex[hItem] = i
self.setHeaderLabels(theLabels)
@@ -474,7 +476,7 @@ class GuiOutlineHeaderMenu(QMenu):
self.theParent = theParent
self.acceptToggle = True
mnuHead = QAction("Select Columns", self)
mnuHead = QAction(self.tr("Select Columns"), self)
self.addAction(mnuHead)
self.addSeparator()
@@ -482,7 +484,8 @@ class GuiOutlineHeaderMenu(QMenu):
for hItem in nwOutline:
if hItem == nwOutline.TITLE:
continue
self.actionMap[hItem] = QAction(nwLabels.OUTLINE_COLS[hItem], self)
self.actionMap[hItem] = QAction(
QCoreApplication.translate("Constant", nwLabels.OUTLINE_COLS[hItem]), self)
self.actionMap[hItem].setCheckable(True)
self.actionMap[hItem].toggled.connect(
lambda isChecked, tItem=hItem : self._columnToggled(isChecked, tItem)
+35 -26
View File
@@ -27,7 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import nw
import logging
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, Qt
from PyQt5.QtWidgets import (
QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel
)
@@ -40,10 +40,10 @@ logger = logging.getLogger(__name__)
class GuiOutlineDetails(QScrollArea):
LVL_MAP = {
"H1" : "Title",
"H2" : "Chapter",
"H3" : "Scene",
"H4" : "Section"
"H1" : QT_TRANSLATE_NOOP("GuiOutlineDetails", "Title"),
"H2" : QT_TRANSLATE_NOOP("GuiOutlineDetails", "Chapter"),
"H3" : QT_TRANSLATE_NOOP("GuiOutlineDetails", "Scene"),
"H4" : QT_TRANSLATE_NOOP("GuiOutlineDetails", "Section"),
}
def __init__(self, theParent):
@@ -66,9 +66,9 @@ class GuiOutlineDetails(QScrollArea):
vSpace = int(self.mainConf.pxInt(4))
# Details Area
self.titleLabel = QLabel("<b>Title</b>")
self.fileLabel = QLabel("<b>Document</b>")
self.itemLabel = QLabel("<b>Status</b>")
self.titleLabel = QLabel("<b>%s</b>" % self.tr("Title"))
self.fileLabel = QLabel("<b>%s</b>" % self.tr("Document"))
self.itemLabel = QLabel("<b>%s</b>" % self.tr("Status"))
self.titleValue = QLabel("")
self.fileValue = QLabel("")
self.itemValue = QLabel("")
@@ -81,9 +81,9 @@ class GuiOutlineDetails(QScrollArea):
self.itemValue.setMaximumWidth(maxTitle)
# Stats Area
self.cCLabel = QLabel("<b>Characters</b>")
self.wCLabel = QLabel("<b>Words</b>")
self.pCLabel = QLabel("<b>Paragraphs</b>")
self.cCLabel = QLabel("<b>%s</b>" % self.tr("Characters"))
self.wCLabel = QLabel("<b>%s</b>" % self.tr("Words"))
self.pCLabel = QLabel("<b>%s</b>" % self.tr("Paragraphs"))
self.cCValue = QLabel("")
self.wCValue = QLabel("")
self.pCValue = QLabel("")
@@ -96,7 +96,7 @@ class GuiOutlineDetails(QScrollArea):
self.pCValue.setAlignment(Qt.AlignRight)
# Synopsis
self.synopLabel = QLabel("<b>Synopsis</b>")
self.synopLabel = QLabel("<b>%s</b>" % self.tr("Synopsis"))
self.synopValue = QLabel("")
self.synopLWrap = QHBoxLayout()
self.synopValue.setWordWrap(True)
@@ -104,15 +104,24 @@ class GuiOutlineDetails(QScrollArea):
self.synopLWrap.addWidget(self.synopValue, 1)
# Tags
self.povKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
self.focKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
self.chrKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY])
self.pltKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
self.timKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.TIME_KEY])
self.wldKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY])
self.objKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY])
self.entKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY])
self.cstKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY])
self.povKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.POV_KEY]))
self.focKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]))
self.chrKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]))
self.pltKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]))
self.timKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]))
self.wldKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]))
self.objKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]))
self.entKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]))
self.cstKeyLabel = QLabel("<b>%s</b>" % QCoreApplication.translate(
"Constant", nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]))
self.povKeyLWrap = QHBoxLayout()
self.focKeyLWrap = QHBoxLayout()
@@ -165,7 +174,7 @@ class GuiOutlineDetails(QScrollArea):
self.cstKeyLWrap.addWidget(self.cstKeyValue, 1)
# Selected Item Details
self.mainGroup = QGroupBox("Title Details", self)
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
self.mainForm = QGridLayout()
self.mainGroup.setLayout(self.mainForm)
@@ -190,7 +199,7 @@ class GuiOutlineDetails(QScrollArea):
self.mainForm.setVerticalSpacing(vSpace)
# Selected Item Tags
self.tagsGroup = QGroupBox("Reference Tags", self)
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsForm = QGridLayout()
self.tagsGroup.setLayout(self.tagsForm)
@@ -256,7 +265,7 @@ class GuiOutlineDetails(QScrollArea):
def clearDetails(self):
"""Clear all the data labels.
"""
self.titleLabel.setText("<b>Title</b>")
self.titleLabel.setText("<b>%s</b>" % self.tr("Title"))
self.titleValue.setText("")
self.fileValue.setText("")
self.itemValue.setText("")
@@ -286,9 +295,9 @@ class GuiOutlineDetails(QScrollArea):
return False
if novIdx["level"] in self.LVL_MAP:
self.titleLabel.setText("<b>%s</b>" % self.LVL_MAP[novIdx["level"]])
self.titleLabel.setText("<b>%s</b>" % self.tr(self.LVL_MAP[novIdx["level"]]))
else:
self.titleLabel.setText("<b>Title</b>")
self.titleLabel.setText("<b>%s</b>" % self.tr("Title"))
self.titleValue.setText(novIdx["title"])
self.fileValue.setText(nwItem.itemName)
+143 -136
View File
@@ -28,7 +28,7 @@ import nw
import logging
import os
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import (
QDialog, QWidget, QComboBox, QSpinBox, QPushButton, QDialogButtonBox,
@@ -53,7 +53,7 @@ class GuiPreferences(PagedDialog):
self.theParent = theParent
self.theProject = theProject
self.setWindowTitle("Preferences")
self.setWindowTitle(self.tr("Preferences"))
self.tabGeneral = GuiPreferencesGeneral(self.theParent)
self.tabProjects = GuiPreferencesProjects(self.theParent)
@@ -62,14 +62,16 @@ class GuiPreferences(PagedDialog):
self.tabSyntax = GuiPreferencesSyntax(self.theParent)
self.tabAuto = GuiPreferencesAutomation(self.theParent)
self.addTab(self.tabGeneral, "General")
self.addTab(self.tabProjects, "Projects")
self.addTab(self.tabDocs, "Documents")
self.addTab(self.tabEditor, "Editor")
self.addTab(self.tabSyntax, "Highlighting")
self.addTab(self.tabAuto, "Automation")
self.addTab(self.tabGeneral, self.tr("General"))
self.addTab(self.tabProjects, self.tr("Projects"))
self.addTab(self.tabDocs, self.tr("Documents"))
self.addTab(self.tabEditor, self.tr("Editor"))
self.addTab(self.tabSyntax, self.tr("Highlighting"))
self.addTab(self.tabAuto, self.tr("Automation"))
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
self.addControls(self.buttonBox)
@@ -98,7 +100,7 @@ class GuiPreferences(PagedDialog):
if needsRestart:
self.theParent.makeAlert(
"Some changes will not be applied until novelWriter has been restarted.",
self.tr("Some changes will not be applied until novelWriter has been restarted."),
nwAlert.INFO
)
@@ -130,7 +132,7 @@ class GuiPreferencesGeneral(QWidget):
# Look and Feel
# =============
self.mainForm.addGroupLabel("Look and Feel")
self.mainForm.addGroupLabel(self.tr("Look and Feel"))
## Select Theme
self.guiTheme = QComboBox()
@@ -143,9 +145,9 @@ class GuiPreferencesGeneral(QWidget):
self.guiTheme.setCurrentIndex(themeIdx)
self.mainForm.addRow(
"Main GUI theme",
self.tr("Main GUI theme"),
self.guiTheme,
"Changing this requires restarting novelWriter."
self.tr("Changing this requires restarting novelWriter.")
)
## Select Icon Theme
@@ -159,18 +161,18 @@ class GuiPreferencesGeneral(QWidget):
self.guiIcons.setCurrentIndex(iconIdx)
self.mainForm.addRow(
"Main icon theme",
self.tr("Main icon theme"),
self.guiIcons,
"Changing this requires restarting novelWriter."
self.tr("Changing this requires restarting novelWriter.")
)
## Dark Icons
self.guiDark = QSwitch()
self.guiDark.setChecked(self.mainConf.guiDark)
self.mainForm.addRow(
"Prefer icons for dark backgrounds",
self.tr("Prefer icons for dark backgrounds"),
self.guiDark,
"May improve the look of icons on dark themes."
self.tr("May improve the look of icons on dark themes.")
)
## Font Family
@@ -182,9 +184,9 @@ class GuiPreferencesGeneral(QWidget):
self.fontButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("...")))
self.fontButton.clicked.connect(self._selectFont)
self.mainForm.addRow(
"Font family",
self.tr("Font family"),
self.guiFont,
"Changing this requires restarting novelWriter.",
self.tr("Changing this requires restarting novelWriter."),
theButton = self.fontButton
)
@@ -195,38 +197,38 @@ class GuiPreferencesGeneral(QWidget):
self.guiFontSize.setSingleStep(1)
self.guiFontSize.setValue(self.mainConf.guiFontSize)
self.mainForm.addRow(
"Font size",
self.tr("Font size"),
self.guiFontSize,
"Changing this requires restarting novelWriter.",
self.tr("Changing this requires restarting novelWriter."),
theUnit = "pt"
)
# GUI Settings
# ============
self.mainForm.addGroupLabel("GUI Settings")
self.mainForm.addGroupLabel(self.tr("GUI Settings"))
self.showFullPath = QSwitch()
self.showFullPath.setChecked(self.mainConf.showFullPath)
self.mainForm.addRow(
"Show full path in document header",
self.tr("Show full path in document header"),
self.showFullPath,
"Add the parent folder names to the header."
self.tr("Add the parent folder names to the header.")
)
self.hideVScroll = QSwitch()
self.hideVScroll.setChecked(self.mainConf.hideVScroll)
self.mainForm.addRow(
"Hide vertical scroll bars in main windows",
self.tr("Hide vertical scroll bars in main windows"),
self.hideVScroll,
"Scrolling available with mouse wheel and keys only."
self.tr("Scrolling available with mouse wheel and keys only.")
)
self.hideHScroll = QSwitch()
self.hideHScroll.setChecked(self.mainConf.hideHScroll)
self.mainForm.addRow(
"Hide horizontal scroll bars in main windows",
self.tr("Hide horizontal scroll bars in main windows"),
self.hideHScroll,
"Scrolling available with mouse wheel and keys only."
self.tr("Scrolling available with mouse wheel and keys only.")
)
return
@@ -295,7 +297,7 @@ class GuiPreferencesProjects(QWidget):
# Automatic Save
# ==============
self.mainForm.addGroupLabel("Automatic Save")
self.mainForm.addGroupLabel(self.tr("Automatic Save"))
## Document Save Timer
self.autoSaveDoc = QSpinBox(self)
@@ -304,10 +306,10 @@ class GuiPreferencesProjects(QWidget):
self.autoSaveDoc.setSingleStep(1)
self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc)
self.mainForm.addRow(
"Save document interval",
self.tr("Save document interval"),
self.autoSaveDoc,
"How often the open document is automatically saved.",
theUnit="seconds"
self.tr("How often the open document is automatically saved."),
theUnit=self.tr("seconds")
)
## Project Save Timer
@@ -317,24 +319,24 @@ class GuiPreferencesProjects(QWidget):
self.autoSaveProj.setSingleStep(1)
self.autoSaveProj.setValue(self.mainConf.autoSaveProj)
self.mainForm.addRow(
"Save project interval",
self.tr("Save project interval"),
self.autoSaveProj,
"How often the open project is automatically saved.",
theUnit="seconds"
self.tr("How often the open project is automatically saved."),
theUnit=self.tr("seconds")
)
# Project Backup
# ==============
self.mainForm.addGroupLabel("Project Backup")
self.mainForm.addGroupLabel(self.tr("Project Backup"))
## Backup Path
self.backupPath = self.mainConf.backupPath
self.backupGetPath = QPushButton("Browse")
self.backupGetPath = QPushButton(self.tr("Browse"))
self.backupGetPath.clicked.connect(self._backupFolder)
self.backupPathRow = self.mainForm.addRow(
"Backup storage location",
self.tr("Backup storage location"),
self.backupGetPath,
"Path: %s" % self.backupPath
self.tr("{0}: {1}").format(self.tr("Path"), self.backupPath)
)
## Run when closing
@@ -342,9 +344,9 @@ class GuiPreferencesProjects(QWidget):
self.backupOnClose.setChecked(self.mainConf.backupOnClose)
self.backupOnClose.toggled.connect(self._toggledBackupOnClose)
self.mainForm.addRow(
"Run backup when the project is closed",
self.tr("Run backup when the project is closed"),
self.backupOnClose,
"Can be overridden for individual projects in project settings."
self.tr("Can be overridden for individual projects in project settings.")
)
## Ask before backup
@@ -353,22 +355,22 @@ class GuiPreferencesProjects(QWidget):
self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup)
self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose)
self.mainForm.addRow(
"Ask before running backup",
self.tr("Ask before running backup"),
self.askBeforeBackup,
"If off, backups will run in the background."
self.tr("If off, backups will run in the background.")
)
# Session Timer
# =============
self.mainForm.addGroupLabel("Session Timer")
self.mainForm.addGroupLabel(self.tr("Session Timer"))
## Pause when idle
self.stopWhenIdle = QSwitch()
self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle)
self.mainForm.addRow(
"Pause the session timer when not writing",
self.tr("Pause the session timer when not writing"),
self.stopWhenIdle,
"Also pauses when the application window does not have focus."
self.tr("Also pauses when the application window does not have focus.")
)
## Inactive time for idle
@@ -379,10 +381,10 @@ class GuiPreferencesProjects(QWidget):
self.userIdleTime.setDecimals(1)
self.userIdleTime.setValue(self.mainConf.userIdleTime/60.0)
self.mainForm.addRow(
"Editor inactive time before pausing timer",
self.tr("Editor inactive time before pausing timer"),
self.userIdleTime,
"User activity includes typing and changing the content.",
theUnit="minutes"
self.tr("User activity includes typing and changing the content."),
theUnit=self.tr("minutes")
)
return
@@ -422,11 +424,12 @@ class GuiPreferencesProjects(QWidget):
dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
newDir = QFileDialog.getExistingDirectory(
self, "Backup Directory", currDir, options=dlgOpt
self, self.tr("Backup Directory"), currDir, options=dlgOpt
)
if newDir:
self.backupPath = newDir
self.mainForm.setHelpText(self.backupPathRow, "Path: %s" % self.backupPath)
self.mainForm.setHelpText(
self.backupPathRow, self.tr("{0}: {1}").format(self.tr("Path"), self.backupPath))
return True
return False
@@ -456,7 +459,7 @@ class GuiPreferencesDocuments(QWidget):
# Text Style
# ==========
self.mainForm.addGroupLabel("Text Style")
self.mainForm.addGroupLabel(self.tr("Text Style"))
## Font Family
self.textFont = QLineEdit()
@@ -467,9 +470,9 @@ class GuiPreferencesDocuments(QWidget):
self.fontButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("...")))
self.fontButton.clicked.connect(self._selectFont)
self.mainForm.addRow(
"Font family",
self.tr("Font family"),
self.textFont,
"Font for the document editor and viewer.",
self.tr("Font for the document editor and viewer."),
theButton = self.fontButton
)
@@ -480,15 +483,15 @@ class GuiPreferencesDocuments(QWidget):
self.textSize.setSingleStep(1)
self.textSize.setValue(self.mainConf.textSize)
self.mainForm.addRow(
"Font size",
self.tr("Font size"),
self.textSize,
"Font size for the document editor and viewer.",
self.tr("Font size for the document editor and viewer."),
theUnit = "pt"
)
# Text Flow
# =========
self.mainForm.addGroupLabel("Text Flow")
self.mainForm.addGroupLabel(self.tr("Text Flow"))
## Max Text Width in Normal Mode
self.textWidth = QSpinBox(self)
@@ -497,10 +500,10 @@ class GuiPreferencesDocuments(QWidget):
self.textWidth.setSingleStep(10)
self.textWidth.setValue(self.mainConf.textWidth)
self.mainForm.addRow(
"Maximum text width in \"Normal Mode\"",
self.tr("Maximum text width in \"Normal Mode\""),
self.textWidth,
"Horizontal margins are scaled automatically.",
theUnit="px"
self.tr("Horizontal margins are scaled automatically."),
theUnit=self.tr("px")
)
## Max Text Width in Focus Mode
@@ -510,37 +513,37 @@ class GuiPreferencesDocuments(QWidget):
self.focusWidth.setSingleStep(10)
self.focusWidth.setValue(self.mainConf.focusWidth)
self.mainForm.addRow(
"Maximum text width in \"Focus Mode\"",
self.tr("Maximum text width in \"Focus Mode\""),
self.focusWidth,
"Horizontal margins are scaled automatically.",
theUnit="px"
self.tr("Horizontal margins are scaled automatically."),
theUnit=self.tr("px")
)
## Document Fixed Width
self.textFixedW = QSwitch()
self.textFixedW.setChecked(not self.mainConf.textFixedW)
self.mainForm.addRow(
"Disable maximum text width in \"Normal Mode\"",
self.tr("Disable maximum text width in \"Normal Mode\""),
self.textFixedW,
"Text width is defined by the margins only."
self.tr("Text width is defined by the margins only.")
)
## Focus Mode Footer
self.hideFocusFooter = QSwitch()
self.hideFocusFooter.setChecked(self.mainConf.hideFocusFooter)
self.mainForm.addRow(
"Hide document footer in \"Focus Mode\"",
self.tr("Hide document footer in \"Focus Mode\""),
self.hideFocusFooter,
"Hide the information bar at the bottom of the document."
self.tr("Hide the information bar at the bottom of the document.")
)
## Justify Text
self.doJustify = QSwitch()
self.doJustify.setChecked(self.mainConf.doJustify)
self.mainForm.addRow(
"Justify the text margins in editor and viewer",
self.tr("Justify the text margins in editor and viewer"),
self.doJustify,
"Lay out text with straight edges in the editor and viewer."
self.tr("Lay out text with straight edges in the editor and viewer.")
)
## Document Margins
@@ -550,10 +553,10 @@ class GuiPreferencesDocuments(QWidget):
self.textMargin.setSingleStep(1)
self.textMargin.setValue(self.mainConf.textMargin)
self.mainForm.addRow(
"Text margin",
self.tr("Text margin"),
self.textMargin,
"If maximum width is set, this becomes the minimum margin.",
theUnit="px"
self.tr("If maximum width is set, this becomes the minimum margin."),
theUnit=self.tr("px")
)
## Tab Width
@@ -563,10 +566,10 @@ class GuiPreferencesDocuments(QWidget):
self.tabWidth.setSingleStep(1)
self.tabWidth.setValue(self.mainConf.tabWidth)
self.mainForm.addRow(
"Tab width",
self.tr("Tab width"),
self.tabWidth,
"The width of a tab key press in the editor and viewer.",
theUnit="px"
self.tr("The width of a tab key press in the editor and viewer."),
theUnit=self.tr("px")
)
return
@@ -626,13 +629,17 @@ class GuiPreferencesEditor(QWidget):
# Spell Checking
# ==============
self.mainForm.addGroupLabel("Spell Checking")
self.mainForm.addGroupLabel(self.tr("Spell Checking"))
## Spell Check Provider and Language
self.spellLangList = QComboBox(self)
self.spellToolList = QComboBox(self)
self.spellToolList.addItem("Internal (difflib)", nwConst.SP_INTERNAL)
self.spellToolList.addItem("Spell Enchant (pyenchant)", nwConst.SP_ENCHANT)
self.spellToolList.addItem(
self.tr("{0} ({1})").format(self.tr("Internal"), "difflib"),
QCoreApplication.translate("Constant", nwConst.SP_INTERNAL))
self.spellToolList.addItem(
self.tr("{0} ({1})").format(self.tr("Spell Enchant"), "pyenchant"),
QCoreApplication.translate("Constant", nwConst.SP_ENCHANT))
theModel = self.spellToolList.model()
idEnchant = self.spellToolList.findData(nwConst.SP_ENCHANT)
@@ -645,14 +652,14 @@ class GuiPreferencesEditor(QWidget):
self._doUpdateSpellTool(0)
self.mainForm.addRow(
"Spell check provider",
self.tr("Spell check provider"),
self.spellToolList,
"Note that the internal spell check tool is quite slow."
self.tr("Note that the internal spell check tool is quite slow.")
)
self.mainForm.addRow(
"Spell check language",
self.tr("Spell check language"),
self.spellLangList,
"Available languages are determined by your system."
self.tr("Available languages are determined by your system.")
)
## Big Document Size Limit
@@ -662,15 +669,15 @@ class GuiPreferencesEditor(QWidget):
self.bigDocLimit.setSingleStep(10)
self.bigDocLimit.setValue(self.mainConf.bigDocLimit)
self.mainForm.addRow(
"Big document limit",
self.tr("Big document limit"),
self.bigDocLimit,
"Full spell checking is disabled above this limit.",
theUnit="kB"
self.tr("Full spell checking is disabled above this limit."),
theUnit=self.tr("kB")
)
# Word Count
# ==========
self.mainForm.addGroupLabel("Word Count")
self.mainForm.addGroupLabel(self.tr("Word Count"))
## Word Count Timer
self.wordCountTimer = QDoubleSpinBox(self)
@@ -680,54 +687,54 @@ class GuiPreferencesEditor(QWidget):
self.wordCountTimer.setSingleStep(0.1)
self.wordCountTimer.setValue(self.mainConf.wordCountTimer)
self.mainForm.addRow(
"Word count interval",
self.tr("Word count interval"),
self.wordCountTimer,
"How often the word count is updated.",
theUnit="seconds"
self.tr("How often the word count is updated."),
theUnit=self.tr("seconds")
)
# Writing Guides
# ==============
self.mainForm.addGroupLabel("Writing Guides")
self.mainForm.addGroupLabel(self.tr("Writing Guides"))
## Show Tabs and Spaces
self.showTabsNSpaces = QSwitch()
self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces)
self.mainForm.addRow(
"Show tabs and spaces",
self.tr("Show tabs and spaces"),
self.showTabsNSpaces,
"Add symbols to indicate tabs and spaces in the editor."
self.tr("Add symbols to indicate tabs and spaces in the editor.")
)
## Show Line Endings
self.showLineEndings = QSwitch()
self.showLineEndings.setChecked(self.mainConf.showLineEndings)
self.mainForm.addRow(
"Show line endings",
self.tr("Show line endings"),
self.showLineEndings,
"Add a symbol to indicate line endings in the editor."
self.tr("Add a symbol to indicate line endings in the editor.")
)
# Scroll Behaviour
# ================
self.mainForm.addGroupLabel("Scroll Behaviour")
self.mainForm.addGroupLabel(self.tr("Scroll Behaviour"))
## Scroll Past End
self.scrollPastEnd = QSwitch()
self.scrollPastEnd.setChecked(self.mainConf.scrollPastEnd)
self.mainForm.addRow(
"Scroll past end of the document",
self.tr("Scroll past end of the document"),
self.scrollPastEnd,
"Also improves trypewriter scrolling for short documents."
self.tr("Also improves trypewriter scrolling for short documents.")
)
## Typewriter Scrolling
self.autoScroll = QSwitch()
self.autoScroll.setChecked(self.mainConf.autoScroll)
self.mainForm.addRow(
"Typewriter style scrolling when you type",
self.tr("Typewriter style scrolling when you type"),
self.autoScroll,
"Try to keep the cursor at a fixed vertical position."
self.tr("Try to keep the cursor at a fixed vertical position.")
)
## Typewriter Position
@@ -737,9 +744,9 @@ class GuiPreferencesEditor(QWidget):
self.autoScrollPos.setSingleStep(1)
self.autoScrollPos.setValue(int(self.mainConf.autoScrollPos))
self.mainForm.addRow(
"Minimum position for Typewriter scrolling",
self.tr("Minimum position for Typewriter scrolling"),
self.autoScrollPos,
"Percentage of the editor height from the top.",
self.tr("Percentage of the editor height from the top."),
theUnit = "%"
)
@@ -819,7 +826,7 @@ class GuiPreferencesSyntax(QWidget):
# Highlighting Theme
# ==================
self.mainForm.addGroupLabel("Highlighting Theme")
self.mainForm.addGroupLabel(self.tr("Highlighting Theme"))
self.guiSyntax = QComboBox()
self.guiSyntax.setMinimumWidth(self.mainConf.pxInt(200))
@@ -831,50 +838,50 @@ class GuiPreferencesSyntax(QWidget):
self.guiSyntax.setCurrentIndex(syntaxIdx)
self.mainForm.addRow(
"Highlighting theme",
self.tr("Highlighting theme"),
self.guiSyntax,
"Colour theme to apply to the editor and viewer."
self.tr("Colour theme to apply to the editor and viewer.")
)
# Quotes & Dialogue
# =================
self.mainForm.addGroupLabel("Quotes & Dialogue")
self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue"))
self.highlightQuotes = QSwitch()
self.highlightQuotes.setChecked(self.mainConf.highlightQuotes)
self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes)
self.mainForm.addRow(
"Highlight text wrapped in quotes",
self.tr("Highlight text wrapped in quotes"),
self.highlightQuotes,
"Applies to single, double and straight quotes."
self.tr("Applies to single, double and straight quotes.")
)
self.allowOpenSQuote = QSwitch()
self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote)
self.mainForm.addRow(
"Allow open-ended single quotes",
self.tr("Allow open-ended single quotes"),
self.allowOpenSQuote,
"Highlight single-quoted line with no closing quote."
self.tr("Highlight single-quoted line with no closing quote.")
)
self.allowOpenDQuote = QSwitch()
self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote)
self.mainForm.addRow(
"Allow open-ended double quotes",
self.tr("Allow open-ended double quotes"),
self.allowOpenDQuote,
"Highlight double-quoted line with no closing quote."
self.tr("Highlight double-quoted line with no closing quote.")
)
# Text Emphasis
# =============
self.mainForm.addGroupLabel("Text Emphasis")
self.mainForm.addGroupLabel(self.tr("Text Emphasis"))
self.highlightEmph = QSwitch()
self.highlightEmph.setChecked(self.mainConf.highlightEmph)
self.mainForm.addRow(
"Add highlight colour to emphasised text",
self.tr("Add highlight colour to emphasised text"),
self.highlightEmph,
"Applies to emphasis (italic) and strong (bold)."
self.tr("Applies to emphasis (italic) and strong (bold).")
)
return
@@ -927,15 +934,15 @@ class GuiPreferencesAutomation(QWidget):
# Automatic Features
# ==================
self.mainForm.addGroupLabel("Automatic Features")
self.mainForm.addGroupLabel(self.tr("Automatic Features"))
## Auto-Select Word Under Cursor
self.autoSelect = QSwitch()
self.autoSelect.setChecked(self.mainConf.autoSelect)
self.mainForm.addRow(
"Auto-select word under cursor",
self.tr("Auto-select word under cursor"),
self.autoSelect,
"Apply formatting to word under cursor if no selection is made."
self.tr("Apply formatting to word under cursor if no selection is made.")
)
## Auto-Replace as You Type Main Switch
@@ -943,23 +950,23 @@ class GuiPreferencesAutomation(QWidget):
self.doReplace.setChecked(self.mainConf.doReplace)
self.doReplace.toggled.connect(self._toggleAutoReplaceMain)
self.mainForm.addRow(
"Auto-replace text as you type",
self.tr("Auto-replace text as you type"),
self.doReplace,
"Allow the editor to replace symbols as you type."
self.tr("Allow the editor to replace symbols as you type.")
)
# Replace as You Type
# ===================
self.mainForm.addGroupLabel("Replace as You Type")
self.mainForm.addGroupLabel(self.tr("Replace as You Type"))
## Auto-Replace Single Quotes
self.doReplaceSQuote = QSwitch()
self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote)
self.doReplaceSQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
"Auto-replace single quotes",
self.tr("Auto-replace single quotes"),
self.doReplaceSQuote,
"Try to guess which is an opening or a closing single quote."
self.tr("Try to guess which is an opening or a closing single quote.")
)
## Auto-Replace Double Quotes
@@ -967,9 +974,9 @@ class GuiPreferencesAutomation(QWidget):
self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote)
self.doReplaceDQuote.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
"Auto-replace double quotes",
self.tr("Auto-replace double quotes"),
self.doReplaceDQuote,
"Try to guess which is an opening or a closing double quote."
self.tr("Try to guess which is an opening or a closing double quote.")
)
## Auto-Replace Hyphens
@@ -977,9 +984,9 @@ class GuiPreferencesAutomation(QWidget):
self.doReplaceDash.setChecked(self.mainConf.doReplaceDash)
self.doReplaceDash.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
"Auto-replace dashes",
self.tr("Auto-replace dashes"),
self.doReplaceDash,
"Double and triple hyphens become short and long dashes."
self.tr("Double and triple hyphens become short and long dashes.")
)
## Auto-Replace Dots
@@ -987,14 +994,14 @@ class GuiPreferencesAutomation(QWidget):
self.doReplaceDots.setChecked(self.mainConf.doReplaceDots)
self.doReplaceDots.setEnabled(self.mainConf.doReplace)
self.mainForm.addRow(
"Auto-replace dots",
self.tr("Auto-replace dots"),
self.doReplaceDots,
"Three consecutive dots become ellipsis."
self.tr("Three consecutive dots become ellipsis.")
)
# Quotation Style
# ===============
self.mainForm.addGroupLabel("Quotation Style")
self.mainForm.addGroupLabel(self.tr("Quotation Style"))
qWidth = self.mainConf.pxInt(40)
bWidth = int(2.5*self.theTheme.getTextWidth("..."))
@@ -1011,9 +1018,9 @@ class GuiPreferencesAutomation(QWidget):
self.btnSingleStyleO.setMaximumWidth(bWidth)
self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
self.mainForm.addRow(
"Single quote open style",
self.tr("Single quote open style"),
self.quoteSym["SO"],
"The symbol to use for a leading single quote.",
self.tr("The symbol to use for a leading single quote."),
theButton=self.btnSingleStyleO
)
@@ -1027,9 +1034,9 @@ class GuiPreferencesAutomation(QWidget):
self.btnSingleStyleC.setMaximumWidth(bWidth)
self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
self.mainForm.addRow(
"Single quote close style",
self.tr("Single quote close style"),
self.quoteSym["SC"],
"The symbol to use for a trailing single quote.",
self.tr("The symbol to use for a trailing single quote."),
theButton=self.btnSingleStyleC
)
@@ -1044,9 +1051,9 @@ class GuiPreferencesAutomation(QWidget):
self.btnDoubleStyleO.setMaximumWidth(bWidth)
self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
self.mainForm.addRow(
"Double quote open style",
self.tr("Double quote open style"),
self.quoteSym["DO"],
"The symbol to use for a leading double quote.",
self.tr("The symbol to use for a leading double quote."),
theButton=self.btnDoubleStyleO
)
@@ -1060,9 +1067,9 @@ class GuiPreferencesAutomation(QWidget):
self.btnDoubleStyleC.setMaximumWidth(bWidth)
self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
self.mainForm.addRow(
"Double quote close style",
self.tr("Double quote close style"),
self.quoteSym["DC"],
"The symbol to use for a trailing double quote.",
self.tr("The symbol to use for a trailing double quote."),
theButton=self.btnDoubleStyleC
)
+28 -20
View File
@@ -54,7 +54,7 @@ class GuiProjectDetails(PagedDialog):
self.theProject = theProject
self.optState = theProject.optState
self.setWindowTitle("Project Details")
self.setWindowTitle(self.tr("Project Details"))
wW = self.mainConf.pxInt(600)
wH = self.mainConf.pxInt(400)
@@ -69,10 +69,11 @@ class GuiProjectDetails(PagedDialog):
self.tabMain = GuiProjectDetailsMain(self.theParent, self.theProject)
self.tabContents = GuiProjectDetailsContents(self.theParent, self.theProject)
self.addTab(self.tabMain, "Overview")
self.addTab(self.tabContents, "Contents")
self.addTab(self.tabMain, self.tr("Overview"))
self.addTab(self.tabContents, self.tr("Contents"))
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
self.buttonBox.button(QDialogButtonBox.Close).setText(self.tr("Close"))
self.buttonBox.rejected.connect(self._doClose)
self.addControls(self.buttonBox)
@@ -154,7 +155,8 @@ class GuiProjectDetailsMain(QWidget):
self.bookTitle.setAlignment(Qt.AlignHCenter)
self.bookTitle.setWordWrap(True)
self.projName = QLabel("Working Title: %s" % self.theProject.projName)
self.projName = QLabel(self.tr("{0}: {1}").format(
self.tr("Working Title"), self.theProject.projName))
workFont = self.projName.font()
workFont.setPointSizeF(0.8*fPt)
workFont.setItalic(True)
@@ -162,7 +164,7 @@ class GuiProjectDetailsMain(QWidget):
self.projName.setAlignment(Qt.AlignHCenter)
self.projName.setWordWrap(True)
self.bookAuthors = QLabel("By %s" % self.theProject.getAuthors())
self.bookAuthors = QLabel(self.tr("By {0}").format(self.theProject.getAuthors()))
authFont = self.bookAuthors.font()
authFont.setPointSizeF(1.2*fPt)
self.bookAuthors.setFont(authFont)
@@ -175,20 +177,20 @@ class GuiProjectDetailsMain(QWidget):
hCounts = self.theIndex.getNovelTitleCounts()
nwCount = self.theIndex.getNovelWordCount()
self.wordCountLbl = QLabel("<b>Words:</b>")
self.wordCountLbl = QLabel("<b>%s:</b>" % self.tr("Words"))
self.wordCountVal = QLabel(f"{nwCount:n}")
self.chapCountLbl = QLabel("<b>Chapters:</b>")
self.chapCountLbl = QLabel("<b>%s:</b>" % self.tr("Chapters"))
self.chapCountVal = QLabel(f"{hCounts[2]:n}")
self.sceneCountLbl = QLabel("<b>Scenes:</b>")
self.sceneCountLbl = QLabel("<b>%s:</b>" % self.tr("Scenes"))
self.sceneCountVal = QLabel(f"{hCounts[3]:n}")
self.revCountLbl = QLabel("<b>Revisions:</b>")
self.revCountLbl = QLabel("<b>%s:</b>" % self.tr("Revisions"))
self.revCountVal = QLabel(f"{self.theProject.saveCount:n}")
edTime = self.theProject.getCurrentEditTime()
self.editTimeLbl = QLabel("<b>Editing Time:</b>")
self.editTimeLbl = QLabel("<b>%s:</b>" % self.tr("Editing Time"))
self.editTimeVal = QLabel(f"{edTime//3600:02d}:{edTime%3600//60:02d}")
self.statsGrid = QGridLayout()
@@ -208,7 +210,7 @@ class GuiProjectDetailsMain(QWidget):
# Meta
# ====
self.projPathLbl = QLabel("<b>Path:</b>")
self.projPathLbl = QLabel("<b>%s:</b>" % self.tr("Path"))
self.projPathVal = QLineEdit()
self.projPathVal.setText(self.theProject.projPath)
self.projPathVal.setReadOnly(True)
@@ -271,7 +273,13 @@ class GuiProjectDetailsContents(QWidget):
self.tocTree.setIndentation(0)
self.tocTree.setColumnCount(6)
self.tocTree.setSelectionMode(QAbstractItemView.NoSelection)
self.tocTree.setHeaderLabels(["Title", "Words", "Pages", "Page", "Progress", ""])
self.tocTree.setHeaderLabels(
[self.tr("Title"),
self.tr("Words"),
self.tr("Pages"),
self.tr("Page"),
self.tr("Progress"),
""])
treeHeadItem = self.tocTree.headerItem()
treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
@@ -304,16 +312,16 @@ class GuiProjectDetailsContents(QWidget):
clearDouble = self.optState.getInt("GuiProjectDetails", "clearDouble", True)
wordsHelp = (
"Typical word count for a 5 by 8 inch book page with 11 pt font is 350."
self.tr("Typical word count for a 5 by 8 inch book page with 11 pt font is 350.")
)
offsetHelp = (
"Start counting page numbers from this page."
self.tr("Start counting page numbers from this page.")
)
dblHelp = (
"Assume a new chapter or partition always start on an odd numbered page."
self.tr("Assume a new chapter or partition always start on an odd numbered page.")
)
self.wpLabel = QLabel("Words per page")
self.wpLabel = QLabel(self.tr("Words per page"))
self.wpLabel.setToolTip(wordsHelp)
self.wpValue = QSpinBox()
@@ -324,7 +332,7 @@ class GuiProjectDetailsContents(QWidget):
self.wpValue.setToolTip(wordsHelp)
self.wpValue.valueChanged.connect(self._populateTree)
self.poLabel = QLabel("Count pages from")
self.poLabel = QLabel(self.tr("Count pages from"))
self.poLabel.setToolTip(offsetHelp)
self.poValue = QSpinBox()
@@ -335,7 +343,7 @@ class GuiProjectDetailsContents(QWidget):
self.poValue.setToolTip(offsetHelp)
self.poValue.valueChanged.connect(self._populateTree)
self.dblLabel = QLabel("Clear double pages")
self.dblLabel = QLabel(self.tr("Clear double pages"))
self.dblLabel.setToolTip(dblHelp)
self.dblValue = QSwitch(self, 2*iPx, iPx)
@@ -358,7 +366,7 @@ class GuiProjectDetailsContents(QWidget):
# ========
self.outerBox = QVBoxLayout()
self.outerBox.addWidget(QLabel("<b>Table of Contents</b>"))
self.outerBox.addWidget(QLabel("<b>%s</b>" % self.tr("Table of Contents")))
self.outerBox.addWidget(self.tocTree)
self.outerBox.addLayout(self.optionsBox)
@@ -390,7 +398,7 @@ class GuiProjectDetailsContents(QWidget):
"""
self._theToC = []
self._theToC = self.theIndex.getTableOfContents(2)
self._theToC.append(("", 0, "END", 0))
self._theToC.append(("", 0, self.tr("END"), 0))
return
##
+23 -12
View File
@@ -74,7 +74,7 @@ class GuiProjectLoad(QDialog):
self.outerBox.setSpacing(sPx)
self.innerBox.setSpacing(sPx)
self.setWindowTitle("Open Project")
self.setWindowTitle(self.tr("Open Project"))
self.setMinimumWidth(self.mainConf.pxInt(650))
self.setMinimumHeight(self.mainConf.pxInt(400))
self.setModal(True)
@@ -90,7 +90,11 @@ class GuiProjectLoad(QDialog):
self.listBox.setSelectionMode(QAbstractItemView.SingleSelection)
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
self.listBox.setColumnCount(3)
self.listBox.setHeaderLabels(["Working Title", "Words", "Last Opened"])
self.listBox.setHeaderLabels([
self.tr("Working Title"),
self.tr("Words"),
self.tr("Last Opened"),
])
self.listBox.setRootIsDecorated(False)
self.listBox.itemSelectionChanged.connect(self._doSelectRecent)
self.listBox.itemDoubleClicked.connect(self._doOpenRecent)
@@ -100,8 +104,8 @@ class GuiProjectLoad(QDialog):
treeHead.setTextAlignment(self.C_COUNT, Qt.AlignRight)
treeHead.setTextAlignment(self.C_TIME, Qt.AlignRight)
self.lblRecent = QLabel("<b>Recently Opened Projects</b>")
self.lblPath = QLabel("<b>Path</b>")
self.lblRecent = QLabel("<b>%s</b>" % self.tr("Recently Opened Projects"))
self.lblPath = QLabel("<b>%s</b>" % self.tr("Path"))
self.selPath = QLineEdit("")
self.selPath.setReadOnly(True)
@@ -123,13 +127,15 @@ class GuiProjectLoad(QDialog):
self.innerBox.addLayout(self.projectForm)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Open | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Open).setText(self.tr("Open"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doOpenRecent)
self.buttonBox.rejected.connect(self._doCancel)
self.newButton = self.buttonBox.addButton("New", QDialogButtonBox.ActionRole)
self.newButton = self.buttonBox.addButton(self.tr("New"), QDialogButtonBox.ActionRole)
self.newButton.clicked.connect(self._doNewProject)
self.delButton = self.buttonBox.addButton("Remove", QDialogButtonBox.ActionRole)
self.delButton = self.buttonBox.addButton(self.tr("Remove"), QDialogButtonBox.ActionRole)
self.delButton.clicked.connect(self._doDeleteRecent)
self.outerBox.addLayout(self.innerBox)
@@ -183,8 +189,12 @@ class GuiProjectLoad(QDialog):
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.DontUseNativeDialog
projFile, _ = QFileDialog.getOpenFileName(
self, "Open novelWriter Project", "",
"novelWriter Project File (%s);;All Files (*)" % nwFiles.PROJ_FILE,
self, self.tr("Open novelWriter Project"), "",
";;".join([
self.tr("{0} ({1})").format(
self.tr("novelWriter Project File"), nwFiles.PROJ_FILE),
self.tr("{0} ({1})").format(self.tr("All Files"), "*")
]),
options=dlgOpt
)
if projFile:
@@ -221,10 +231,11 @@ class GuiProjectLoad(QDialog):
selList = self.listBox.selectedItems()
if selList:
projName = selList[0].text(self.C_NAME)
msgYes = self.theParent.askQuestion("Remove Entry", (
"Remove '%s' from the recent projects list? "
"The project files will not be deleted."
) % projName)
msgYes = self.theParent.askQuestion(
self.tr("Remove Entry"),
self.tr("Remove '{0}' from the recent projects list? "
"The project files will not be deleted.").format(projName)
)
if msgYes:
self.mainConf.removeFromRecentCache(
selList[0].data(self.C_NAME, Qt.UserRole)
+46 -36
View File
@@ -54,7 +54,7 @@ class GuiProjectSettings(PagedDialog):
self.optState = theProject.optState
self.theProject.countStatus()
self.setWindowTitle("Project Settings")
self.setWindowTitle(self.tr("Project Settings"))
wW = self.mainConf.pxInt(570)
wH = self.mainConf.pxInt(375)
@@ -71,12 +71,14 @@ class GuiProjectSettings(PagedDialog):
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False)
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
self.addTab(self.tabMain, "Settings")
self.addTab(self.tabStatus, "Status")
self.addTab(self.tabImport, "Importance")
self.addTab(self.tabReplace, "Auto-Replace")
self.addTab(self.tabMain, self.tr("Settings"))
self.addTab(self.tabStatus, self.tr("Status"))
self.addTab(self.tabImport, self.tr("Importance"))
self.addTab(self.tabReplace, self.tr("Auto-Replace"))
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel"))
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
self.addControls(self.buttonBox)
@@ -166,7 +168,7 @@ class GuiProjectEditMain(QWidget):
self.mainForm.setHelpTextStyle(self.theParent.theTheme.helpText)
self.setLayout(self.mainForm)
self.mainForm.addGroupLabel("Project Settings")
self.mainForm.addGroupLabel(self.tr("Project Settings"))
xW = self.mainConf.pxInt(250)
xH = self.mainConf.pxInt(100)
@@ -176,9 +178,9 @@ class GuiProjectEditMain(QWidget):
self.editName.setFixedWidth(xW)
self.editName.setText(self.theProject.projName)
self.mainForm.addRow(
"Working title",
self.tr("Working title"),
self.editName,
"Should be set only once."
self.tr("Should be set only once.")
)
self.editTitle = QLineEdit()
@@ -186,9 +188,9 @@ class GuiProjectEditMain(QWidget):
self.editTitle.setFixedWidth(xW)
self.editTitle.setText(self.theProject.bookTitle)
self.mainForm.addRow(
"Novel title",
self.tr("Novel title"),
self.editTitle,
"Change whenever you want!"
self.tr("Change whenever you want!")
)
self.editAuthors = QPlainTextEdit()
@@ -199,22 +201,22 @@ class GuiProjectEditMain(QWidget):
self.editAuthors.setFixedHeight(xH)
self.editAuthors.setFixedWidth(xW)
self.mainForm.addRow(
"Author(s)",
self.tr("Author(s)"),
self.editAuthors,
"One name per line."
self.tr("One name per line.")
)
self.spellLang = QComboBox(self)
theDict = self.theParent.docEditor.theDict
self.spellLang.addItem("Default", "None")
self.spellLang.addItem(self.tr("Default"), "None")
if theDict is not None:
for spTag, spName in theDict.listDictionaries():
self.spellLang.addItem(spName, spTag)
self.mainForm.addRow(
"Spell check language",
self.tr("Spell check language"),
self.spellLang,
"Overrides main preferences."
self.tr("Overrides main preferences.")
)
spellIdx = 0
@@ -226,9 +228,9 @@ class GuiProjectEditMain(QWidget):
self.doBackup = QSwitch(self)
self.doBackup.setChecked(not self.theProject.doBackup)
self.mainForm.addRow(
"No backup on close",
self.tr("No backup on close"),
self.doBackup,
"Overrides main preferences."
self.tr("Overrides main preferences.")
)
return
@@ -271,12 +273,12 @@ class GuiProjectEditStatus(QWidget):
self.editName = QLineEdit()
self.editName.setMaxLength(40)
self.editName.setEnabled(False)
self.newButton = QPushButton("New")
self.delButton = QPushButton("Delete")
self.saveButton = QPushButton("Save")
self.newButton = QPushButton(self.tr("New"))
self.delButton = QPushButton(self.tr("Delete"))
self.saveButton = QPushButton(self.tr("Save"))
self.colPixmap = QPixmap(self.iPx, self.iPx)
self.colPixmap.fill(QColor(120, 120, 120))
self.colButton = QPushButton(QIcon(self.colPixmap), "Colour")
self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"))
self.colButton.setIconSize(self.colPixmap.rect().size())
self.newButton.clicked.connect(self._newItem)
@@ -287,7 +289,7 @@ class GuiProjectEditStatus(QWidget):
self.mainForm.addWidget(self.newButton)
self.mainForm.addWidget(self.delButton)
self.mainForm.addStretch(1)
self.mainForm.addWidget(QLabel("<b>Name</b>"))
self.mainForm.addWidget(QLabel("<b>%s</b>" % self.tr("Name")))
self.mainForm.addWidget(self.editName)
self.mainForm.addWidget(self.colButton)
self.mainForm.addStretch(1)
@@ -297,9 +299,9 @@ class GuiProjectEditStatus(QWidget):
self.mainBox.addLayout(self.mainForm)
if isStatus:
self.outerBox.addWidget(QLabel("<b>Novel File Status Levels</b>"))
self.outerBox.addWidget(QLabel("<b>%s</b>" % self.tr("Novel File Status Levels")))
else:
self.outerBox.addWidget(QLabel("<b>Note File Importance Levels</b>"))
self.outerBox.addWidget(QLabel("<b>%s</b>" % self.tr("Note File Importance Levels")))
self.outerBox.addLayout(self.mainBox)
self.setLayout(self.outerBox)
@@ -325,7 +327,10 @@ class GuiProjectEditStatus(QWidget):
"""
if self.selColour is not None:
newCol = QColorDialog.getColor(
self.selColour, self, "Select Colour", QColorDialog.DontUseNativeDialog
self.selColour,
self,
self.tr("Select Colour"),
QColorDialog.DontUseNativeDialog
)
if newCol.isValid():
self.selColour = newCol
@@ -338,7 +343,7 @@ class GuiProjectEditStatus(QWidget):
def _newItem(self):
"""Create a new status item.
"""
newItem = self._addItem("New Item", (0, 0, 0), None, 0)
newItem = self._addItem(self.tr("New Item"), (0, 0, 0), None, 0)
newItem.setBackground(QBrush(QColor(0, 255, 0, 80)))
self.colChanged = True
return
@@ -355,7 +360,7 @@ class GuiProjectEditStatus(QWidget):
self.colChanged = True
else:
self.theParent.makeAlert(
"Cannot delete status item that is in use.", nwAlert.ERROR
self.tr("Cannot delete status item that is in use."), nwAlert.ERROR
)
return
@@ -372,7 +377,8 @@ class GuiProjectEditStatus(QWidget):
self.selColour.blue(),
self.colData[selIdx][4]
)
selItem.setText("%s [%d]" % (self.colData[selIdx][0], self.colCounts[selIdx]))
selItem.setText(self.tr("{0} [{1}]").format(
self.colData[selIdx][0], self.colCounts[selIdx]))
selItem.setIcon(self.colButton.icon())
self.editName.setEnabled(False)
self.colChanged = True
@@ -384,7 +390,7 @@ class GuiProjectEditStatus(QWidget):
newIcon = QPixmap(self.iPx, self.iPx)
newIcon.fill(QColor(*iCol))
newItem = QListWidgetItem()
newItem.setText("%s [%d]" % (iName, nUse))
newItem.setText(self.tr("{0} [{1}]").format(iName, nUse))
newItem.setIcon(QIcon(newIcon))
newItem.setData(Qt.UserRole, len(self.colData))
self.listBox.addItem(newItem)
@@ -450,13 +456,16 @@ class GuiProjectEditReplace(QWidget):
self.optState.getInt("GuiProjectSettings", "replaceColW", 100)
)
self.listBox = QTreeWidget()
self.listBox.setHeaderLabels(["Keyword", "Replace With"])
self.listBox.setHeaderLabels([
self.tr("Keyword"),
self.tr("Replace With"),
])
self.listBox.itemSelectionChanged.connect(self._selectedItem)
self.listBox.setColumnWidth(0, wCol0)
self.listBox.setIndentation(0)
for aKey, aVal in self.theProject.autoReplace.items():
newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
newItem = QTreeWidgetItem([self.tr("<{0}>").format(aKey), aVal])
self.listBox.addTopLevelItem(newItem)
self.listBox.sortByColumn(0, Qt.AscendingOrder)
@@ -467,9 +476,9 @@ class GuiProjectEditReplace(QWidget):
self.saveButton = QPushButton(self.theTheme.getIcon("done"), "")
self.addButton = QPushButton(self.theTheme.getIcon("add"), "")
self.delButton = QPushButton(self.theTheme.getIcon("remove"), "")
self.saveButton.setToolTip("Save entry")
self.addButton.setToolTip("Add new entry")
self.delButton.setToolTip("Delete selected entry")
self.saveButton.setToolTip(self.tr("Save entry"))
self.addButton.setToolTip(self.tr("Add new entry"))
self.delButton.setToolTip(self.tr("Delete selected entry"))
self.editKey.setEnabled(False)
self.editKey.setMaxLength(40)
@@ -486,7 +495,8 @@ class GuiProjectEditReplace(QWidget):
self.bottomBox.addWidget(self.addButton)
self.bottomBox.addWidget(self.delButton)
self.outerBox.addWidget(QLabel("<b>Text Replace List for Preview and Export</b>"))
self.outerBox.addWidget(
QLabel("<b>%s</b>" % self.tr("Text Replace List for Preview and Export")))
self.outerBox.addWidget(self.listBox)
self.outerBox.addLayout(self.bottomBox)
self.setLayout(self.outerBox)
@@ -538,7 +548,7 @@ class GuiProjectEditReplace(QWidget):
saveKey = self._stripNotAllowed(newKey)
if len(saveKey) > 0 and len(newVal) > 0:
selItem.setText(0, "<%s>" % saveKey)
selItem.setText(0, self.tr("<{0}>").format(saveKey))
selItem.setText(1, newVal)
self.editKey.clear()
self.editValue.clear()
+53 -41
View File
@@ -30,7 +30,7 @@ import logging
from time import time
from PyQt5.QtCore import Qt, QSize, pyqtSignal
from PyQt5.QtCore import QCoreApplication, Qt, QSize, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMenu, QAction
@@ -85,14 +85,19 @@ class GuiProjectTree(QTreeWidget):
self.setExpandsOnDoubleClick(True)
self.setIndentation(iPx)
self.setColumnCount(4)
self.setHeaderLabels(["Label", "Words", "Inc", "Flags"])
self.setHeaderLabels([
self.tr("Label"),
self.tr("Words"),
self.tr("Inc"),
self.tr("Flags")
])
treeHeadItem = self.headerItem()
treeHeadItem.setTextAlignment(self.C_COUNT, Qt.AlignRight)
treeHeadItem.setToolTip(self.C_NAME, "Item label")
treeHeadItem.setToolTip(self.C_COUNT, "Word count")
treeHeadItem.setToolTip(self.C_EXPORT, "Include in build")
treeHeadItem.setToolTip(self.C_FLAGS, "Status, class, and layout flags")
treeHeadItem.setToolTip(self.C_NAME, self.tr("Item label"))
treeHeadItem.setToolTip(self.C_COUNT, self.tr("Word count"))
treeHeadItem.setToolTip(self.C_EXPORT, self.tr("Include in build"))
treeHeadItem.setToolTip(self.C_FLAGS, self.tr("Status, class, and layout flags"))
# Let the last column stretch, and set the minimum size to the
# size of the icon as the default Qt font metrics approach fails
@@ -193,12 +198,12 @@ class GuiProjectTree(QTreeWidget):
if itemClass is None:
if itemType == nwItemType.FILE:
self.makeAlert(
"Please select a valid location in the tree to add the document.",
self.tr("Please select a valid location in the tree to add the document."),
nwAlert.ERROR
)
else:
self.makeAlert(
"Please select a valid location in the tree to add the folder.",
self.tr("Please select a valid location in the tree to add the folder."),
nwAlert.ERROR
)
return False
@@ -209,7 +214,8 @@ class GuiProjectTree(QTreeWidget):
)
if itemType == nwItemType.ROOT:
tHandle = self.theProject.newRoot(nwLabels.CLASS_NAME[itemClass], itemClass)
tHandle = self.theProject.newRoot(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[itemClass]), itemClass)
if tHandle is None:
logger.error("No root item added")
return False
@@ -223,7 +229,7 @@ class GuiProjectTree(QTreeWidget):
# If still nothing, give up
if pHandle is None:
self.makeAlert(
"Did not find anywhere to add the file or folder!", nwAlert.ERROR
self.tr("Did not find anywhere to add the file or folder!"), nwAlert.ERROR
)
return False
@@ -237,14 +243,15 @@ class GuiProjectTree(QTreeWidget):
# If we again have no home, give up
if pHandle is None:
self.makeAlert(
"Did not find anywhere to add the file or folder!", nwAlert.ERROR
self.tr("Did not find anywhere to add the file or folder!"), nwAlert.ERROR
)
return False
if self.theProject.projTree.isTrashRoot(pHandle):
self.makeAlert(
"Cannot add new files or folders to the %s folder." % (
nwLabels.CLASS_NAME[nwItemClass.TRASH]
self.tr("Cannot add new files or folders to the {0} folder.").format(
QCoreApplication.translate(
"Constant", nwLabels.CLASS_NAME[nwItemClass.TRASH])
), nwAlert.ERROR
)
return False
@@ -253,18 +260,18 @@ class GuiProjectTree(QTreeWidget):
# If we're still here, add the file or folder
if itemType == nwItemType.FILE:
tHandle = self.theProject.newFile("New File", itemClass, pHandle)
tHandle = self.theProject.newFile(self.tr("New File"), itemClass, pHandle)
elif itemType == nwItemType.FOLDER:
if len(parTree) >= nwConst.MAX_DEPTH - 1:
# Folders cannot be deeper than MAX_DEPTH - 1, leaving room
# for one more level of files.
self.makeAlert((
"Cannot add new folder to this item. "
"Maximum folder depth has been reached."
self.tr("Cannot add new folder to this item."),
self.tr("Maximum folder depth has been reached.")
), nwAlert.ERROR)
return False
tHandle = self.theProject.newFolder("New Folder", itemClass, pHandle)
tHandle = self.theProject.newFolder(self.tr("New Folder"), itemClass, pHandle)
else:
logger.error("Failed to add new item")
@@ -428,7 +435,7 @@ class GuiProjectTree(QTreeWidget):
logger.debug("Emptying Trash folder")
if trashHandle is None:
self.makeAlert(
"There is currently no Trash folder in this project.", nwAlert.INFO
self.tr("There is currently no Trash folder in this project."), nwAlert.INFO
)
return False
@@ -438,11 +445,12 @@ class GuiProjectTree(QTreeWidget):
nTrash = len(theTrash)
if nTrash == 0:
self.makeAlert("The Trash folder is already empty.", nwAlert.INFO)
self.makeAlert(self.tr("The Trash folder is already empty."), nwAlert.INFO)
return False
msgYes = self.askQuestion(
"Empty Trash", "Permanently delete %d file(s) from Trash?" % nTrash
self.tr("Empty Trash"),
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
)
if not msgYes:
return False
@@ -500,7 +508,8 @@ class GuiProjectTree(QTreeWidget):
doPermanent = False
if not alreadyAsked:
msgYes = self.askQuestion(
"Delete File", "Permanently delete file '%s'?" % nwItemS.itemName
self.tr("Delete File"),
self.tr("Permanently delete file '{0}'?").format(nwItemS.itemName)
)
if msgYes:
doPermanent = True
@@ -529,7 +538,8 @@ class GuiProjectTree(QTreeWidget):
doTrash = False
if askForTrash:
msgYes = self.askQuestion(
"Delete File", "Move file '%s' to Trash?" % nwItemS.itemName
self.tr("Delete File"),
self.tr("Move file '{0}' to Trash?").format(nwItemS.itemName),
)
if msgYes:
doTrash = True
@@ -564,9 +574,9 @@ class GuiProjectTree(QTreeWidget):
self._setTreeChanged(True)
else:
self.makeAlert((
"Cannot delete folder. It is not empty. "
"Recursive deletion is not supported. "
"Please delete the content first."
self.tr("Cannot delete folder. It is not empty."),
self.tr("Recursive deletion is not supported."),
self.tr("Please delete the content first."),
), nwAlert.ERROR)
return False
@@ -580,9 +590,9 @@ class GuiProjectTree(QTreeWidget):
self._setTreeChanged(True)
else:
self.makeAlert((
"Cannot delete root folder. It is not empty. "
"Recursive deletion is not supported. "
"Please delete the content first."
self.tr("Cannot delete root folder. It is not empty."),
self.tr("Recursive deletion is not supported."),
self.tr("Please delete the content first."),
), nwAlert.ERROR)
return False
@@ -835,7 +845,7 @@ class GuiProjectTree(QTreeWidget):
snItem = self.theProject.projTree[sHandle]
dnItem = self.theProject.projTree[dHandle]
if dnItem is None:
self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR)
self.makeAlert(self.tr("The item cannot be moved to that location."), nwAlert.ERROR)
return
pItem = sItem.parent()
@@ -866,7 +876,7 @@ class GuiProjectTree(QTreeWidget):
else:
theEvent.ignore()
logger.debug("Drag'n'drop of item %s not accepted" % sHandle)
self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR)
self.makeAlert(self.tr("The item cannot be moved to that location."), nwAlert.ERROR)
return
@@ -964,7 +974,9 @@ class GuiProjectTree(QTreeWidget):
self.addTopLevelItem(newItem)
else:
self.makeAlert(
"There is nowhere to add item with name '%s'" % nwItem.itemName, nwAlert.ERROR
self.tr("There is nowhere to add item with name '{0}'").format(
nwItem.itemName),
nwAlert.ERROR
)
del self._treeMap[tHandle]
return None
@@ -1083,43 +1095,43 @@ class GuiProjectTreeMenu(QMenu):
self.theTree = theTree
self.theItem = None
self.editItem = QAction("Edit Project Item", self)
self.editItem = QAction(self.tr("Edit Project Item"), self)
self.editItem.triggered.connect(self._doEditItem)
self.addAction(self.editItem)
self.openItem = QAction("Open Document", self)
self.openItem = QAction(self.tr("Open Document"), self)
self.openItem.triggered.connect(self._doOpenItem)
self.addAction(self.openItem)
self.viewItem = QAction("View Document", self)
self.viewItem = QAction(self.tr("View Document"), self)
self.viewItem.triggered.connect(self._doViewItem)
self.addAction(self.viewItem)
self.toggleExp = QAction("Toggle Included Flag", self)
self.toggleExp = QAction(self.tr("Toggle Included Flag"), self)
self.toggleExp.triggered.connect(self._doToggleExported)
self.addAction(self.toggleExp)
self.newFile = QAction("New File", self)
self.newFile = QAction(self.tr("New File"), self)
self.newFile.triggered.connect(self._doMakeFile)
self.addAction(self.newFile)
self.newFolder = QAction("New Folder", self)
self.newFolder = QAction(self.tr("New Folder"), self)
self.newFolder.triggered.connect(self._doMakeFolder)
self.addAction(self.newFolder)
self.deleteItem = QAction("Delete Item", self)
self.deleteItem = QAction(self.tr("Delete Item"), self)
self.deleteItem.triggered.connect(self._doDeleteItem)
self.addAction(self.deleteItem)
self.emptyTrash = QAction("Empty Trash", self)
self.emptyTrash = QAction(self.tr("Empty Trash"), self)
self.emptyTrash.triggered.connect(self._doEmptyTrash)
self.addAction(self.emptyTrash)
self.moveUp = QAction("Move Item Up", self)
self.moveUp = QAction(self.tr("Move Item Up"), self)
self.moveUp.triggered.connect(self._doMoveUp)
self.addAction(self.moveUp)
self.moveDown = QAction("Move Item Down", self)
self.moveDown = QAction(self.tr("Move Item Down"), self)
self.moveDown.triggered.connect(self._doMoveDown)
self.addAction(self.moveDown)
+56 -48
View File
@@ -28,7 +28,7 @@ import nw
import logging
import os
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtWidgets import (
QWizard, QWizardPage, QLabel, QVBoxLayout, QLineEdit, QPlainTextEdit,
QPushButton, QFileDialog, QHBoxLayout, QRadioButton, QFormLayout,
@@ -94,16 +94,19 @@ class ProjWizardIntroPage(QWizardPage):
self.theWizard = theWizard
self.theTheme = theWizard.theTheme
self.setTitle("Create New Project")
self.setTitle(self.tr("Create New Project"))
self.theText = QLabel(
"Provide at least a working title. The working title should not "
"be change beyond this point as it is used by the application for "
"generating file names for for instance backups. The other fields "
"are optional and can be changed at any time in Project Settings."
self.tr("Provide at least a working title. The working title should not "
"be change beyond this point as it is used by the application for "
"generating file names for for instance backups. The other fields "
"are optional and can be changed at any time in Project Settings.")
)
self.theText.setWordWrap(True)
self.imgCredit = QLabel("Side image by Peter Mitterhofer, CC BY-SA 4.0")
self.imgCredit = QLabel(self.tr("Side image by {author:s}, {license:s}").format(
author = "Peter Mitterhofer",
license = "CC BY-SA 4.0"
))
lblFont = self.imgCredit.font()
lblFont.setPointSizeF(0.6*self.theTheme.fontPointSize)
self.imgCredit.setFont(lblFont)
@@ -117,22 +120,22 @@ class ProjWizardIntroPage(QWizardPage):
self.projName = QLineEdit()
self.projName.setMaxLength(200)
self.projName.setFixedWidth(xW)
self.projName.setPlaceholderText("Required")
self.projName.setPlaceholderText(self.tr("Required"))
self.projTitle = QLineEdit()
self.projTitle.setMaxLength(200)
self.projTitle.setFixedWidth(xW)
self.projTitle.setPlaceholderText("Optional")
self.projTitle.setPlaceholderText(self.tr("Optional"))
self.projAuthors = QPlainTextEdit()
self.projAuthors.setFixedHeight(xH)
self.projAuthors.setFixedWidth(xW)
self.projAuthors.setPlaceholderText("Optional. One name per line.")
self.projAuthors.setPlaceholderText(self.tr("Optional. One name per line."))
self.mainForm = QFormLayout()
self.mainForm.addRow("Working Title", self.projName)
self.mainForm.addRow("Novel Title", self.projTitle)
self.mainForm.addRow("Author(s)", self.projAuthors)
self.mainForm.addRow(self.tr("Working Title"), self.projName)
self.mainForm.addRow(self.tr("Novel Title"), self.projTitle)
self.mainForm.addRow(self.tr("Author(s)"), self.projAuthors)
self.mainForm.setVerticalSpacing(fS)
self.registerField("projName*", self.projName)
@@ -161,10 +164,10 @@ class ProjWizardFolderPage(QWizardPage):
self.theWizard = theWizard
self.theTheme = theWizard.theTheme
self.setTitle("Select Project Folder")
self.setTitle(self.tr("Select Project Folder"))
self.theText = QLabel(
"Select a location to store the project. A new project folder "
"will be created in the selected location."
self.tr("Select a location to store the project. A new project folder "
"will be created in the selected location.")
)
self.theText.setWordWrap(True)
@@ -174,14 +177,14 @@ class ProjWizardFolderPage(QWizardPage):
self.projPath = QLineEdit("")
self.projPath.setFixedWidth(xW)
self.projPath.setPlaceholderText("Required")
self.projPath.setPlaceholderText(self.tr("Required"))
self.browseButton = QPushButton("...")
self.browseButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("...")))
self.browseButton.clicked.connect(self._doBrowse)
self.mainForm = QHBoxLayout()
self.mainForm.addWidget(QLabel("Project Path"), 0)
self.mainForm.addWidget(QLabel(self.tr("Project Path")), 0)
self.mainForm.addWidget(self.projPath, 1)
self.mainForm.addWidget(self.browseButton, 0)
self.mainForm.setSpacing(fS)
@@ -213,7 +216,7 @@ class ProjWizardFolderPage(QWizardPage):
dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
projDir = QFileDialog.getExistingDirectory(
self, "Select Project Folder", lastPath, options=dlgOpt
self, self.tr("Select Project Folder"), lastPath, options=dlgOpt
)
if projDir:
projName = self.field("projName")
@@ -235,20 +238,20 @@ class ProjWizardPopulatePage(QWizardPage):
self.mainConf = nw.CONFIG
self.theWizard = theWizard
self.setTitle("Populate Project")
self.setTitle(self.tr("Populate Project"))
self.theText = QLabel(
"Choose how to pre-fill the project. Either with a minimal set of "
"starter items, an example project explaining and showing many of "
"the features, or show further custom options on the next page."
self.tr("Choose how to pre-fill the project. Either with a minimal set of "
"starter items, an example project explaining and showing many of "
"the features, or show further custom options on the next page.")
)
self.theText.setWordWrap(True)
vS = self.mainConf.pxInt(12)
fS = self.mainConf.pxInt(4)
self.popMinimal = QRadioButton("Fill the project with a minimal set of items")
self.popSample = QRadioButton("Fill the project with example files")
self.popCustom = QRadioButton("Show detailed options for filling the project")
self.popMinimal = QRadioButton(self.tr("Fill the project with a minimal set of items"))
self.popSample = QRadioButton(self.tr("Fill the project with example files"))
self.popCustom = QRadioButton(self.tr("Show detailed options for filling the project"))
self.popMinimal.setChecked(True)
self.popBox = QVBoxLayout()
@@ -290,27 +293,33 @@ class ProjWizardCustomPage(QWizardPage):
self.mainConf = nw.CONFIG
self.theWizard = theWizard
self.setTitle("Custom Project Options")
self.setTitle(self.tr("Custom Project Options"))
self.theText = QLabel(
"Select which additional root folders to make, and how to populate "
"the Novel folder. If you don't want to add chapters or scenes, set "
"the values to 0. You can add scenes without chapters."
self.tr("Select which additional root folders to make, and how to populate "
"the Novel folder. If you don't want to add chapters or scenes, set "
"the values to 0. You can add scenes without chapters.")
)
self.theText.setWordWrap(True)
vS = self.mainConf.pxInt(12)
# Root Folders
self.rootGroup = QGroupBox("Additional Root Folders")
self.rootGroup = QGroupBox(self.tr("Additional Root Folders"))
self.rootForm = QGridLayout()
self.rootGroup.setLayout(self.rootForm)
self.lblPlot = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.PLOT])
self.lblChar = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.CHARACTER])
self.lblWorld = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.WORLD])
self.lblTime = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.TIMELINE])
self.lblObject = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.OBJECT])
self.lblEntity = QLabel("%s folder" % nwLabels.CLASS_NAME[nwItemClass.ENTITY])
self.lblPlot = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.PLOT])))
self.lblChar = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.CHARACTER])))
self.lblWorld = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.WORLD])))
self.lblTime = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.TIMELINE])))
self.lblObject = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.OBJECT])))
self.lblEntity = QLabel(self.tr("{0} folder").format(
QCoreApplication.translate("Constant", nwLabels.CLASS_NAME[nwItemClass.ENTITY])))
self.addPlot = QSwitch()
self.addChar = QSwitch()
@@ -338,7 +347,7 @@ class ProjWizardCustomPage(QWizardPage):
self.rootForm.setRowStretch(6, 1)
# Novel Options
self.novelGroup = QGroupBox("Populate Novel Folder")
self.novelGroup = QGroupBox(self.tr("Populate Novel Folder"))
self.novelForm = QGridLayout()
self.novelGroup.setLayout(self.novelForm)
@@ -353,9 +362,9 @@ class ProjWizardCustomPage(QWizardPage):
self.chFolders = QSwitch()
self.chFolders.setChecked(True)
self.novelForm.addWidget(QLabel("Add chapters"), 0, 0)
self.novelForm.addWidget(QLabel("Scenes (per chapter)"), 1, 0)
self.novelForm.addWidget(QLabel("Add chapter folders"), 2, 0)
self.novelForm.addWidget(QLabel(self.tr("Add chapters")), 0, 0)
self.novelForm.addWidget(QLabel(self.tr("Scenes (per chapter)")), 1, 0)
self.novelForm.addWidget(QLabel(self.tr("Add chapter folders")), 2, 0)
self.novelForm.addWidget(self.numChapters, 0, 1, 1, 1, Qt.AlignRight)
self.novelForm.addWidget(self.numScenes, 1, 1, 1, 1, Qt.AlignRight)
self.novelForm.addWidget(self.chFolders, 2, 1, 1, 1, Qt.AlignRight)
@@ -396,13 +405,12 @@ class ProjWizardFinalPage(QWizardPage):
self.mainConf = nw.CONFIG
self.theWizard = theWizard
self.setTitle("Finished")
self.theText = QLabel((
"<p>All done.</p>"
"<p>Press '{finish}' to create the new project.</p>"
).format(
finish = "Done" if self.mainConf.osDarwin else "Finish"
))
self.setTitle(self.tr("Finished"))
self.theText = QLabel("".join([
("<p>%s</p>" % self.tr("All done.")),
("<p>%s</p>" % self.tr("Press '{0}' to create the new project.").format(
self.tr("Done") if self.mainConf.osDarwin else self.tr("Finish")))
]))
self.theText.setWordWrap(True)
# Assemble
+10 -8
View File
@@ -63,7 +63,7 @@ class GuiMainStatus(QStatusBar):
## The Spell Checker Language
self.langIcon = QLabel("")
self.langText = QLabel("None")
self.langText = QLabel(self.tr("None"))
self.langIcon.setPixmap(self.theTheme.getPixmap("status_lang", (iPx, iPx)))
self.langIcon.setContentsMargins(0, 0, 0, 0)
self.langText.setContentsMargins(0, 0, xM, 0)
@@ -72,7 +72,7 @@ class GuiMainStatus(QStatusBar):
## The Editor Status
self.docIcon = StatusLED(colNone, colTrue, colFalse, iPx, iPx, self)
self.docText = QLabel("Editor")
self.docText = QLabel(self.tr("Editor"))
self.docIcon.setContentsMargins(0, 0, 0, 0)
self.docText.setContentsMargins(0, 0, xM, 0)
self.addPermanentWidget(self.docIcon)
@@ -80,7 +80,7 @@ class GuiMainStatus(QStatusBar):
## The Project Status
self.projIcon = StatusLED(colNone, colTrue, colFalse, iPx, iPx, self)
self.projText = QLabel("Project")
self.projText = QLabel(self.tr("Project"))
self.projIcon.setContentsMargins(0, 0, 0, 0)
self.projText.setContentsMargins(0, 0, xM, 0)
self.addPermanentWidget(self.projIcon)
@@ -103,7 +103,7 @@ class GuiMainStatus(QStatusBar):
self.timeIcon = QLabel()
self.timeText = QLabel("")
self.timeIcon.setPixmap(self.timePixmap)
self.timeText.setToolTip("Session Time")
self.timeText.setToolTip(self.tr("Session Time"))
self.timeText.setMinimumWidth(self.theTheme.getTextWidth("00:00:00:"))
self.timeIcon.setContentsMargins(0, 0, 0, 0)
self.timeText.setContentsMargins(0, 0, 0, 0)
@@ -151,12 +151,14 @@ class GuiMainStatus(QStatusBar):
"""Set the language code for the spell checker.
"""
if theLanguage is None:
self.langText.setText("None")
self.langText.setText(self.tr("None"))
self.langText.setToolTip("")
else:
self.langText.setText(NWSpellCheck.expandLanguage(theLanguage))
self.langText.setToolTip(
"Provider: %s" % (theProvider if theProvider else "unknown")
self.tr("{0}: {1}").format(
self.tr("Provider"),
theProvider if theProvider else self.tr("unknown"))
)
return
@@ -175,8 +177,8 @@ class GuiMainStatus(QStatusBar):
def setStats(self, pWC, sWC):
"""Set the current project statistics.
"""
self.statsText.setText(f"Words: {pWC:n} ({sWC:+n})")
self.statsText.setToolTip("Project word count (session change)")
self.statsText.setText("%s: %s (%s)" % (self.tr("Words"), f"{pWC:n}", f"{sWC:+n}"))
self.statsText.setToolTip(self.tr("Project word count (session change)"))
return
def setUserIdle(self, userIdle):
+3 -3
View File
@@ -393,7 +393,7 @@ class GuiTheme:
confParser.read_file(inFile)
except Exception as e:
self.theParent.makeAlert(
["Could not load theme config file.", str(e)], nwAlert.ERROR
[self.tr("Could not load theme config file."), str(e)], nwAlert.ERROR
)
continue
themeName = ""
@@ -426,7 +426,7 @@ class GuiTheme:
confParser.read_file(inFile)
except Exception as e:
self.theParent.makeAlert(
["Could not load syntax file.", str(e)], nwAlert.ERROR
[self.tr("Could not load syntax file."), str(e)], nwAlert.ERROR
)
return []
syntaxName = ""
@@ -741,7 +741,7 @@ class GuiIcons:
confParser.read_file(inFile)
except Exception as e:
self.theParent.makeAlert(
["Could not load theme config file.", str(e)], nwAlert.ERROR
[self.tr("Could not load theme config file."), str(e)], nwAlert.ERROR
)
continue
themeName = ""
+9 -6
View File
@@ -52,7 +52,7 @@ class GuiWordList(QDialog):
self.theProject = theProject
self.optState = theProject.optState
self.setWindowTitle("Project Word List")
self.setWindowTitle(self.tr("Project Word List"))
mS = self.mainConf.pxInt(250)
wW = self.mainConf.pxInt(320)
@@ -68,7 +68,7 @@ class GuiWordList(QDialog):
# Main Widgets
# ============
self.headLabel = QLabel("<b>Project Word List</b>")
self.headLabel = QLabel("<b>%s</b>" % self.tr("Project Word List"))
self.listBox = QListWidget()
self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop)
@@ -77,11 +77,11 @@ class GuiWordList(QDialog):
self.newEntry = QLineEdit()
self.addButton = QPushButton(self.theTheme.getIcon("add"), "")
self.addButton.setToolTip("Add new entry")
self.addButton.setToolTip(self.tr("Add new entry"))
self.addButton.clicked.connect(self._doAdd)
self.delButton = QPushButton(self.theTheme.getIcon("remove"), "")
self.delButton.setToolTip("Delete selected entry")
self.delButton.setToolTip(self.tr("Delete selected entry"))
self.delButton.clicked.connect(self._doDelete)
self.editBox = QHBoxLayout()
@@ -90,6 +90,8 @@ class GuiWordList(QDialog):
self.editBox.addWidget(self.delButton, 0)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close)
self.buttonBox.button(QDialogButtonBox.Save).setText(self.tr("Save"))
self.buttonBox.button(QDialogButtonBox.Close).setText(self.tr("Close"))
self.buttonBox.accepted.connect(self._doSave)
self.buttonBox.rejected.connect(self._doClose)
@@ -121,12 +123,13 @@ class GuiWordList(QDialog):
"""
newWord = self.newEntry.text().strip()
if newWord == "":
self.theParent.makeAlert("Cannot add a blank word.", nwAlert.ERROR)
self.theParent.makeAlert(self.tr("Cannot add a blank word."), nwAlert.ERROR)
return False
if self.listBox.findItems(newWord, Qt.MatchExactly):
self.theParent.makeAlert(
"The word '%s' is already in the word list." % newWord, nwAlert.ERROR
self.tr("The word '{0}' is already in the word list.").format(newWord),
nwAlert.ERROR
)
return False
+33 -24
View File
@@ -72,7 +72,7 @@ class GuiWritingStats(QDialog):
self.timeFilter = 0.0
self.wordOffset = 0
self.setWindowTitle("Writing Statistics")
self.setWindowTitle(self.tr("Writing Statistics"))
self.setMinimumWidth(self.mainConf.pxInt(420))
self.setMinimumHeight(self.mainConf.pxInt(400))
self.resize(
@@ -95,7 +95,13 @@ class GuiWritingStats(QDialog):
)
self.listBox = QTreeWidget()
self.listBox.setHeaderLabels(["Session Start", "Length", "Idle", "Words", "Histogram"])
self.listBox.setHeaderLabels([
self.tr("Session Start"),
self.tr("Length"),
self.tr("Idle"),
self.tr("Words"),
self.tr("Histogram"),
])
self.listBox.setIndentation(0)
self.listBox.setColumnWidth(self.C_TIME, wCol0)
self.listBox.setColumnWidth(self.C_LENGTH, wCol1)
@@ -125,7 +131,7 @@ class GuiWritingStats(QDialog):
self.barImage.fill(self.palette().highlight().color())
# Session Info
self.infoBox = QGroupBox("Sum Totals", self)
self.infoBox = QGroupBox(self.tr("Sum Totals"), self)
self.infoForm = QGridLayout(self)
self.infoBox.setLayout(self.infoForm)
@@ -153,12 +159,12 @@ class GuiWritingStats(QDialog):
self.totalWords.setFont(self.theTheme.guiFontFixed)
self.totalWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
self.infoForm.addWidget(QLabel("Total Time:"), 0, 0)
self.infoForm.addWidget(QLabel("Idle Time:"), 1, 0)
self.infoForm.addWidget(QLabel("Filtered Time:"), 2, 0)
self.infoForm.addWidget(QLabel("Novel Word Count:"), 3, 0)
self.infoForm.addWidget(QLabel("Notes Word Count:"), 4, 0)
self.infoForm.addWidget(QLabel("Total Word Count:"), 5, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Total Time"))), 0, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Idle Time"))), 1, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Filtered Time"))), 2, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Novel Word Count"))), 3, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Notes Word Count"))), 4, 0)
self.infoForm.addWidget(QLabel(self.tr("{0}:").format(self.tr("Total Word Count"))), 5, 0)
self.infoForm.addWidget(self.labelTotal, 0, 1)
self.infoForm.addWidget(self.labelIdleT, 1, 1)
self.infoForm.addWidget(self.labelFilter, 2, 1)
@@ -170,7 +176,7 @@ class GuiWritingStats(QDialog):
# Filter Options
sPx = self.theTheme.baseIconSize
self.filterBox = QGroupBox("Filters", self)
self.filterBox = QGroupBox(self.tr("Filters"), self)
self.filterForm = QGridLayout(self)
self.filterBox.setLayout(self.filterForm)
@@ -210,12 +216,12 @@ class GuiWritingStats(QDialog):
)
self.showIdleTime.clicked.connect(self._updateListBox)
self.filterForm.addWidget(QLabel("Count novel files"), 0, 0)
self.filterForm.addWidget(QLabel("Count note files"), 1, 0)
self.filterForm.addWidget(QLabel("Hide zero word count"), 2, 0)
self.filterForm.addWidget(QLabel("Hide negative word count"), 3, 0)
self.filterForm.addWidget(QLabel("Group entries by day"), 4, 0)
self.filterForm.addWidget(QLabel("Show idle time"), 5, 0)
self.filterForm.addWidget(QLabel(self.tr("Count novel files")), 0, 0)
self.filterForm.addWidget(QLabel(self.tr("Count note files")), 1, 0)
self.filterForm.addWidget(QLabel(self.tr("Hide zero word count")), 2, 0)
self.filterForm.addWidget(QLabel(self.tr("Hide negative word count")), 3, 0)
self.filterForm.addWidget(QLabel(self.tr("Group entries by day")), 4, 0)
self.filterForm.addWidget(QLabel(self.tr("Show idle time")), 5, 0)
self.filterForm.addWidget(self.incNovel, 0, 1)
self.filterForm.addWidget(self.incNotes, 1, 1)
self.filterForm.addWidget(self.hideZeros, 2, 1)
@@ -236,7 +242,7 @@ class GuiWritingStats(QDialog):
self.optsBox = QHBoxLayout()
self.optsBox.addStretch(1)
self.optsBox.addWidget(QLabel("Word count cap for the histogram"), 0)
self.optsBox.addWidget(QLabel(self.tr("Word count cap for the histogram")), 0)
self.optsBox.addWidget(self.histMax, 0)
# Buttons
@@ -244,19 +250,22 @@ class GuiWritingStats(QDialog):
self.buttonBox.rejected.connect(self._doClose)
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
self.buttonBox.button(QDialogButtonBox.Close).setText(self.tr("Close"))
self.btnClose.setAutoDefault(False)
self.btnSave = self.buttonBox.addButton("Save As", QDialogButtonBox.ActionRole)
self.btnSave = self.buttonBox.addButton(self.tr("Save As"), QDialogButtonBox.ActionRole)
self.btnSave.setAutoDefault(False)
self.saveMenu = QMenu(self)
self.btnSave.setMenu(self.saveMenu)
self.saveJSON = QAction("JSON Data File (.json)", self)
self.saveJSON = QAction(self.tr("{0} ({1})").format(
self.tr("JSON Data File"), ".json"), self)
self.saveJSON.triggered.connect(lambda: self._saveData(self.FMT_JSON))
self.saveMenu.addAction(self.saveJSON)
self.saveCSV = QAction("CSV Data File (.csv)", self)
self.saveCSV = QAction(self.tr("{0} ({1})").format(
self.tr("CSV Data File"), ".csv"), self)
self.saveCSV.triggered.connect(lambda: self._saveData(self.FMT_CSV))
self.saveMenu.addAction(self.saveCSV)
@@ -338,10 +347,10 @@ class GuiWritingStats(QDialog):
if dataFmt == self.FMT_JSON:
fileExt = "json"
textFmt = "JSON Data File"
textFmt = self.tr("JSON Data File")
elif dataFmt == self.FMT_CSV:
fileExt = "csv"
textFmt = "CSV Data File"
textFmt = self.tr("CSV Data File")
else:
return False
@@ -356,7 +365,7 @@ class GuiWritingStats(QDialog):
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.DontUseNativeDialog
savePath, _ = QFileDialog.getSaveFileName(
self, "Save Document As", savePath, options=dlgOpt
self, self.tr("Save Document As"), savePath, options=dlgOpt
)
if not savePath:
return False
@@ -474,7 +483,7 @@ class GuiWritingStats(QDialog):
except Exception as e:
self.theParent.makeAlert(
["Failed to read session log file.", str(e)], nwAlert.ERROR
[self.tr("Failed to read session log file."), str(e)], nwAlert.ERROR
)
return False
+68 -52
View File
@@ -122,8 +122,8 @@ class GuiMain(QMainWindow):
self.projTabs = QTabWidget()
self.projTabs.setTabPosition(QTabWidget.South)
self.projTabs.setStyleSheet(r"QTabWidget::pane {border: 0;};")
self.projTabs.addTab(self.treeView, "Project")
self.projTabs.addTab(self.novelView, "Novel")
self.projTabs.addTab(self.treeView, self.tr("Project"))
self.projTabs.addTab(self.novelView, self.tr("Novel"))
self.projTabs.currentChanged.connect(self._projTabsChanged)
tabFont = self.projTabs.tabBar().font()
@@ -139,17 +139,17 @@ class GuiMain(QMainWindow):
self.treeButtons.setStyleSheet(r"QToolBar {padding: 0;}")
self.projTabs.setCornerWidget(self.treeButtons, Qt.BottomRightCorner)
self.projDetailsBtn = QAction("Project Details")
self.projDetailsBtn = QAction(self.tr("Project Details"))
self.projDetailsBtn.setIcon(self.theTheme.getIcon("status_lines"))
self.projDetailsBtn.triggered.connect(lambda: self.showProjectDetailsDialog())
self.treeButtons.addAction(self.projDetailsBtn)
self.projStatsBtn = QAction("Writing Statistics")
self.projStatsBtn = QAction(self.tr("Writing Statistics"))
self.projStatsBtn.setIcon(self.theTheme.getIcon("status_stats"))
self.projStatsBtn.triggered.connect(lambda: self.showWritingStatsDialog())
self.treeButtons.addAction(self.projStatsBtn)
self.projSettingsBtn = QAction("Project Settings")
self.projSettingsBtn = QAction(self.tr("Project Settings"))
self.projSettingsBtn.setIcon(self.theTheme.getIcon("settings"))
self.projSettingsBtn.triggered.connect(lambda: self.showProjectSettingsDialog())
self.treeButtons.addAction(self.projSettingsBtn)
@@ -180,12 +180,12 @@ class GuiMain(QMainWindow):
self.splitOutline.addWidget(self.projMeta)
self.splitOutline.setSizes(self.mainConf.getOutlinePanePos())
# Main Tabs : Editor / Outline
# Main Tabs : Edirot / Outline
self.mainTabs = QTabWidget()
self.mainTabs.setTabPosition(QTabWidget.East)
self.mainTabs.setStyleSheet(r"QTabWidget::pane {border: 0;}")
self.mainTabs.addTab(self.splitDocs, "Editor")
self.mainTabs.addTab(self.splitOutline, "Outline")
self.mainTabs.addTab(self.splitDocs, self.tr("Editor"))
self.mainTabs.addTab(self.splitOutline, self.tr("Outline"))
self.mainTabs.currentChanged.connect(self._mainTabChanged)
# Splitter : Project Tree / Main Tabs
@@ -339,7 +339,7 @@ class GuiMain(QMainWindow):
if self.hasProject:
if not self.closeProject():
self.makeAlert(
"Cannot create new project when another project is open.",
self.tr("Cannot create new project when another project is open."),
nwAlert.ERROR
)
return False
@@ -357,7 +357,8 @@ class GuiMain(QMainWindow):
if os.path.isfile(os.path.join(projPath, self.theProject.projFile)):
self.makeAlert(
"A project already exists in that location. Please choose another folder.",
self.tr("A project already exists in that location. "
"Please choose another folder."),
nwAlert.ERROR
)
return False
@@ -372,7 +373,7 @@ class GuiMain(QMainWindow):
self.statusBar.setRefTime(self.theProject.projOpened)
self.statusBar.setProjectStatus(True)
self.statusBar.setDocumentStatus(None)
self.statusBar.setStatus("New project created ...")
self.statusBar.setStatus(self.tr("New project created ..."))
self._updateWindowTitle(self.theProject.projName)
else:
self.theProject.clearProject()
@@ -391,8 +392,9 @@ class GuiMain(QMainWindow):
if not isYes:
msgYes = self.askQuestion(
"Close Project",
"Close the current project?<br>Changes are saved automatically."
self.tr("Close Project"),
"%s<br>%s" % (self.tr("Close the current project?"),
self.tr("Changes are saved automatically."))
)
if not msgYes:
return False
@@ -407,7 +409,8 @@ class GuiMain(QMainWindow):
doBackup = True
if self.mainConf.askBeforeBackup:
msgYes = self.askQuestion(
"Backup Project", "Backup the current project?"
self.tr("Backup Project"),
self.tr("Backup the current project?")
)
if not msgYes:
doBackup = False
@@ -457,13 +460,14 @@ class GuiMain(QMainWindow):
try:
lockDetails = (
"<br><br>The project was locked by the computer "
"'%s' (%s %s), last active on %s"
) % (
self.theProject.lockedBy[0],
self.theProject.lockedBy[1],
self.theProject.lockedBy[2],
datetime.fromtimestamp(
"<br>%s" % self.tr("The project was locked by the computer "
"'{computer_name}' ({os_name} {os_version}), "
"last active on {time}")
).format(
computer_name = self.theProject.lockedBy[0],
os_name = self.theProject.lockedBy[1],
os_version = self.theProject.lockedBy[2],
time = datetime.fromtimestamp(
int(self.theProject.lockedBy[3])
).strftime("%x %X")
)
@@ -472,14 +476,16 @@ class GuiMain(QMainWindow):
msgBox = QMessageBox()
msgRes = msgBox.warning(
self, "Project Locked", (
"The project is already open by another instance of novelWriter, and "
"is therefore locked. Override lock and continue anyway?<br><br>"
"Note: If the program or the computer previously crashed, the lock "
"can safely be overridden. If, however, another instance of "
"novelWriter has the project open, overriding the lock may corrupt "
"the project, and is not recommended.%s"
) % lockDetails,
self, self.tr("Project Locked"),
"%s<br><br>%s<br>%s" % (
self.tr("The project is already open by another instance of novelWriter, and "
"is therefore locked. Override lock and continue anyway?"),
self.tr("Note: If the program or the computer previously crashed, the lock "
"can safely be overridden. If, however, another instance of "
"novelWriter has the project open, overriding the lock may corrupt "
"the project, and is not recommended."),
lockDetails
),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
)
if msgRes == QMessageBox.Yes:
@@ -685,15 +691,16 @@ class GuiMain(QMainWindow):
lastPath = self.mainConf.lastPath
extFilter = [
"Text files (*.txt)",
"Markdown files (*.md)",
"novelWriter files (*.nwd)",
"All files (*.*)",
self.tr("{0} ({1})").format(self.tr("Text files"), "*.txt"),
self.tr("{0} ({1})").format(self.tr("Markdown files")),
self.tr("{0} ({1})").format(self.tr("novelWriter files"), "*.nwd"),
self.tr("{0} ({1})").format(self.tr("All files")),
]
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.DontUseNativeDialog
loadFile, _ = QFileDialog.getOpenFileName(
self, "Import File", lastPath, options=dlgOpt, filter=";;".join(extFilter)
self, self.tr("Import File"), lastPath,
options=dlgOpt, filter=";;".join(extFilter)
)
if not loadFile:
return False
@@ -708,22 +715,25 @@ class GuiMain(QMainWindow):
self.mainConf.setLastPath(loadFile)
except Exception as e:
self.makeAlert(
["Could not read file. The file must be an existing text file.", str(e)],
[
self.tr("Could not read file. The file must be an existing text file."),
str(e)
],
nwAlert.ERROR
)
return False
if self.docEditor.theHandle is None:
self.makeAlert(
"Please open a document to import the text file into.",
self.tr("Please open a document to import the text file into."),
nwAlert.ERROR
)
return False
if not self.docEditor.isEmpty():
msgYes = self.askQuestion("Import Document", (
"Importing the file will overwrite the current content of the document. "
"Do you want to proceed?"
msgYes = self.askQuestion(self.tr("Import Document"), (
self.tr("Importing the file will overwrite the current content of the document. "
"Do you want to proceed?")
))
if not msgYes:
return False
@@ -861,9 +871,11 @@ class GuiMain(QMainWindow):
for nDone, tItem in enumerate(self.theProject.projTree):
if tItem is not None:
self.setStatus("Indexing: '%s'" % tItem.itemName)
self.setStatus(self.tr("{0}: '{1}'").format(self.tr("Indexing"), tItem.itemName))
else:
self.setStatus("Indexing: Unknown item")
self.setStatus(self.tr("{0}: {1}").format(
self.tr("Indexing"),
self.tr("Unknown item")))
if tItem is not None and tItem.itemType == nwItemType.FILE:
logger.verbose("Scanning: %s" % tItem.itemName)
@@ -881,12 +893,14 @@ class GuiMain(QMainWindow):
self.treeView.projectWordCount()
tEnd = time()
self.setStatus("Indexing completed in %.1f ms" % ((tEnd - tStart)*1000.0))
self.setStatus(self.tr("Indexing completed in {0} ms").
format(f"{(tEnd - tStart)*1000.0:.1f}"))
self.docEditor.updateTagHighLighting()
qApp.restoreOverrideCursor()
if not beQuiet:
self.makeAlert("The project index has been successfully rebuilt.", nwAlert.INFO)
self.makeAlert(self.tr("The project index has been successfully rebuilt."),
nwAlert.INFO)
return True
@@ -914,7 +928,7 @@ class GuiMain(QMainWindow):
dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
projPath = QFileDialog.getExistingDirectory(
self, "Save novelWriter Project", "", options=dlgOpt
self, self.tr("Save novelWriter Project"), "", options=dlgOpt
)
if projPath:
return projPath
@@ -1100,14 +1114,14 @@ class GuiMain(QMainWindow):
# Popup
msgBox = QMessageBox()
if theLevel == nwAlert.INFO:
msgBox.information(self, "Information", popMsg)
msgBox.information(self, self.tr("Information"), popMsg)
elif theLevel == nwAlert.WARN:
msgBox.warning(self, "Warning", popMsg)
msgBox.warning(self, self.tr("Warning"), popMsg)
elif theLevel == nwAlert.ERROR:
msgBox.critical(self, "Error", popMsg)
msgBox.critical(self, self.tr("Error"), popMsg)
elif theLevel == nwAlert.BUG:
popMsg += "<br>This is a bug!"
msgBox.critical(self, "Internal Error", popMsg)
popMsg += "<br>%s" % self.tr("This is a bug!")
msgBox.critical(self, self.tr("Internal Error"), popMsg)
return
@@ -1115,7 +1129,8 @@ class GuiMain(QMainWindow):
"""Ask the user a Yes/No question.
"""
msgBox = QMessageBox()
msgRes = msgBox.question(self, theTitle, theQuestion)
print(msgBox.standardButtons())
msgRes = msgBox.question(self, theTitle, theQuestion, QMessageBox.Yes | QMessageBox.No)
return msgRes == QMessageBox.Yes
def reportConfErr(self):
@@ -1137,8 +1152,9 @@ class GuiMain(QMainWindow):
"""
if self.hasProject:
msgYes = self.askQuestion(
"Exit",
"Do you want to exit novelWriter?<br>Changes are saved automatically."
self.tr("Exit"),
"%s<br>%s" % (self.tr("Do you want to exit novelWriter?"),
self.tr("Changes are saved automatically."))
)
if not msgYes:
return False
Binary file not shown.
File diff suppressed because it is too large Load Diff
+447
View File
@@ -0,0 +1,447 @@
<!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>
+22
View File
@@ -186,6 +186,20 @@ def buildQtDocs():
return
def buildQtI18n():
try:
subprocess.call(["lrelease", "-verbose", "novelWriter.pro"])
except Exception as e:
print("QtI18n Release Error:")
print(str(e))
def buildQtI18nTS():
try:
subprocess.call(["pylupdate5", "-verbose", "-noobsolete", "novelWriter.pro"])
except Exception as e:
print("QtI18n Release Error:")
print(str(e))
##
# Sample Project ZIP File Builder (sample)
##
@@ -898,6 +912,14 @@ if __name__ == "__main__":
sys.argv.remove("qthelp")
buildQtDocs()
if "qtlrelease" in sys.argv:
sys.argv.remove("qtlrelease")
buildQtI18n()
if "qtlupdate" in sys.argv:
sys.argv.remove("qtlupdate")
buildQtI18nTS()
if "sample" in sys.argv:
sys.argv.remove("sample")
buildSampleZip()