diff --git a/aboutdialog.py b/aboutdialog.py index 4d89825..167ce9b 100644 --- a/aboutdialog.py +++ b/aboutdialog.py @@ -20,7 +20,7 @@ class AboutDialog(QDialog): self.layout = QVBoxLayout(self) - heading_app_name = QLabel("RavenLog") + heading_app_name = QLabel(self.tr("RavenLog")) heading_app_name.setAlignment(Qt.AlignmentFlag.AlignLeft) heading_app_name.setFont(QFont("default", 25)) heading_app_name.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) diff --git a/bigtext.py b/bigtext.py index 031dc6c..4d6cd7b 100644 --- a/bigtext.py +++ b/bigtext.py @@ -335,13 +335,13 @@ class InnerBigText(QWidget): you_sure.setStandardButtons(QMessageBox.StandardButton.Cancel) you_sure.addButton(QPushButton(self.tr("Copy {0} to Clipboard").format(bytes_human_readable)), QMessageBox.ButtonRole.AcceptRole) - you_sure.addButton(QPushButton(self.tr("Write to File")), QMessageBox.ButtonRole.YesRole) + you_sure.addButton(QPushButton(self.tr("Write to File")), QMessageBox.ActionRole) you_sure.setDefaultButton(QMessageBox.StandardButton.Cancel) result = you_sure.exec() if result == 1: # second custom button has the number 1 self._copy_selection_to_file() - if result == QMessageBox.StandardButton.Cancel.value: + if result == QMessageBox.StandardButton.Cancel: # abort return diff --git a/main.py b/main.py index 947aa10..973dff6 100644 --- a/main.py +++ b/main.py @@ -1,10 +1,11 @@ import logging +import os import signal import ctypes from PySide6 import QtCore from PySide6.QtWidgets import QApplication -from PySide6.QtCore import QTimer +from PySide6.QtCore import QTimer, QLibraryInfo, QTranslator, QLocale from PySide6.QtGui import QIcon import sys @@ -40,6 +41,17 @@ if __name__ == "__main__": # if translator.load(QLocale("de"), "messages_de.ts"): # app.installTranslator(translator) + locale = os.environ['LANG'] if os.environ['LANG'] else "en" + + path = QLibraryInfo.location(QLibraryInfo.TranslationsPath) + translator = QTranslator(app) + if translator.load(QLocale(locale), 'qtbase', '_', path): + app.installTranslator(translator) + translator = QTranslator(app) + path = './translations' + if translator.load(QLocale(locale), 'messages', '_', path): + app.installTranslator(translator) + # workaround to make signals work in QT apps. # They do not work out of the box, because the main thread # is running in C++ code once app.exec() is executed @@ -55,6 +67,8 @@ if __name__ == "__main__": PluginRegistry.load_plugin("LogFilePlugin") PluginRegistry.load_plugin("NotesPlugin") + PluginRegistry.execute("set_translator", lambda string: translator.tr(string)) + window = PluginRegistry.execute_single("create_main_window") RavenUI.window = window window.show() diff --git a/messages_de.ts b/messages_de.ts index 06cd4fd..08c5168 100644 --- a/messages_de.ts +++ b/messages_de.ts @@ -1,29 +1,326 @@ - - + + + AboutDialog + + + About RavenLog + Über RavenLog + + + + RavenLog + RavenLog + + + + Version: {0} + Version: {0} + + + + About + Über RavenLog + + + + License + Lizenz + + + + ColorButton + + + Strawberry Cream + Strawberry Cream + + + + Pale Crimson + Pale Crimson + + + + Broken Buttercup + Broken Buttercup + + + + Passion Fruit Sugar + Passion Fruit Sugar + + + + Sunrise Yellow + Sunrise Yellow + + + + Magical Mustard + Magical Mustard + + + + Trendy Green + Trendy Green + + + + Garden Of Sweden + Garden Of Sweden + + + + Light Sky Blue + Light Sky Blue + + + + True Blue + True Blue + + + + Fairy Topia + Fairy Topia + + + + Magenta Bachiego + Magenta Bachiego + + + + Breeze of Mist + Breeze of Mist + + + + Light Grey + Light Grey + + + + Grey + Grey + + + + transparent + Transparent + + + + custom + Individuell + + + + FilterWidget + + + Cancel + Abbrechen + + + + ignore case + Groß-/Kleinschreibung + + + + regex + RegExp + + + + HighlightingDialog + + + Manage Highlighting + Hervorhebungen Verwalten + + + + Add + Hinzufügen + + + + Update + Aktualisieren + + + + Remove + Entfernen + + + + Up + Hoch + + + + Down + Runter + + + + Query: + Suche + + + + Ignore Case + Groß-/Kleinschreibung + + + + Regular Expression + Regulärer Ausdruck + + + + Hit Background: + Hintergrund Treffer + + + + Line Background: + Hintergrund Zeile + + + + unsaved changes + nicht gespeicherte Änderungen + + + + You have unsaved changes. Continue? + Du hast Änderungen die noch nicht gespeichert sind. Weiter? + + + + Continue + Weiter + + + + InnerBigText + + + &Copy to Clipboard + &Kopiere in die Zwischenablage + + + + Copy to &File + Speichere als &Datei + + + + Select &All + &Alles Selektieren + + + + &Highlighter + &Hervorhebungen + + + + data selection + Selektion + + + + You have selected <b>{0}</b> of data. + Du hast <b>{0}</b> selektiert. + + + + Copy {0} to Clipboard + {0} in Zwischenablage kopieren + + + + Write to File + In Datei speichern + + + + Save File + Datei Speichern + + + MainWindow - - RavenLog - RavenLog + + RavenLog + RavenLog - - Font Size: - Schriftgröße: + + Open &Recent + Zu&letzt geöffnete Dateien - - File - name of the file menu - Datei + + &File + &Datei - - Close - menu item to close the application - Schließen + + &Settings + &Einstellungen - + + + &Window + &Fenster + + + + &Help + &Hilfe + + + + NotesPlugin + + + Add &Notes + Notizen Hinzufügen + + + + Notes %d + Notizen %d + + + + OpenFilePlugin + + + Open File + Datei öffnen + + + + RavenLogPlugin + + + &About + &Über RavenLog + + + + E&xit + Be&enden + + diff --git a/raven/mainwindow.py b/raven/mainwindow.py index 389e114..3a43ba5 100644 --- a/raven/mainwindow.py +++ b/raven/mainwindow.py @@ -35,7 +35,7 @@ class MainWindow(QMainWindow): self.settings = SettingsStore.load() PluginRegistry.execute("set_settings", self.settings) - PluginRegistry.execute("set_translator", self.tr) + self.setWindowTitle(self.tr("RavenLog")) self._restore_window() @@ -80,7 +80,7 @@ class MainWindow(QMainWindow): action = self._raction_to_qaction(menu_contribution.action, menu) menu.addAction(action) if menu_contribution.menu: - submenu = QMenu(self.tr(menu_contribution.menu.label), menu_bar) + submenu = QMenu(menu_contribution.menu.label, menu_bar) submenu.setIcon(QIcon.fromTheme(menu_contribution.menu.icon_from_theme)) menu_contribution.menu.add_change_listener( lambda qmenu=submenu, rmenu=menu_contribution.menu: self._rmenu_update(qmenu, rmenu)) diff --git a/raven/pluginbase.py b/raven/pluginbase.py index 1b79fbc..141f2f3 100644 --- a/raven/pluginbase.py +++ b/raven/pluginbase.py @@ -1,3 +1,6 @@ +from PySide6.QtCore import QObject + + class PluginBase(): def __init__(self): pass diff --git a/raven/plugins/notesplugin.py b/raven/plugins/notesplugin.py index b916521..dbf5009 100644 --- a/raven/plugins/notesplugin.py +++ b/raven/plugins/notesplugin.py @@ -26,7 +26,7 @@ class NotesPlugin(PluginBase): ] def _add_notes_tab_action(self) -> RAction: - open_file = RAction("Add &Notes", self._add_notes_tab, shortcut='Ctrl+Shift+N', + open_file = RAction(self.tr("Add &Notes"), self._add_notes_tab, shortcut='Ctrl+Shift+N', icon_from_theme="filenew") return open_file diff --git a/raven/plugins/openfileplugin.py b/raven/plugins/openfileplugin.py index 96faf3d..c2ccd17 100644 --- a/raven/plugins/openfileplugin.py +++ b/raven/plugins/openfileplugin.py @@ -1,6 +1,8 @@ import os from typing import Callable from pathlib import Path + +from PySide6.QtCore import QObject from PySide6.QtWidgets import QFileDialog from raven.pluginbase import PluginBase @@ -24,12 +26,12 @@ class OpenFilePlugin(PluginBase): self.tr = tr def _action_open_file(self) -> RAction: - open_file = RAction("&Open...", self._open_file_dialog, shortcut='Ctrl+O', + open_file = RAction(self.tr("&Open..."), self._open_file_dialog, shortcut='Ctrl+O', icon_from_theme="document-open") return open_file def _sub_menu_recent_files(self) -> RMenu: - self._menu_recent_files = RMenu("Open &Recent", icon_from_theme="document-open-recent") + self._menu_recent_files = RMenu(self.tr("Open &Recent"), icon_from_theme="document-open-recent") self._update_recent_files_menu() return self._menu_recent_files diff --git a/raven/plugins/ravenlogplugin.py b/raven/plugins/ravenlogplugin.py index 38ec6db..3b800de 100644 --- a/raven/plugins/ravenlogplugin.py +++ b/raven/plugins/ravenlogplugin.py @@ -1,5 +1,5 @@ import sys -from typing import Optional +from typing import Optional, Callable from PySide6.QtCore import Qt from PySide6.QtWidgets import QDockWidget @@ -16,8 +16,12 @@ from raven.plugins.ravenlog.Tab import Tab class RavenLogPlugin(PluginBase): def __init__(self): super(RavenLogPlugin, self).__init__() + self.tr = None self.main_window = None + def set_translator(self, tr: Callable[[str], str]): + self.tr = tr + def create_main_window(self): if not self.main_window: self.main_window = MainWindow() @@ -42,7 +46,7 @@ class RavenLogPlugin(PluginBase): def _action_about(self) -> RAction: about_action = RAction( - "&About", + self.tr("&About"), action=lambda: AboutDialog().exec(), icon_file=constants.raven_icon ) @@ -50,6 +54,6 @@ class RavenLogPlugin(PluginBase): def _action_close(self) -> RAction: icon = "close" if sys.platform == 'win32' or sys.platform == 'cygwin' else "exit" - close_action = RAction("E&xit", action=lambda: self.main_window.destruct(), shortcut='Ctrl+X', + close_action = RAction(self.tr("E&xit"), action=lambda: self.main_window.destruct(), shortcut='Ctrl+X', icon_from_theme=icon) return close_action diff --git a/translate.sh b/translate.sh new file mode 100755 index 0000000..e2754d0 --- /dev/null +++ b/translate.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "extract text from source files" +pyside6-lupdate *.py raven/*.py raven/plugins/*.py -recursive -ts messages_de.ts + +echo "write translation to qm file" +pyside6-lrelease messages_de.ts -qm translations/messages_de.qm \ No newline at end of file diff --git a/translations/messages_de.qm b/translations/messages_de.qm new file mode 100644 index 0000000..7795693 Binary files /dev/null and b/translations/messages_de.qm differ