diff --git a/src/main.py b/src/main.py index 0bd6378..aaab597 100644 --- a/src/main.py +++ b/src/main.py @@ -31,6 +31,15 @@ class Toxygen(object): auto_profile = Settings.get_auto_profile() if not auto_profile: # show login screen if default profile not found + current_locale = QtCore.QLocale() + curr_lang = current_locale.languageToString(current_locale.language()) + langs = Settings.supported_languages() + if curr_lang in map(lambda x: x[0], langs): + lang_path = filter(lambda x: x[0] == curr_lang, langs)[0][1] + translator = QtCore.QTranslator() + translator.load('translations/' + lang_path) + app.installTranslator(translator) + app.translator = translator ls = LoginScreen() ls.setWindowIconText("Toxygen") profiles = ProfileHelper.find_profiles() @@ -67,7 +76,7 @@ class Toxygen(object): deactivate = False reply = QtGui.QMessageBox.question(None, 'Profile {}'.format(name), - 'Looks like other instance of Toxygen uses this profile! Continue?', + QtGui.QApplication.translate("login", 'Looks like other instance of Toxygen uses this profile! Continue?', None, QtGui.QApplication.UnicodeUTF8), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply != QtGui.QMessageBox.Yes: @@ -76,13 +85,20 @@ class Toxygen(object): settings.set_active_profile() deactivate = True + lang = filter(lambda x: x[0] == settings['language'], Settings.supported_languages())[0] + translator = QtCore.QTranslator() + translator.load('translations/' + lang[1]) + app.installTranslator(translator) + app.translator = translator + self.ms = MainWindow(self.tox, self.reset) # tray icon self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png')) + self.tray.setObjectName('tray') m = QtGui.QMenu() - show = m.addAction('Open Toxygen') - exit = m.addAction('Exit') + show = m.addAction(QtGui.QApplication.translate('tray', 'Open Toxygen', None, QtGui.QApplication.UnicodeUTF8)) + exit = m.addAction(QtGui.QApplication.translate('tray', 'Exit', None, QtGui.QApplication.UnicodeUTF8)) def show_window(): if not self.ms.isActiveWindow(): diff --git a/src/mainscreen.py b/src/mainscreen.py index f02a0c9..c4b45b0 100644 --- a/src/mainscreen.py +++ b/src/mainscreen.py @@ -78,7 +78,13 @@ class MainWindow(QtGui.QMainWindow): self.actionPrivacy_settings.triggered.connect(self.privacy_settings) self.actionInterface_settings.triggered.connect(self.interface_settings) self.actionNotifications.triggered.connect(self.notification_settings) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + def languageChange(self, *args, **kwargs): + self.retranslateUi() + + def retranslateUi(self): + self.online_contacts.setText(QtGui.QApplication.translate("Form", "Online contacts", None, QtGui.QApplication.UnicodeUTF8)) self.menuProfile.setTitle(QtGui.QApplication.translate("MainWindow", "Profile", None, QtGui.QApplication.UnicodeUTF8)) self.menuSettings.setTitle(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8)) self.menuAbout.setTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) @@ -90,7 +96,6 @@ class MainWindow(QtGui.QMainWindow): self.actionNetwork.setText(QtGui.QApplication.translate("MainWindow", "Network", None, QtGui.QApplication.UnicodeUTF8)) self.actionAbout_program.setText(QtGui.QApplication.translate("MainWindow", "About program", None, QtGui.QApplication.UnicodeUTF8)) self.actionSettings.setText(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8)) - QtCore.QMetaObject.connectSlotsByName(MainWindow) def setup_right_bottom(self, Form): Form.setObjectName("right_bottom") @@ -137,7 +142,6 @@ class MainWindow(QtGui.QMainWindow): self.contact_name.setGeometry(QtCore.QRect(0, 27, 270, 30)) self.contact_name.setObjectName("contact_name") self.contact_name.textChanged.connect(self.filtering) - self.online_contacts.setText(QtGui.QApplication.translate("Form", "Online contacts", None, QtGui.QApplication.UnicodeUTF8)) QtCore.QMetaObject.connectSlotsByName(Form) def setup_left_top(self, Form): @@ -261,6 +265,7 @@ class MainWindow(QtGui.QMainWindow): self.user_info = name self.friend_info = info self.profile = Profile(tox, self) + self.retranslateUi() def closeEvent(self, *args, **kwargs): self.profile.save_history() @@ -272,8 +277,8 @@ class MainWindow(QtGui.QMainWindow): def about_program(self): import util msgBox = QtGui.QMessageBox() - msgBox.setWindowTitle('About') - msgBox.setText('Toxygen is Tox client written on Python 2.7. Version: ' + util.program_version) + msgBox.setWindowTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) + msgBox.setText(QtGui.QApplication.translate("MainWindow", 'Toxygen is Tox client written on Python 2.7. Version: ', None, QtGui.QApplication.UnicodeUTF8) + util.program_version) msgBox.exec_() def network_settings(self): @@ -310,7 +315,8 @@ class MainWindow(QtGui.QMainWindow): def send_file(self): if self.profile.is_active_online(): # active friend exists and online - name = QtGui.QFileDialog.getOpenFileName(self, 'Choose file') + choose = QtGui.QApplication.translate("MainWindow", "Choose file", None, QtGui.QApplication.UnicodeUTF8) + name = QtGui.QFileDialog.getOpenFileName(self, choose) if name[0]: self.profile.send_file(name[0]) @@ -329,14 +335,14 @@ class MainWindow(QtGui.QMainWindow): friend = Profile.get_instance().get_friend_by_number(num) settings = Settings.get_instance() allowed = friend.tox_id in settings['auto_accept_from_friends'] - auto = 'Disallow auto accept' if allowed else 'Allow auto accept' + auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8) if item is not None: self.listMenu = QtGui.QMenu() - set_alias_item = self.listMenu.addAction('Set alias') - clear_history_item = self.listMenu.addAction('Clear history') - copy_key_item = self.listMenu.addAction('Copy public key') + set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8)) + clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8)) + copy_key_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Copy public key', None, QtGui.QApplication.UnicodeUTF8)) auto_accept_item = self.listMenu.addAction(auto) - remove_item = self.listMenu.addAction('Remove friend') + remove_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Remove friend', None, QtGui.QApplication.UnicodeUTF8)) self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num)) self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num)) self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num)) diff --git a/src/menu.py b/src/menu.py index a91d037..5bec3f3 100644 --- a/src/menu.py +++ b/src/menu.py @@ -87,15 +87,15 @@ class ProfileSettings(CenteredWidget): def initUI(self): self.setObjectName("ProfileSettingsForm") - self.setMinimumSize(QtCore.QSize(650, 400)) - self.setMaximumSize(QtCore.QSize(650, 400)) + self.setMinimumSize(QtCore.QSize(650, 370)) + self.setMaximumSize(QtCore.QSize(650, 370)) self.nick = QtGui.QLineEdit(self) - self.nick.setGeometry(QtCore.QRect(30, 60, 351, 27)) + self.nick.setGeometry(QtCore.QRect(30, 60, 350, 27)) self.nick.setObjectName("nick") profile = Profile.get_instance() self.nick.setText(profile.name) self.status = QtGui.QLineEdit(self) - self.status.setGeometry(QtCore.QRect(30, 130, 351, 27)) + self.status.setGeometry(QtCore.QRect(30, 130, 350, 27)) self.status.setObjectName("status") self.status.setText(profile.status_message) self.label = QtGui.QLabel(self) @@ -129,14 +129,6 @@ class ProfileSettings(CenteredWidget): self.export.setGeometry(QtCore.QRect(200, 250, 150, 30)) self.export.setObjectName("export") self.export.clicked.connect(self.export_profile) - self.lang_choose = QtGui.QComboBox(self) - self.lang_choose.setGeometry(QtCore.QRect(30, 350, 211, 27)) - self.lang_choose.setObjectName("comboBox") - self.lang_choose.addItem('English') - self.lang = QtGui.QLabel(self) - self.lang.setGeometry(QtCore.QRect(40, 310, 121, 31)) - font.setPointSize(18) - self.lang.setFont(font) self.new_avatar = QtGui.QPushButton(self) self.new_avatar.setGeometry(QtCore.QRect(400, 50, 200, 50)) self.delete_avatar = QtGui.QPushButton(self) @@ -153,7 +145,6 @@ class ProfileSettings(CenteredWidget): self.label_2.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Status:", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setText(QtGui.QApplication.translate("ProfileSettingsForm", "TOX ID:", None, QtGui.QApplication.UnicodeUTF8)) self.copyId.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Copy TOX ID", None, QtGui.QApplication.UnicodeUTF8)) - self.lang.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Language:", None, QtGui.QApplication.UnicodeUTF8)) self.new_avatar.setText(QtGui.QApplication.translate("ProfileSettingsForm", "New avatar", None, QtGui.QApplication.UnicodeUTF8)) self.delete_avatar.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Reset avatar", None, QtGui.QApplication.UnicodeUTF8)) @@ -384,25 +375,46 @@ class InterfaceSettings(CenteredWidget): self.label.setObjectName("label") self.themeSelect = QtGui.QComboBox(self) self.themeSelect.setGeometry(QtCore.QRect(30, 60, 161, 31)) - font = QtGui.QFont() - font.setPointSize(17) - self.themeSelect.setFont(font) self.themeSelect.setObjectName("themeSelect") list_of_themes = ['default', 'windows', 'gtk', 'cde', 'plastique', 'motif'] self.themeSelect.addItems(list_of_themes) - theme = Settings.get_instance()['theme'] + settings = Settings.get_instance() + theme = settings['theme'] index = list_of_themes.index(theme) self.themeSelect.setCurrentIndex(index) + self.lang_choose = QtGui.QComboBox(self) + self.lang_choose.setGeometry(QtCore.QRect(30, 150, 211, 27)) + self.lang_choose.setObjectName("comboBox") + supported = Settings.supported_languages() + for elem in supported: + self.lang_choose.addItem(elem[0]) + lang = settings['language'] + index = map(lambda x: x[0], supported).index(lang) + self.lang_choose.setCurrentIndex(index) + self.lang = QtGui.QLabel(self) + self.lang.setGeometry(QtCore.QRect(30, 110, 121, 31)) + self.lang.setFont(font) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): self.setWindowTitle(QtGui.QApplication.translate("interfaceForm", "Interface settings", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("interfaceForm", "Theme:", None, QtGui.QApplication.UnicodeUTF8)) + self.lang.setText(QtGui.QApplication.translate("interfaceForm", "Language:", None, QtGui.QApplication.UnicodeUTF8)) def closeEvent(self, event): settings = Settings.get_instance() style = str(self.themeSelect.currentText()) settings['theme'] = style - settings.save() QtGui.QApplication.setStyle(get_style(style)) + language = self.lang_choose.currentText() + if settings['language'] != language: + settings['language'] = language + index = self.lang_choose.currentIndex() + path = Settings.supported_languages()[index][1] + app = QtGui.QApplication.instance() + app.removeTranslator(app.translator) + app.translator.load(curr_directory() + '/translations/' + path) + app.installTranslator(app.translator) + settings.save() + diff --git a/src/profile.py b/src/profile.py index ac6d134..48eebab 100644 --- a/src/profile.py +++ b/src/profile.py @@ -682,8 +682,10 @@ class Profile(Contact, Singleton): :param message: message """ try: - info = 'User {} wants to add you to contact list. Message:\n{}'.format(tox_id, message) - reply = QtGui.QMessageBox.question(None, 'Friend request', info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + text = QtGui.QApplication.translate('MainWindow', 'User {} wants to add you to contact list. Message:\n{}', None, QtGui.QApplication.UnicodeUTF8) + info = text.format(tox_id, message) + fr_req = QtGui.QApplication.translate('MainWindow', 'Friend request', None, QtGui.QApplication.UnicodeUTF8) + reply = QtGui.QMessageBox.question(None, fr_req, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: # accepted num = self._tox.friend_add_norequest(tox_id) # num - friend number item = self.create_friend_item() diff --git a/src/settings.py b/src/settings.py index a3a8085..78854b1 100644 --- a/src/settings.py +++ b/src/settings.py @@ -48,7 +48,7 @@ class Settings(Singleton, dict): 'tcp_port': 0, 'notifications': True, 'sound_notifications': False, - 'language': 'en-en', + 'language': 'English', 'save_history': False, 'allow_inline': True, 'allow_auto_accept': False, @@ -60,6 +60,13 @@ class Settings(Singleton, dict): 'calls_sound': True } + @staticmethod + def supported_languages(): + return [ + ('English', 'en_EN'), + ('Russian', 'ru_RU') + ] + def save(self): text = json.dumps(self) with open(self.path, 'w') as fl: diff --git a/src/toxygen.pro b/src/toxygen.pro new file mode 100644 index 0000000..02e4f0f --- /dev/null +++ b/src/toxygen.pro @@ -0,0 +1,2 @@ +SOURCES = main.py profile.py menu.py list_items.py loginscreen.py mainscreen.py +TRANSLATIONS = translations/en_GB.ts translations/ru_RU.ts diff --git a/src/translations/en_GB.qm b/src/translations/en_GB.qm new file mode 100644 index 0000000..cfa5f65 Binary files /dev/null and b/src/translations/en_GB.qm differ diff --git a/src/translations/en_GB.ts b/src/translations/en_GB.ts new file mode 100644 index 0000000..0ad236d --- /dev/null +++ b/src/translations/en_GB.ts @@ -0,0 +1,344 @@ + + + + AddContact + + + Add contact + Add contact + + + + TOX ID: + TOX ID: + + + + Message: + Message: + + + + Form + + + Send request + Send request + + + + IPv6 + IPv6 + + + + UDP + UDP + + + + Proxy + Proxy + + + + IP: + IP: + + + + Port: + Port: + + + + Online contacts + Online contacts + + + + MainWindow + + + Profile + + + + + Settings + + + + + About + + + + + Add contact + + + + + Privacy + + + + + Interface + + + + + Notifications + + + + + Network + + + + + About program + + + + + User {} wants to add you to contact list. Message: +{} + + + + + Friend request + + + + + Toxygen is Tox client written on Python 2.7. Version: + + + + + Choose file + + + + + Disallow auto accept + + + + + Allow auto accept + + + + + Set alias + + + + + Clear history + + + + + Copy public key + + + + + Remove friend + + + + + NetworkSettings + + + Network settings + Network settings + + + + ProfileSettingsForm + + + Export profile + + + + + Profile settings + + + + + Name: + + + + + Status: + + + + + TOX ID: + + + + + Copy TOX ID + + + + + New avatar + + + + + Reset avatar + + + + + interfaceForm + + + Interface settings + + + + + Theme: + + + + + Language: + + + + + login + + + Log in + + + + + Create + + + + + Profile name: + + + + + Load profile + + + + + Use as default + + + + + Load existing profile + + + + + Create new profile + + + + + toxygen + + + + + Looks like other instance of Toxygen uses this profile! Continue? + + + + + notificationsForm + + + Notification settings + + + + + Enable notifications + + + + + Enable call's sound + + + + + Enable sound notifications + + + + + privacySettings + + + Privacy settings + + + + + Save chat history + + + + + Allow file auto accept + + + + + Send typing notifications + + + + + Auto accept default path: + + + + + Change + + + + + tray + + + Open Toxygen + + + + + Exit + + + + diff --git a/src/translations/ru_RU.qm b/src/translations/ru_RU.qm new file mode 100644 index 0000000..49a5338 Binary files /dev/null and b/src/translations/ru_RU.qm differ diff --git a/src/translations/ru_RU.ts b/src/translations/ru_RU.ts new file mode 100644 index 0000000..b2932f4 --- /dev/null +++ b/src/translations/ru_RU.ts @@ -0,0 +1,352 @@ + + + + + AddContact + + + Add contact + Добавить контакт + + + + TOX ID: + TOX ID: + + + + Message: + Сообщение: + + + + Form + + + Send request + Отправить запрос + + + + IPv6 + IPv6 + + + + UDP + UDP + + + + Proxy + Прокси + + + + IP: + IP: + + + + Port: + Порт: + + + + Online contacts + Контакты в сети + + + + MainWindow + + + Profile + Профиль + + + + Settings + Настройки + + + + About + О программе + + + + Add contact + Добавить контакт + + + + Privacy + Приватность + + + + Interface + Интерфейс + + + + Notifications + Уведомления + + + + Network + Сеть + + + + About program + О программе + + + + User {} wants to add you to contact list. Message: +{} + Пользователь {} хочет добавить Вас в список контактов. Сообщение: +{} + + + + Friend request + Запрос на добавление в друзья + + + + Toxygen is Tox client written on Python 2.7. Version: + Toxygen - клиент для мессенджера Tox, написанный на Python 2.7. Версия: + + + + Choose file + Выберите файл + + + + Disallow auto accept + Запретить автоматическое получение файлов + + + + Allow auto accept + Разрешить автоматическое получение файлов + + + + Set alias + Изменить псевдоним + + + + Clear history + Очистить историю + + + + Copy public key + Копировать публичный ключ + + + + Remove friend + Удалить друга + + + + NetworkSettings + + + Network settings + Настройки сети + + + + ProfileSettingsForm + + + Export profile + Экспорт профиля + + + + Profile settings + Настройки профиля + + + + Name: + Имя: + + + + Status: + Статус: + + + + TOX ID: + TOX ID: + + + + Copy TOX ID + Копировать TOX ID + + + + Language: + Язык: + + + + New avatar + Новый аватар + + + + Reset avatar + Сбросить аватар + + + + interfaceForm + + + Interface settings + Настройки интерфейса + + + + Theme: + Тема: + + + + Language: + Язык: + + + + login + + + Log in + Вход + + + + Create + Создать + + + + Profile name: + Имя профиля: + + + + Load profile + Загрузить профиль + + + + Use as default + По умолчанию + + + + Load existing profile + Загрузить профиль + + + + Create new profile + Создать новый профиль + + + + toxygen + toxygen + + + + Looks like other instance of Toxygen uses this profile! Continue? + Похоже, что этот профиль используется другим экземпляром Toxygen! Продолжить? + + + + notificationsForm + + + Notification settings + Настройки уведомлений + + + + Enable notifications + Включить уведомления + + + + Enable call's sound + Включить звук звонков + + + + Enable sound notifications + Включить звуковые уведомления + + + + + privacySettings + + + Privacy settings + Настройки приватности + + + + Save chat history + Сохранять историю переписки + + + + Allow file auto accept + Разрешить автополучение файлов + + + + Send typing notifications + Посылать уведомления о наборе текста + + + + Auto accept default path: + Путь автоприема файлов: + + + + Change + Изменить + + + + tray + + + Open Toxygen + Открыть Toxygen + + + + Exit + Выход + + +