diff --git a/advanced.py b/advanced.py
index 11192bd..6e98770 100644
--- a/advanced.py
+++ b/advanced.py
@@ -21,13 +21,13 @@
Qt, QObject, QDialog, QGroupBox, QWidget, QVBoxLayout, QHBoxLayout,
QPlainTextEdit, QPushButton, QSplitter, QLabel, QThread, QLineEdit,
QGridLayout, QProgressBar, pyqtSignal, pyqtSlot, QPixmap, QEvent,
- QStackedWidget, QSpacerItem, QTextCursor, QTabWidget)
+ QStackedWidget, QSpacerItem, QTextCursor, QTabWidget, QCheckBox)
except ImportError:
from PyQt5.Qt import (
Qt, QObject, QDialog, QGroupBox, QWidget, QVBoxLayout, QHBoxLayout,
QPlainTextEdit, QPushButton, QSplitter, QLabel, QThread, QLineEdit,
QGridLayout, QProgressBar, pyqtSignal, pyqtSlot, QPixmap, QEvent,
- QStackedWidget, QSpacerItem, QTextCursor, QTabWidget)
+ QStackedWidget, QSpacerItem, QTextCursor, QTabWidget, QCheckBox)
load_translations()
@@ -236,6 +236,7 @@ def show_advanced(self):
class AdvancedTranslation(QDialog):
paragraph_sig = pyqtSignal(Paragraph)
+ ebook_title = pyqtSignal()
progress_bar = pyqtSignal()
preparation_thread = QThread()
@@ -526,60 +527,81 @@ def layout_control(self):
layout = QHBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
+ cache_group = QGroupBox(_('Cache Status'))
+ cache_layout = QVBoxLayout(cache_group)
+ cache_status = QLabel(
+ _('Enabled') if self.cache.is_persistence() else _('Disabled'))
+ cache_status.setAlignment(Qt.AlignCenter)
+ cache_status.setStyleSheet(
+ 'border-radius:2px;color:white;background-color:%s;'
+ % ('green' if self.cache.is_persistence() else 'grey'))
+ cache_layout.addWidget(cache_status)
+
engine_group = QGroupBox(_('Translation Engine'))
engine_layout = QVBoxLayout(engine_group)
engine_list = EngineList(self.current_engine.name)
- engine_list.setFixedWidth(150)
+ engine_list.setMaximumWidth(150)
engine_layout.addWidget(engine_list)
source_group = QGroupBox(_('Source Language'))
source_layout = QVBoxLayout(source_group)
source_lang = SourceLang()
- source_lang.setFixedWidth(150)
+ source_lang.setMaximumWidth(150)
source_layout.addWidget(source_lang)
target_group = QGroupBox(_('Target Language'))
target_layout = QVBoxLayout(target_group)
target_lang = TargetLang()
- target_lang.setFixedWidth(150)
+ target_lang.setMaximumWidth(150)
target_layout.addWidget(target_lang)
- cache_group = QGroupBox(_('Cache Status'))
- cache_layout = QVBoxLayout(cache_group)
- cache_status = QLabel(
- _('Enabled') if self.cache.is_persistence() else _('Disabled'))
- cache_status.setAlignment(Qt.AlignCenter)
- cache_status.setStyleSheet(
- 'border-radius:2px;color:white;background-color:%s;'
- % ('green' if self.cache.is_persistence() else 'grey'))
- cache_layout.addWidget(cache_status)
+ title_group = QGroupBox(_('Custom Ebook Title'))
+ title_layout = QHBoxLayout(title_group)
+ custom_title = QCheckBox()
+ ebook_title = QLineEdit()
+ ebook_title.setText(self.ebook.title)
+ ebook_title.setToolTip(
+ _('By default, title metadata will be translated.'))
+ ebook_title.setDisabled(True)
+ # ebook_title.setCursorPosition(0)
+ title_layout.addWidget(custom_title)
+ title_layout.addWidget(ebook_title)
+
+ def enable_custom_title(checked):
+ ebook_title.setDisabled(not checked)
+ self.ebook.set_custom_title(
+ ebook_title.text() if checked else None)
+ if checked:
+ ebook_title.setFocus(Qt.MouseFocusReason)
+ custom_title.stateChanged.connect(enable_custom_title)
+
+ def change_ebook_title():
+ if ebook_title.text() == '':
+ ebook_title.undo()
+ self.ebook.set_custom_title(ebook_title.text())
+ ebook_title.editingFinished.connect(change_ebook_title)
+
+ # if self.config.get('to_library'):
+ # ebook_title.setDisabled(True)
+ # ebook_title.setToolTip(_(
+ # "The ebook's filename is automatically managed by Calibre "
+ # 'according to metadata since the output path is set to '
+ # 'Calibre Library.'))
+ # ebook_title.textChanged.connect(self.ebook.set_custom_title)
save_group = QGroupBox(_('Output Ebook'))
save_layout = QHBoxLayout(save_group)
save_ebook = QPushButton(_('Output'))
- ebook_title = QLineEdit()
- ebook_title.setText(self.ebook.title)
- ebook_title.setCursorPosition(0)
output_format = OutputFormat()
- output_format.setFixedWidth(150)
- save_layout.addWidget(QLabel(_('Filename')))
- save_layout.addWidget(ebook_title, 1)
- save_layout.addWidget(QLabel(_('Format')))
+ # save_layout.addWidget(QLabel(_('Format')))
save_layout.addWidget(output_format)
save_layout.addWidget(save_ebook)
- if self.config.get('to_library'):
- ebook_title.setDisabled(True)
- ebook_title.setToolTip(_(
- "The ebook's filename is automatically managed by Calibre "
- 'according to metadata since the output path is set to '
- 'Calibre Library.'))
- ebook_title.textChanged.connect(self.ebook.set_title)
-
layout.addWidget(cache_group)
layout.addWidget(engine_group)
layout.addWidget(source_group)
layout.addWidget(target_group)
+ layout.addWidget(title_group, 1)
layout.addWidget(save_group)
source_lang.currentTextChanged.connect(
diff --git a/batch.py b/batch.py
index e9eb557..4f2ccb3 100644
--- a/batch.py
+++ b/batch.py
@@ -11,11 +11,11 @@
try:
from qt.core import (
QDialog, QWidget, QPushButton, QHeaderView, QVBoxLayout, QTableWidget,
- QTableWidgetItem)
+ QTableWidgetItem, Qt)
except ImportError:
from PyQt5.Qt import (
QDialog, QWidget, QPushButton, QHeaderView, QVBoxLayout, QTableWidget,
- QTableWidgetItem)
+ QTableWidgetItem, Qt)
load_translations()
@@ -63,6 +63,7 @@ def layout_translate(self):
for row, ebook in enumerate(self.ebooks):
ebook_title = QTableWidgetItem(ebook.title)
+ ebook_title.setFlags(Qt.ItemIsEnabled)
ebook_title.setSizeHint(table.sizeHint())
table.setItem(row, 0, ebook_title)
diff --git a/lib/config.py b/lib/config.py
index 7fa938f..f3b5002 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -17,6 +17,11 @@
'cache_path': None,
'log_translation': True,
'translation_position': None,
+ 'column_gap': {
+ '_type': 'percentage',
+ 'percentage': 10,
+ 'space_count': 6,
+ },
'original_color': None,
'translation_color': None,
'rule_mode': 'normal',
diff --git a/lib/conversion.py b/lib/conversion.py
index b7bcc82..8ab3e45 100644
--- a/lib/conversion.py
+++ b/lib/conversion.py
@@ -237,29 +237,39 @@ def translate_done(self, job):
if not ebook.is_extra_format() and ebook_metadata:
with open(output_path, 'r+b') as file:
metadata = get_metadata(file, ebook.output_format)
- if ebook_metadata.get('language'):
+ ebook_title = metadata.title
+ if ebook.custom_title is not None:
+ ebook_title = ebook.custom_title
+ if ebook_metadata.get('lang_mark'):
+ ebook_title = '%s [%s]' % (ebook_title, ebook.target_lang)
+ metadata.title = ebook_title
+ if ebook_metadata.get('lang_code'):
metadata.language = ebook.lang_code
subjects = ebook_metadata.get('subjects')
- metadata.tags += subjects + [
- 'Translate by Ebook Translator: '
+ metadata.tags += (subjects or []) + [
+ 'Translated by Ebook Translator: '
'https://translator.bookfere.com']
- # metadata.title = 'Custom Title'
# metadata.authors = ['bookfere.com']
# metadata.author_sort = 'bookfere.com'
# metadata.book_producer = 'Ebook Translator'
set_metadata(file, metadata, ebook.output_format)
if self.config.get('to_library'):
- with open(output_path, 'rb') as file:
- metadata = get_metadata(file, ebook.output_format)
- if ebook.is_extra_format():
- metadata.title = ebook.title
+ # with open(output_path, 'rb') as file:
+ # metadata = get_metadata(file, ebook.output_format)
+ # if ebook.is_extra_format():
+ # metadata.title = ebook.title
book_id = self.db.create_book_entry(metadata)
self.api.add_format(
book_id, ebook.output_format, output_path, run_hooks=False)
self.gui.library_view.model().books_added(1)
output_path = self.api.format_abspath(book_id, ebook.output_format)
# os.remove(temp_file)
+ else:
+ dirname = os.path.dirname(output_path)
+ filename = '%s.%s' % (metadata.title, ebook.output_format)
+ new_output_path = os.path.join(dirname, filename)
+ os.rename(output_path, new_output_path)
self.gui.status_bar.show_message(
job.description + ' ' + _('completed'), 5000)
diff --git a/lib/ebook.py b/lib/ebook.py
index 65a4dfe..faff14e 100644
--- a/lib/ebook.py
+++ b/lib/ebook.py
@@ -17,10 +17,12 @@ def __init__(self, id, title, files, input_format, source_lang,
self.target_lang = None
self.lang_code = None
- self.set_title(title)
+ self.title = title
+ self.custom_title = None
- def set_title(self, title):
- self.title = sanitize_file_name(title)
+ def set_custom_title(self, title):
+ self.custom_title = None if title is None else \
+ sanitize_file_name(title)
# self.title = re.sub(r'^\.+|[\/\\\\<>:"|?*\n\t]', '', title)
def set_input_format(self, format):
diff --git a/lib/element.py b/lib/element.py
index 3b59df1..789bdab 100644
--- a/lib/element.py
+++ b/lib/element.py
@@ -29,6 +29,7 @@ def __init__(self, element, page_id=None):
self.placeholder = None
self.reserve_elements = []
self.original = []
+ self.column_gap = None
def _element_copy(self):
return copy.deepcopy(self.element)
@@ -39,6 +40,9 @@ def set_ignored(self, ignored):
def set_placeholder(self, placeholder):
self.placeholder = placeholder
+ def set_column_gap(self, values):
+ self.column_gap = values
+
def get_name(self):
return None
@@ -281,11 +285,22 @@ def _create_table(self, position, original, translation=None):
table = etree.XML(
'
'.format(ns['x']))
tr = etree.SubElement(table, 'tr')
- td_left = etree.SubElement(
- tr, 'td', attrib={'width': '45%', 'valign': 'top'})
- etree.SubElement(tr, 'td', attrib={'width': '10%'})
- td_right = etree.SubElement(
- tr, 'td', attrib={'width': '45%', 'valign': 'top'})
+ td_left = etree.SubElement(tr, 'td', attrib={'valign': 'top'})
+ td_middle = etree.SubElement(tr, 'td')
+ td_right = etree.SubElement(tr, 'td', attrib={'valign': 'top'})
+ if self.column_gap is None:
+ td_left.set('width', '45%')
+ td_middle.set('width', '10%')
+ td_right.set('width', '45%')
+ else:
+ unit, value = self.column_gap
+ if unit == 'percentage':
+ width = '%s%%' % round((100 - value) / 2)
+ td_left.set('width', width)
+ td_middle.set('width', '%s%%' % value)
+ td_right.set('width', width)
+ else:
+ td_middle.text = '\xa0' * value
if position == 'left':
if translation is not None:
td_left.append(translation)
@@ -414,6 +429,7 @@ def __init__(self, placeholder, separator, position, merge_length=0):
self.translation_lang = None
self.original_color = None
self.translation_color = None
+ self.column_gap = None
self.elements = {}
self.originals = []
@@ -432,6 +448,9 @@ def set_original_color(self, color):
def set_translation_color(self, color):
self.translation_color = color
+ def set_column_gap(self, values):
+ self.column_gap = values
+
def remove_unused_elements(self):
if self.position == 'only':
for element in self.elements.values():
@@ -441,6 +460,8 @@ def prepare_original(self, elements):
count = 0
for oid, element in enumerate(elements):
element.set_placeholder(self.placeholder)
+ if self.column_gap is not None:
+ element.set_column_gap(self.column_gap)
raw = element.get_raw()
content = element.get_content()
md5 = uid('%s%s' % (oid, content))
@@ -485,6 +506,8 @@ def prepare_original(self, elements):
if element.ignored:
continue
element.set_placeholder(self.placeholder)
+ if self.column_gap is not None:
+ element.set_column_gap(self.column_gap)
self.elements[count] = element
code = element.get_raw()
content = element.get_content()
@@ -549,7 +572,6 @@ def add_translations(self, paragraphs):
for eid, element in self.elements.copy().items():
if element.ignored:
continue
- element.set_placeholder(self.placeholder)
original = element.get_content()
translation = translations.get(original)
if translation is None:
@@ -632,6 +654,10 @@ def get_element_handler(placeholder, separator):
if config.get('merge_enabled'):
handler = ElementHandlerMerge(
placeholder, separator, position, config.get('merge_length'))
+ column_gap = config.get('column_gap')
+ gap_type = column_gap.get('_type')
+ if gap_type is not None and gap_type in column_gap.keys():
+ handler.set_column_gap((gap_type, column_gap.get(gap_type)))
handler.set_original_color(config.get('original_color'))
handler.set_translation_color(config.get('translation_color'))
return handler
diff --git a/setting.py b/setting.py
index cfbf026..5bf0a26 100644
--- a/setting.py
+++ b/setting.py
@@ -78,6 +78,7 @@ def save_setting(index):
layout.addWidget(self.tabs)
layout.addWidget(layout_info())
+ @staticmethod
def layout_scroll_area(func):
def scroll_widget(self):
widget = QWidget()
@@ -381,17 +382,23 @@ def layout_engine(self):
request_timeout = QDoubleSpinBox()
request_timeout.setRange(0, 9999)
request_timeout.setDecimals(1)
- max_error_count = QSpinBox()
- max_error_count.setRange(0, 9999)
request_layout = QFormLayout(request_group)
request_layout.addRow(_('Concurrency limit'), concurrency_limit)
request_layout.addRow(_('Interval (seconds)'), request_interval)
request_layout.addRow(_('Attempt times'), request_attempt)
request_layout.addRow(_('Timeout (seconds)'), request_timeout)
- request_layout.addRow(
- _('Error limit to stop translation'), max_error_count)
layout.addWidget(request_group, 1)
+ # Abort Translation
+ abort_translation_group = QGroupBox(_('Abort Translation'))
+ abort_translation_layout = QHBoxLayout(abort_translation_group)
+ max_error_count = QSpinBox()
+ max_error_count.setRange(1, 9999)
+ abort_translation_layout.addWidget(max_error_count)
+ abort_translation_layout.addWidget(QLabel(
+ _('The number of consecutive errors to abort translation.')), 1)
+ layout.addWidget(abort_translation_group, 1)
+
self.set_form_layout_policy(request_layout)
self.disable_wheel_event(concurrency_limit)
self.disable_wheel_event(request_attempt)
@@ -730,13 +737,61 @@ def layout_content(self):
'border:1px solid rgba(127,127,127,.3);'
'background-color:rgba(127,127,127,.1);padding:10px;'
'color:black;font-size:28px;')
-
position_samples_layout.addWidget(original_sample, 1)
position_samples_layout.addWidget(translation_sample, 1)
+ position_setup = QWidget()
+ position_setup.setVisible(False)
+ position_setup_layout = QHBoxLayout(position_setup)
+ position_setup_layout.setContentsMargins(0, 0, 0, 0)
+ column_gap_type = QComboBox()
+ column_gap_value = QSpinBox()
+ column_gap_value.setRange(1, 100)
+ position_setup_layout.addWidget(QLabel(_('Column Gap')))
+ position_setup_layout.addWidget(column_gap_type)
+ position_setup_layout.addWidget(column_gap_value)
+ percentage_unit = QLabel('%')
+ position_setup_layout.addWidget(percentage_unit)
+ position_setup_layout.addStretch(1)
+
+ self.disable_wheel_event(column_gap_type)
+ self.disable_wheel_event(column_gap_value)
+
+ column_gap_type.addItem('Percentage', 'percentage')
+ column_gap_type.addItem('Space count', 'space_count')
+
+ column_gap_config = self.config.get('column_gap').copy()
+
+ current_type = column_gap_config.get('_type')
+ current_index = column_gap_type.findData(current_type)
+ percentage_unit.setVisible(current_type == 'percentage')
+ column_gap_type.setCurrentIndex(current_index)
+ column_gap_value.setValue(column_gap_config.get(current_type))
+
+ def change_column_gap_value(value):
+ gap_type = column_gap_type.currentData()
+ column_gap_config.update({gap_type: value})
+ self.config.update(column_gap=column_gap_config)
+ column_gap_value.valueChanged.connect(change_column_gap_value)
+
+ def change_column_gap_type(index):
+ gap_type = column_gap_type.itemData(index)
+ percentage_unit.setVisible(gap_type == 'percentage')
+ column_gap_value.setValue(column_gap_config.get(gap_type))
+ column_gap_config.update(_type=gap_type)
+ self.config.update(column_gap=column_gap_config)
+ column_gap_type.currentIndexChanged.connect(change_column_gap_type)
+
+ position_preview = QWidget()
+ position_preview_layout = QVBoxLayout(position_preview)
+ position_preview_layout.setSpacing(10)
+ position_preview_layout.setContentsMargins(0, 0, 0, 0)
+ position_preview_layout.addWidget(position_samples, 1)
+ position_preview_layout.addWidget(position_setup)
+
position_group = QGroupBox(_('Translation Position'))
position_layout = QHBoxLayout(position_group)
- position_layout.addWidget(position_samples, 1)
+ position_layout.addWidget(position_preview, 1)
position_layout.addSpacing(10)
position_layout.addWidget(position_radios)
@@ -775,6 +830,7 @@ def choose_option(btn_id):
original_sample.setVisible(btn_id != 4)
position_samples.layout().setDirection(
directions[btn_id] if btn_id != 4 else directions[0])
+ position_setup.setVisible(btn_id in [2, 3])
self.config.update(translation_position=position_map.get(btn_id))
choose_option(position_btn_group.checkedId())
position_btn_click.connect(choose_option)
@@ -789,7 +845,8 @@ def choose_option(btn_id):
original_color_layout = QHBoxLayout(original_color_group)
self.original_color = QLineEdit()
self.original_color.setText(self.config.get('original_color'))
- self.original_color.setPlaceholderText('#0055ff')
+ self.original_color.setPlaceholderText(
+ '%s %s' % (_('e.g.,'), '#0055ff'))
original_color_show = QLabel()
original_color_show.setObjectName('original_color_show')
original_color_show.setFixedWidth(25)
@@ -806,7 +863,8 @@ def choose_option(btn_id):
translation_color_group = QGroupBox(_('Translation Text Color'))
translation_color_layout = QHBoxLayout(translation_color_group)
self.translation_color = QLineEdit()
- self.translation_color.setPlaceholderText('#0055ff')
+ self.translation_color.setPlaceholderText(
+ '%s %s' % (_('e.g.,'), '#0055ff'))
self.translation_color.setText(self.config.get('translation_color'))
translation_color_show = QLabel()
translation_color_show.setObjectName('translation_color')
@@ -965,7 +1023,7 @@ def choose_filter_mode(btn_id):
element_layout = QVBoxLayout(element_group)
self.element_rules = QPlainTextEdit()
self.element_rules.setPlaceholderText(
- '%s %s' % (_('e.g.'), 'table, table#report, table.list'))
+ '%s %s' % (_('e.g.,'), 'table, table#report, table.list'))
self.element_rules.setMinimumHeight(100)
self.element_rules.insertPlainText(
'\n'.join(self.config.get('element_rules')))
@@ -979,16 +1037,24 @@ def choose_filter_mode(btn_id):
metadata_group = QGroupBox(_('Ebook Metadata'))
metadata_layout = QFormLayout(metadata_group)
self.set_form_layout_policy(metadata_layout)
- self.metadata_lang = QCheckBox(_('Set "Target Language" to metadata'))
+ self.metadata_lang_mark = QCheckBox(
+ _('Append target language to title metadata'))
+ self.metadata_lang_code = QCheckBox(
+ _('Set target language code to language metadata'))
self.metadata_subject = QPlainTextEdit()
self.metadata_subject.setPlaceholderText(
_('Subjects of ebook (one subject per line)'))
- metadata_layout.addRow(_('Language'), self.metadata_lang)
+ metadata_layout.addRow(_('Language Mark'), self.metadata_lang_mark)
+ metadata_layout.addRow(_('Language Code'), self.metadata_lang_code)
metadata_layout.addRow(_('Subject'), self.metadata_subject)
layout.addWidget(metadata_group)
- self.metadata_lang.setChecked(
- self.config.get('ebook_metadata.language', False))
+ self.metadata_lang_mark.setChecked(
+ self.config.get('ebook_metadata.lang_mark', False))
+ self.metadata_lang_code.setChecked(
+ self.config.get(
+ 'ebook_metadata.lang_code',
+ self.config.get('ebook_metadata.language', False))) # old key
self.metadata_subject.setPlainText(
'\n'.join(self.config.get('ebook_metadata.subjects', [])))
@@ -1170,19 +1236,14 @@ def update_content_config(self):
# Ebook metadata
ebook_metadata = self.config.get('ebook_metadata').copy()
- self.config.delete('ebook_metadata')
- if self.metadata_lang.isChecked():
- ebook_metadata.update(language=True)
- elif 'language' in ebook_metadata:
- del ebook_metadata['language']
+ ebook_metadata.clear()
+ ebook_metadata.update(lang_mark=self.metadata_lang_mark.isChecked())
+ ebook_metadata.update(lang_code=self.metadata_lang_code.isChecked())
subject_content = self.metadata_subject.toPlainText().strip()
if subject_content:
subjects = [s.strip() for s in subject_content.split('\n')]
ebook_metadata.update(subjects=subjects)
- elif 'subjects' in ebook_metadata:
- del ebook_metadata['subjects']
- if ebook_metadata:
- self.config.update(ebook_metadata=ebook_metadata)
+ self.config.update(ebook_metadata=ebook_metadata)
return True
def is_valid_regex(self, rule):
diff --git a/tests/test_config.py b/tests/test_config.py
index d96800e..50271d1 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -22,6 +22,11 @@ def test_default(self):
'cache_path': None,
'log_translation': True,
'translation_position': None,
+ 'column_gap': {
+ '_type': 'percentage',
+ 'percentage': 10,
+ 'space_count': 6,
+ },
'original_color': None,
'translation_color': None,
'rule_mode': 'normal',
diff --git a/translations/es.po b/translations/es.po
index c5e0fcd..717c54c 100644
--- a/translations/es.po
+++ b/translations/es.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: 2023-04-17 14:17+0800\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -88,12 +88,6 @@ msgstr ""
msgid "Stopping..."
msgstr ""
-msgid "Translation Engine"
-msgstr "Motor de traducción"
-
-msgid "Source Language"
-msgstr "Lenguaje original"
-
msgid "Cache Status"
msgstr ""
@@ -103,21 +97,22 @@ msgstr ""
msgid "Enabled"
msgstr ""
-msgid "Output Ebook"
-msgstr ""
+msgid "Translation Engine"
+msgstr "Motor de traducción"
-msgid "Output"
+msgid "Source Language"
+msgstr "Lenguaje original"
+
+msgid "Custom Ebook Title"
msgstr ""
-msgid "Filename"
+msgid "By default, title metadata will be translated."
msgstr ""
-msgid "Format"
+msgid "Output Ebook"
msgstr ""
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
+msgid "Output"
msgstr ""
msgid "Translated"
@@ -217,6 +212,9 @@ msgstr ""
msgid "Merge Length"
msgstr ""
+msgid "Filename"
+msgstr ""
+
msgid "Size (MB)"
msgstr ""
@@ -559,7 +557,10 @@ msgstr ""
msgid "Timeout (seconds)"
msgstr ""
-msgid "Error limit to stop translation"
+msgid "Abort Translation"
+msgstr ""
+
+msgid "The number of consecutive errors to abort translation."
msgstr ""
msgid "Tune Gemini"
@@ -607,12 +608,18 @@ msgstr "Agregar sin original"
msgid "Translation"
msgstr ""
+msgid "Column Gap"
+msgstr ""
+
msgid "Translation Position"
msgstr "Posición de la traducción"
msgid "Original Text Color"
msgstr ""
+msgid "e.g.,"
+msgstr ""
+
msgid "Translation Text Color"
msgstr "Color de la traducción"
@@ -660,21 +667,27 @@ msgstr "Excluir párrafo por patrón de expresión regular. Un patrón por líne
msgid "Ignore Element"
msgstr ""
-msgid "e.g."
-msgstr ""
-
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr ""
msgid "Ebook Metadata"
msgstr ""
-msgid "Set \"Target Language\" to metadata"
+msgid "Append target language to title metadata"
+msgstr ""
+
+msgid "Set target language code to language metadata"
msgstr ""
msgid "Subjects of ebook (one subject per line)"
msgstr ""
+msgid "Language Mark"
+msgstr ""
+
+msgid "Language Code"
+msgstr ""
+
msgid "Subject"
msgstr ""
diff --git a/translations/fr.mo b/translations/fr.mo
index d3f0a9a..d095237 100644
Binary files a/translations/fr.mo and b/translations/fr.mo differ
diff --git a/translations/fr.po b/translations/fr.po
index de920b6..cd97dcd 100644
--- a/translations/fr.po
+++ b/translations/fr.po
@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: 2023-10-01 15:35-0400\n"
"Last-Translator: PoP\n"
@@ -88,12 +88,6 @@ msgstr "Arrêt"
msgid "Stopping..."
msgstr "Arrêtant..."
-msgid "Translation Engine"
-msgstr "Moteur de traduction"
-
-msgid "Source Language"
-msgstr "Langage d'origine"
-
msgid "Cache Status"
msgstr "Statut du cache"
@@ -103,23 +97,24 @@ msgstr "Désactivé"
msgid "Enabled"
msgstr "Activé"
-msgid "Output Ebook"
-msgstr "Produit ebook"
-
-msgid "Output"
-msgstr "Produit"
+msgid "Translation Engine"
+msgstr "Moteur de traduction"
-msgid "Filename"
-msgstr "Nom du fichier"
+msgid "Source Language"
+msgstr "Langage d'origine"
-msgid "Format"
+msgid "Custom Ebook Title"
msgstr ""
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
+msgid "By default, title metadata will be translated."
msgstr ""
+msgid "Output Ebook"
+msgstr "Produit ebook"
+
+msgid "Output"
+msgstr "Produit"
+
msgid "Translated"
msgstr "Traduit"
@@ -221,6 +216,9 @@ msgstr "Langue"
msgid "Merge Length"
msgstr "Longueur de fusion"
+msgid "Filename"
+msgstr "Nom du fichier"
+
msgid "Size (MB)"
msgstr "Taille (MB)"
@@ -569,8 +567,11 @@ msgstr "Nombre d'essais"
msgid "Timeout (seconds)"
msgstr "Échéance (secondes)"
-msgid "Error limit to stop translation"
-msgstr "Nombre d'erreurs avant d'arrêter la traduction"
+msgid "Abort Translation"
+msgstr ""
+
+msgid "The number of consecutive errors to abort translation."
+msgstr ""
msgid "Tune Gemini"
msgstr ""
@@ -617,12 +618,18 @@ msgstr "Ajouter sans l'original"
msgid "Translation"
msgstr ""
+msgid "Column Gap"
+msgstr ""
+
msgid "Translation Position"
msgstr "Position de traduction"
msgid "Original Text Color"
msgstr ""
+msgid "e.g.,"
+msgstr "e.g.,"
+
msgid "Translation Text Color"
msgstr "Couleur de la traduction"
@@ -671,21 +678,27 @@ msgstr ""
msgid "Ignore Element"
msgstr "Ignorer l'élément"
-msgid "e.g."
-msgstr "e.g."
-
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr "Sélecteurs CSS pour exclure des éléments. Une règle par ligne:"
msgid "Ebook Metadata"
msgstr "Metadata du ebook"
-msgid "Set \"Target Language\" to metadata"
-msgstr "Sélectionnez la \"Langue cible\" pour le metadata"
+msgid "Append target language to title metadata"
+msgstr ""
+
+msgid "Set target language code to language metadata"
+msgstr "Sélectionnez la langue cible pour le metadata"
msgid "Subjects of ebook (one subject per line)"
msgstr "Sujets du ebook (un sujet par ligne)"
+msgid "Language Mark"
+msgstr ""
+
+msgid "Language Code"
+msgstr ""
+
msgid "Subject"
msgstr "Sujet"
diff --git a/translations/message.pot b/translations/message.pot
index 3c15b0c..5e28f8f 100644
--- a/translations/message.pot
+++ b/translations/message.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -43,157 +43,151 @@ msgstr ""
msgid "Start"
msgstr ""
-#: advanced.py:199 batch.py:54 setting.py:184
+#: advanced.py:199 batch.py:54 setting.py:185
msgid "Input Format"
msgstr ""
-#: advanced.py:210 advanced.py:541 batch.py:55 setting.py:367
+#: advanced.py:210 advanced.py:552 batch.py:55 setting.py:368
msgid "Target Language"
msgstr ""
-#: advanced.py:302
+#: advanced.py:303
msgid "Failed to translate {} paragraph(s), Would you like to retry?"
msgstr ""
-#: advanced.py:308 lib/translation.py:258
+#: advanced.py:309 lib/translation.py:258
msgid "Translation completed."
msgstr ""
-#: advanced.py:323
+#: advanced.py:324
msgid "There is no content that needs to be translated."
msgstr ""
-#: advanced.py:360
+#: advanced.py:361
msgid "Loading ebook data, please wait..."
msgstr ""
-#: advanced.py:383
+#: advanced.py:384
msgid "Review"
msgstr ""
-#: advanced.py:384
+#: advanced.py:385
msgid "Log"
msgstr ""
-#: advanced.py:385
+#: advanced.py:386
msgid "Errors"
msgstr ""
-#: advanced.py:437
+#: advanced.py:438
msgid "Total items: {}"
msgstr ""
-#: advanced.py:438 lib/translation.py:233
+#: advanced.py:439 lib/translation.py:233
msgid "Character count: {}"
msgstr ""
-#: advanced.py:466 cache.py:92 cache.py:182 components/engine.py:200
+#: advanced.py:467 cache.py:92 cache.py:182 components/engine.py:200
#: components/table.py:135
msgid "Delete"
msgstr ""
-#: advanced.py:467
+#: advanced.py:468
msgid "Translate All"
msgstr ""
-#: advanced.py:468
+#: advanced.py:469
msgid "Translate Selected"
msgstr ""
-#: advanced.py:493 advanced.py:504
+#: advanced.py:494 advanced.py:505
msgid "Stop"
msgstr ""
-#: advanced.py:499
+#: advanced.py:500
msgid "Stopping..."
msgstr ""
-#: advanced.py:529 setting.py:326
-msgid "Translation Engine"
-msgstr ""
-
-#: advanced.py:535 batch.py:55 setting.py:366
-msgid "Source Language"
-msgstr ""
-
-#: advanced.py:547
+#: advanced.py:530
msgid "Cache Status"
msgstr ""
-#: advanced.py:550
+#: advanced.py:533
msgid "Disabled"
msgstr ""
-#: advanced.py:550
+#: advanced.py:533
msgid "Enabled"
msgstr ""
-#: advanced.py:557
-msgid "Output Ebook"
+#: advanced.py:540 setting.py:327
+msgid "Translation Engine"
msgstr ""
-#: advanced.py:559
-msgid "Output"
+#: advanced.py:546 batch.py:55 setting.py:367
+msgid "Source Language"
msgstr ""
-#: advanced.py:565 cache.py:203
-msgid "Filename"
+#: advanced.py:558
+msgid "Custom Ebook Title"
msgstr ""
-#: advanced.py:567
-msgid "Format"
+#: advanced.py:564
+msgid "By default, title metadata will be translated."
msgstr ""
-#: advanced.py:574
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
+#: advanced.py:592
+msgid "Output Ebook"
+msgstr ""
+
+#: advanced.py:594
+msgid "Output"
msgstr ""
-#: advanced.py:620 components/table.py:89
+#: advanced.py:642 components/table.py:89
msgid "Translated"
msgstr ""
-#: advanced.py:621
+#: advanced.py:643
msgid "The ebook has not been translated yet."
msgstr ""
-#: advanced.py:625
+#: advanced.py:647
msgid ""
"The number of lines in some translation units differs between the original "
"text and the translated text. Are you sure you want to output without "
"checking alignment?"
msgstr ""
-#: advanced.py:660
+#: advanced.py:682
msgid "No translation yet"
msgstr ""
-#: advanced.py:709 components/engine.py:206 setting.py:96
+#: advanced.py:731 components/engine.py:206 setting.py:97
msgid "Save"
msgstr ""
-#: advanced.py:765
+#: advanced.py:787
msgid "Your changes have been saved."
msgstr ""
-#: advanced.py:778
+#: advanced.py:800
msgid "Translation log"
msgstr ""
-#: advanced.py:789
+#: advanced.py:811
msgid "Error log"
msgstr ""
-#: advanced.py:809
+#: advanced.py:831
msgid "Are you sure you want to translate all {:n} paragraphs?"
msgstr ""
-#: advanced.py:835
+#: advanced.py:857
msgid "Are you sure you want to stop the translation progress?"
msgstr ""
-#: batch.py:54 setting.py:185
+#: batch.py:54 setting.py:186
msgid "Output Format"
msgstr ""
@@ -201,15 +195,15 @@ msgstr ""
msgid "Title"
msgstr ""
-#: batch.py:126 components/engine.py:137 components/table.py:133
+#: batch.py:127 components/engine.py:137 components/table.py:133
msgid "Translate"
msgstr ""
-#: batch.py:137 lib/cache.py:126
+#: batch.py:138 lib/cache.py:126
msgid "Unknown"
msgstr ""
-#: batch.py:146 cache.py:130 setting.py:1025
+#: batch.py:147 cache.py:130 setting.py:1091
msgid "The specified path does not exist."
msgstr ""
@@ -217,8 +211,8 @@ msgstr ""
msgid "Choose a path to store cache files."
msgstr ""
-#: cache.py:73 components/mode.py:41 components/mode.py:51 setting.py:156
-#: setting.py:799 setting.py:817 setting.py:865
+#: cache.py:73 components/mode.py:41 components/mode.py:51 setting.py:157
+#: setting.py:856 setting.py:875 setting.py:923
msgid "Choose"
msgstr ""
@@ -271,7 +265,7 @@ msgstr ""
msgid "Engine"
msgstr ""
-#: cache.py:202 components/table.py:40 setting.py:986
+#: cache.py:202 components/table.py:40
msgid "Language"
msgstr ""
@@ -279,6 +273,10 @@ msgstr ""
msgid "Merge Length"
msgstr ""
+#: cache.py:203
+msgid "Filename"
+msgstr ""
+
#: cache.py:203
msgid "Size (MB)"
msgstr ""
@@ -332,7 +330,7 @@ msgstr ""
msgid "The setting has been saved."
msgstr ""
-#: components/format.py:27 setting.py:194
+#: components/format.py:27 setting.py:195
msgid "Ebook Specific"
msgstr ""
@@ -344,15 +342,15 @@ msgstr ""
msgid "Feedback"
msgstr ""
-#: components/lang.py:34 engines/base.py:70 setting.py:1086
+#: components/lang.py:34 engines/base.py:70 setting.py:1152
msgid "Auto detect"
msgstr ""
-#: components/mode.py:28 setting.py:123
+#: components/mode.py:28 setting.py:124
msgid "Choose a translation mode for clicking the icon button."
msgstr ""
-#: components/mode.py:33 setting.py:113 ui.py:54 ui.py:82
+#: components/mode.py:33 setting.py:114 ui.py:54 ui.py:82
msgid "Advanced Mode"
msgstr ""
@@ -362,7 +360,7 @@ msgid ""
"for more control and customization."
msgstr ""
-#: components/mode.py:43 setting.py:114 ui.py:55 ui.py:109
+#: components/mode.py:43 setting.py:115 ui.py:55 ui.py:109
msgid "Batch Mode"
msgstr ""
@@ -372,7 +370,7 @@ msgid ""
"the translation process and saving time."
msgstr ""
-#: components/table.py:40 setting.py:719
+#: components/table.py:40 setting.py:726
msgid "Original"
msgstr ""
@@ -406,7 +404,7 @@ msgstr ""
msgid "Baidu"
msgstr ""
-#: engines/base.py:20 setting.py:347
+#: engines/base.py:20 setting.py:348
msgid "API Keys"
msgstr ""
@@ -532,19 +530,19 @@ msgstr ""
msgid "Translation job failed"
msgstr ""
-#: lib/conversion.py:263
+#: lib/conversion.py:275
msgid "completed"
msgstr ""
-#: lib/conversion.py:278
+#: lib/conversion.py:290
msgid "Ebook Translation Log"
msgstr ""
-#: lib/conversion.py:279
+#: lib/conversion.py:291
msgid "Translation Completed"
msgstr ""
-#: lib/conversion.py:280
+#: lib/conversion.py:292
msgid "The translation of \"{}\" was completed. Do you want to open the book?"
msgstr ""
@@ -612,311 +610,331 @@ msgstr ""
msgid "Content"
msgstr ""
-#: setting.py:111
+#: setting.py:112
msgid "Preferred Mode"
msgstr ""
-#: setting.py:145
+#: setting.py:146
msgid "Output Path"
msgstr ""
-#: setting.py:147
+#: setting.py:148
msgid "Library"
msgstr ""
-#: setting.py:148
+#: setting.py:149
msgid "Path"
msgstr ""
-#: setting.py:153
+#: setting.py:154
msgid "Choose a path to store translated book(s)"
msgstr ""
-#: setting.py:180
+#: setting.py:181
msgid "Preferred Format"
msgstr ""
-#: setting.py:204
+#: setting.py:205
msgid "(Beta)"
msgstr ""
-#: setting.py:204
+#: setting.py:205
msgid "Merge to Translate"
msgstr ""
-#: setting.py:206 setting.py:227 setting.py:271 setting.py:862
+#: setting.py:207 setting.py:228 setting.py:272 setting.py:920
msgid "Enable"
msgstr ""
-#: setting.py:212
+#: setting.py:213
msgid "The number of characters to translate at once."
msgstr ""
-#: setting.py:224
+#: setting.py:225
msgid "HTTP Proxy"
msgstr ""
-#: setting.py:239
+#: setting.py:240
msgid "Host"
msgstr ""
-#: setting.py:242
+#: setting.py:243
msgid "Port"
msgstr ""
-#: setting.py:253 setting.py:329
+#: setting.py:254 setting.py:330
msgid "Test"
msgstr ""
-#: setting.py:269 ui.py:57
+#: setting.py:270 ui.py:57
msgid "Cache"
msgstr ""
-#: setting.py:272
+#: setting.py:273
msgid "Manage"
msgstr ""
-#: setting.py:289
+#: setting.py:290
msgid "Job Log"
msgstr ""
-#: setting.py:290
+#: setting.py:291
msgid "Show translation"
msgstr ""
-#: setting.py:303
+#: setting.py:304
msgid "Search Paths"
msgstr ""
-#: setting.py:306
+#: setting.py:307
msgid "The plugin will search for external programs via these paths."
msgstr ""
-#: setting.py:330 setting.py:536 setting.py:540 setting.py:547 setting.py:552
+#: setting.py:331 setting.py:543 setting.py:547 setting.py:554 setting.py:559
msgid "Custom"
msgstr ""
-#: setting.py:337
+#: setting.py:338
msgid "Usage Tip"
msgstr ""
-#: setting.py:351
+#: setting.py:352
msgid "Tip:"
msgstr ""
-#: setting.py:352
+#: setting.py:353
msgid "API keys will auto-switch if the previous one is unavailable."
msgstr ""
-#: setting.py:362
+#: setting.py:363
msgid "Preferred Language"
msgstr ""
-#: setting.py:373
+#: setting.py:374
msgid "HTTP Request"
msgstr ""
-#: setting.py:387
+#: setting.py:386
msgid "Concurrency limit"
msgstr ""
-#: setting.py:388
+#: setting.py:387
msgid "Interval (seconds)"
msgstr ""
-#: setting.py:389
+#: setting.py:388
msgid "Attempt times"
msgstr ""
-#: setting.py:390
+#: setting.py:389
msgid "Timeout (seconds)"
msgstr ""
-#: setting.py:392
-msgid "Error limit to stop translation"
+#: setting.py:393
+msgid "Abort Translation"
+msgstr ""
+
+#: setting.py:399
+msgid "The number of consecutive errors to abort translation."
msgstr ""
-#: setting.py:402
+#: setting.py:409
msgid "Tune Gemini"
msgstr ""
-#: setting.py:409 setting.py:443
+#: setting.py:416 setting.py:450
msgid "Prompt"
msgstr ""
-#: setting.py:435
+#: setting.py:442
msgid "Tune ChatGPT"
msgstr ""
-#: setting.py:445
+#: setting.py:452
msgid "Endpoint"
msgstr ""
-#: setting.py:454
+#: setting.py:461
msgid "Model"
msgstr ""
-#: setting.py:477
+#: setting.py:484
msgid "Sampling"
msgstr ""
-#: setting.py:482
+#: setting.py:489
msgid "Enable streaming text like in ChatGPT"
msgstr ""
-#: setting.py:483
+#: setting.py:490
msgid "Stream"
msgstr ""
-#: setting.py:700
+#: setting.py:707
msgid "Below original"
msgstr ""
-#: setting.py:702
+#: setting.py:709
msgid "Above original"
msgstr ""
-#: setting.py:704 setting.py:706
+#: setting.py:711 setting.py:713
msgid "Beta"
msgstr ""
-#: setting.py:704
+#: setting.py:711
msgid "Right to original"
msgstr ""
-#: setting.py:706
+#: setting.py:713
msgid "Left to original"
msgstr ""
-#: setting.py:707
+#: setting.py:714
msgid "With no original"
msgstr ""
-#: setting.py:726
+#: setting.py:733
msgid "Translation"
msgstr ""
-#: setting.py:737
+#: setting.py:750
+msgid "Column Gap"
+msgstr ""
+
+#: setting.py:792
msgid "Translation Position"
msgstr ""
-#: setting.py:788
+#: setting.py:844
msgid "Original Text Color"
msgstr ""
-#: setting.py:806
+#: setting.py:849 setting.py:867 setting.py:1026
+msgid "e.g.,"
+msgstr ""
+
+#: setting.py:863
msgid "Translation Text Color"
msgstr ""
-#: setting.py:860
+#: setting.py:918
msgid "Translation Glossary"
msgstr ""
-#: setting.py:864
+#: setting.py:922
msgid "Choose a glossary file"
msgstr ""
-#: setting.py:883
+#: setting.py:941
msgid "Ignore Paragraph"
msgstr ""
-#: setting.py:889
+#: setting.py:947
msgid "Scope"
msgstr ""
-#: setting.py:890
+#: setting.py:948
msgid "Text only"
msgstr ""
-#: setting.py:892
+#: setting.py:950
msgid "HTML element"
msgstr ""
-#: setting.py:899
+#: setting.py:957
msgid "Mode"
msgstr ""
-#: setting.py:900
+#: setting.py:958
msgid "Normal"
msgstr ""
-#: setting.py:902
+#: setting.py:960
msgid "Normal (case-sensitive)"
msgstr ""
-#: setting.py:903
+#: setting.py:961
msgid "Regular Expression"
msgstr ""
-#: setting.py:945
+#: setting.py:1003
msgid "Exclude paragraph by keyword. One keyword per line:"
msgstr ""
-#: setting.py:946
+#: setting.py:1004
msgid "Exclude paragraph by case-sensitive keyword. One keyword per line:"
msgstr ""
-#: setting.py:948
+#: setting.py:1006
msgid "Exclude paragraph by regular expression pattern. One pattern per line:"
msgstr ""
-#: setting.py:964
+#: setting.py:1022
msgid "Ignore Element"
msgstr ""
-#: setting.py:968
-msgid "e.g."
-msgstr ""
-
-#: setting.py:974
+#: setting.py:1032
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr ""
-#: setting.py:979
+#: setting.py:1037
msgid "Ebook Metadata"
msgstr ""
-#: setting.py:982
-msgid "Set \"Target Language\" to metadata"
+#: setting.py:1041
+msgid "Append target language to title metadata"
msgstr ""
-#: setting.py:985
+#: setting.py:1043
+msgid "Set target language code to language metadata"
+msgstr ""
+
+#: setting.py:1046
msgid "Subjects of ebook (one subject per line)"
msgstr ""
-#: setting.py:987
+#: setting.py:1047
+msgid "Language Mark"
+msgstr ""
+
+#: setting.py:1048
+msgid "Language Code"
+msgstr ""
+
+#: setting.py:1049
msgid "Subject"
msgstr ""
-#: setting.py:1004 setting.py:1039
+#: setting.py:1070 setting.py:1105
msgid "Proxy host or port is incorrect."
msgstr ""
-#: setting.py:1006
+#: setting.py:1072
msgid "The proxy is available."
msgstr ""
-#: setting.py:1007
+#: setting.py:1073
msgid "The proxy is not available."
msgstr ""
-#: setting.py:1096
+#: setting.py:1162
msgid "the prompt must include {}."
msgstr ""
-#: setting.py:1125 setting.py:1132
+#: setting.py:1191 setting.py:1198
msgid "Invalid color value."
msgstr ""
-#: setting.py:1141
+#: setting.py:1207
msgid "The specified glossary file does not exist."
msgstr ""
-#: setting.py:1153
+#: setting.py:1219
msgid "{} is not a valid regular expression."
msgstr ""
-#: setting.py:1165
+#: setting.py:1231
msgid "{} is not a valid CSS seletor."
msgstr ""
diff --git a/translations/pt.mo b/translations/pt.mo
index 4680493..516f94d 100644
Binary files a/translations/pt.mo and b/translations/pt.mo differ
diff --git a/translations/pt.po b/translations/pt.po
index 0492ddf..70d46a5 100644
--- a/translations/pt.po
+++ b/translations/pt.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: none\n"
@@ -87,12 +87,6 @@ msgstr "Parar"
msgid "Stopping..."
msgstr "Parando..."
-msgid "Translation Engine"
-msgstr "Mecanismo de Tradução"
-
-msgid "Source Language"
-msgstr "Idioma de Origem"
-
msgid "Cache Status"
msgstr "Status do Cache"
@@ -102,23 +96,24 @@ msgstr "Desabilitado"
msgid "Enabled"
msgstr "Habilitado"
-msgid "Output Ebook"
-msgstr "Ebook de Saída"
-
-msgid "Output"
-msgstr "Saída"
+msgid "Translation Engine"
+msgstr "Mecanismo de Tradução"
-msgid "Filename"
-msgstr "Nome do arquivo"
+msgid "Source Language"
+msgstr "Idioma de Origem"
-msgid "Format"
+msgid "Custom Ebook Title"
msgstr ""
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
+msgid "By default, title metadata will be translated."
msgstr ""
+msgid "Output Ebook"
+msgstr "Ebook de Saída"
+
+msgid "Output"
+msgstr "Saída"
+
msgid "Translated"
msgstr "Traduzido"
@@ -218,6 +213,9 @@ msgstr "Idioma"
msgid "Merge Length"
msgstr "Comprimento da Mesclagem"
+msgid "Filename"
+msgstr "Nome do arquivo"
+
msgid "Size (MB)"
msgstr "Tamanho (MB)"
@@ -572,8 +570,11 @@ msgstr "Limite de tentativas"
msgid "Timeout (seconds)"
msgstr "Tempo esgotado (segundos)"
-msgid "Error limit to stop translation"
-msgstr "Contagem de erros para interromper a tradução"
+msgid "Abort Translation"
+msgstr ""
+
+msgid "The number of consecutive errors to abort translation."
+msgstr ""
msgid "Tune Gemini"
msgstr ""
@@ -620,12 +621,18 @@ msgstr "Adicionar sem o original"
msgid "Translation"
msgstr ""
+msgid "Column Gap"
+msgstr ""
+
msgid "Translation Position"
msgstr "Posição da Tradução"
msgid "Original Text Color"
msgstr ""
+msgid "e.g.,"
+msgstr "por exemplo,"
+
msgid "Translation Text Color"
msgstr "Cor da tradução"
@@ -674,21 +681,27 @@ msgstr ""
msgid "Ignore Element"
msgstr "Ignorar Elemento"
-msgid "e.g."
-msgstr "por exemplo"
-
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr "Seletores CSS para excluir elementos. Uma regra por linha:"
msgid "Ebook Metadata"
msgstr "Metadados dos ebooks"
-msgid "Set \"Target Language\" to metadata"
-msgstr "Defina \"Idioma de destino\" como metadados"
+msgid "Append target language to title metadata"
+msgstr ""
+
+msgid "Set target language code to language metadata"
+msgstr "Defina idioma de destino como metadados"
msgid "Subjects of ebook (one subject per line)"
msgstr "Assuntos do e-book (um assunto por linha)"
+msgid "Language Mark"
+msgstr ""
+
+msgid "Language Code"
+msgstr ""
+
msgid "Subject"
msgstr "Assuntos"
diff --git a/translations/zh_CN.mo b/translations/zh_CN.mo
index 67e9893..5bbe31a 100644
Binary files a/translations/zh_CN.mo and b/translations/zh_CN.mo differ
diff --git a/translations/zh_CN.po b/translations/zh_CN.po
index b52d139..3c354bc 100644
--- a/translations/zh_CN.po
+++ b/translations/zh_CN.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: 2023-04-17 14:17+0800\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -85,12 +85,6 @@ msgstr "停止"
msgid "Stopping..."
msgstr "停止中..."
-msgid "Translation Engine"
-msgstr "翻译引擎"
-
-msgid "Source Language"
-msgstr "来源语言"
-
msgid "Cache Status"
msgstr "缓存状态"
@@ -100,24 +94,24 @@ msgstr "已禁用"
msgid "Enabled"
msgstr "已启用"
+msgid "Translation Engine"
+msgstr "翻译引擎"
+
+msgid "Source Language"
+msgstr "来源语言"
+
+msgid "Custom Ebook Title"
+msgstr "自定义书名"
+
+msgid "By default, title metadata will be translated."
+msgstr "默认情况下书名元数据会被翻译"
+
msgid "Output Ebook"
msgstr "输出电子书"
msgid "Output"
msgstr "输出"
-msgid "Filename"
-msgstr "文件名"
-
-msgid "Format"
-msgstr "格式"
-
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
-msgstr ""
-"由于输出路径是 Calibre 书库,因此电子书文件名由 Calibre 根据原数据自动处理。"
-
msgid "Translated"
msgstr "已翻译"
@@ -215,6 +209,9 @@ msgstr "语言"
msgid "Merge Length"
msgstr "合并长度"
+msgid "Filename"
+msgstr "文件名"
+
msgid "Size (MB)"
msgstr "大小(MB)"
@@ -562,8 +559,11 @@ msgstr "重试次数"
msgid "Timeout (seconds)"
msgstr "超时(秒)"
-msgid "Error limit to stop translation"
-msgstr "超过错误限制停止翻译"
+msgid "Abort Translation"
+msgstr "中止翻译"
+
+msgid "The number of consecutive errors to abort translation."
+msgstr "超过连续错误次数中止翻译。"
msgid "Tune Gemini"
msgstr "调节 Gemini"
@@ -610,12 +610,18 @@ msgstr "仅保留译文"
msgid "Translation"
msgstr "译文"
+msgid "Column Gap"
+msgstr "栏间距"
+
msgid "Translation Position"
msgstr "译文位置"
msgid "Original Text Color"
msgstr "原文颜色"
+msgid "e.g.,"
+msgstr "如"
+
msgid "Translation Text Color"
msgstr "译文颜色"
@@ -661,21 +667,27 @@ msgstr "排除匹配正则表达式规则的段落。一行一条规则:"
msgid "Ignore Element"
msgstr "忽略元素"
-msgid "e.g."
-msgstr "如"
-
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr "用来排除元素的 CSS 选择器。一行一条规则:"
msgid "Ebook Metadata"
msgstr "电子书元数据"
-msgid "Set \"Target Language\" to metadata"
-msgstr "将目标语言设为元数据中的语言"
+msgid "Append target language to title metadata"
+msgstr "将目标语言附加到书名元数据中"
+
+msgid "Set target language code to language metadata"
+msgstr "将语言元数据设置为目标语言代码"
msgid "Subjects of ebook (one subject per line)"
msgstr "电子书主题(每行一个主题)"
+msgid "Language Mark"
+msgstr "语言标记"
+
+msgid "Language Code"
+msgstr "语言代码"
+
msgid "Subject"
msgstr "主题"
@@ -732,3 +744,12 @@ msgstr "缓存管理器"
msgid "Choose Translation Mode"
msgstr "选择翻译模式"
+
+#~ msgid "Format"
+#~ msgstr "格式"
+
+#~ msgid "Error limit to stop translation"
+#~ msgstr "超过错误限制停止翻译"
+
+#~ msgid "Set \"Target Language\" to metadata"
+#~ msgstr "将目标语言设为元数据中的语言"
diff --git a/translations/zh_TW.po b/translations/zh_TW.po
index b720389..48816ca 100644
--- a/translations/zh_TW.po
+++ b/translations/zh_TW.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: bookfere@gmail.com\n"
-"POT-Creation-Date: 2024-03-12 21:56+0800\n"
+"POT-Creation-Date: 2024-03-13 23:34+0800\n"
"PO-Revision-Date: 2023-04-25 15:36+0800\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -86,12 +86,6 @@ msgstr ""
msgid "Stopping..."
msgstr ""
-msgid "Translation Engine"
-msgstr "翻譯引擎"
-
-msgid "Source Language"
-msgstr "來源語言"
-
msgid "Cache Status"
msgstr ""
@@ -101,21 +95,22 @@ msgstr ""
msgid "Enabled"
msgstr ""
-msgid "Output Ebook"
-msgstr ""
+msgid "Translation Engine"
+msgstr "翻譯引擎"
-msgid "Output"
+msgid "Source Language"
+msgstr "來源語言"
+
+msgid "Custom Ebook Title"
msgstr ""
-msgid "Filename"
+msgid "By default, title metadata will be translated."
msgstr ""
-msgid "Format"
+msgid "Output Ebook"
msgstr ""
-msgid ""
-"The ebook's filename is automatically managed by Calibre according to "
-"metadata since the output path is set to Calibre Library."
+msgid "Output"
msgstr ""
msgid "Translated"
@@ -215,6 +210,9 @@ msgstr ""
msgid "Merge Length"
msgstr ""
+msgid "Filename"
+msgstr ""
+
msgid "Size (MB)"
msgstr ""
@@ -557,7 +555,10 @@ msgstr "嘗試次數"
msgid "Timeout (seconds)"
msgstr ""
-msgid "Error limit to stop translation"
+msgid "Abort Translation"
+msgstr ""
+
+msgid "The number of consecutive errors to abort translation."
msgstr ""
msgid "Tune Gemini"
@@ -605,12 +606,18 @@ msgstr "僅保留譯文"
msgid "Translation"
msgstr ""
+msgid "Column Gap"
+msgstr ""
+
msgid "Translation Position"
msgstr "譯文位置"
msgid "Original Text Color"
msgstr ""
+msgid "e.g.,"
+msgstr ""
+
msgid "Translation Text Color"
msgstr "譯文色彩"
@@ -656,21 +663,27 @@ msgstr "依規則運算式模式排除段落。每行一條模式:"
msgid "Ignore Element"
msgstr ""
-msgid "e.g."
-msgstr ""
-
msgid "CSS selectors to exclude elements. One rule per line:"
msgstr ""
msgid "Ebook Metadata"
msgstr ""
-msgid "Set \"Target Language\" to metadata"
+msgid "Append target language to title metadata"
+msgstr ""
+
+msgid "Set target language code to language metadata"
msgstr ""
msgid "Subjects of ebook (one subject per line)"
msgstr ""
+msgid "Language Mark"
+msgstr ""
+
+msgid "Language Code"
+msgstr ""
+
msgid "Subject"
msgstr ""
@@ -727,4 +740,3 @@ msgstr ""
msgid "Choose Translation Mode"
msgstr ""
-