diff --git a/toxygen/app.py b/toxygen/app.py index 423ae5f..17c760e 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -23,6 +23,8 @@ from contacts.friend_factory import FriendFactory from contacts.contacts_manager import ContactsManager from av.calls_manager import CallsManager from history.database import Database +from ui.widgets_factory import WidgetsFactory +from smileys.smileys import SmileyLoader class App: @@ -148,16 +150,20 @@ class App: return self._tox def create_dependencies(self): - self._ms = MainWindow(self._settings, self._tox, self.reset, self._tray) + self._ms = MainWindow(self._settings, self._tox, self._tray) db = Database(self._path.replace('.tox', '.db'), self._toxes) self._friend_factory = FriendFactory(self._profile_manager, self._settings, self._tox, db) self._contacts_provider = ContactProvider(self._tox, self._friend_factory) + profile = Profile(self._profile_manager, self._tox, self._ms, self._file_transfer_handler) + self._smiley_loader = SmileyLoader(self._settings) + widgets_factory = WidgetsFactory(self._settings, profile, self._contacts_manager, self._file_transfer_handler, + self._smiley_loader, self._plugin_loader) self._contacts_manager = ContactsManager(self._tox, self._settings, self._ms, self._profile_manager, self._contacts_provider, db) self._calls_manager = CallsManager(self._tox.AV, self._settings) self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider) - profile = Profile(self._profile_manager, self._tox, self._ms, self._file_transfer_handler) self._ms.profile = profile + self._ms.set_widget_factory(widgets_factory) self._ms.show() self._tray = tray.init_tray(profile, self._settings, self._ms) diff --git a/toxygen/bootstrap/bootstrap.py b/toxygen/bootstrap/bootstrap.py index aa6f863..ccce1c7 100644 --- a/toxygen/bootstrap/bootstrap.py +++ b/toxygen/bootstrap/bootstrap.py @@ -1,11 +1,13 @@ import random import urllib.request -from util.util import log, curr_directory -from user_data import settings +from util.util import log, curr_directory, join_path from PyQt5 import QtNetwork, QtCore import json +DEFAULT_NODES_COUNT = 4 + + class Node: def __init__(self, node): @@ -21,11 +23,18 @@ class Node: return bytes(self._ip, 'utf-8'), self._port, self._tox_key -def generate_nodes(): - with open(curr_directory() + '/nodes.json', 'rt') as fl: +def _get_nodes_path(): + return join_path(curr_directory(__file__), 'nodes.json') + + +def generate_nodes(nodes_count=DEFAULT_NODES_COUNT): + with open(_get_nodes_path(), 'rt') as fl: json_nodes = json.loads(fl.read())['nodes'] nodes = map(lambda json_node: Node(json_node), json_nodes) - sorted_nodes = sorted(nodes, key=lambda x: x.priority)[-4:] + nodes = filter(lambda n: n.priority > 0, nodes) + sorted_nodes = sorted(nodes, key=lambda x: x.priority) + if nodes_count is not None: + sorted_nodes = sorted_nodes[-DEFAULT_NODES_COUNT:] for node in sorted_nodes: yield node.get_data() @@ -34,7 +43,7 @@ def save_nodes(nodes): if not nodes: return print('Saving nodes...') - with open(curr_directory() + '/nodes.json', 'wb') as fl: + with open(_get_nodes_path(), 'wb') as fl: fl.write(nodes) diff --git a/toxygen/contacts/profile.py b/toxygen/contacts/profile.py index 70a6f7e..642cc04 100644 --- a/toxygen/contacts/profile.py +++ b/toxygen/contacts/profile.py @@ -1,21 +1,12 @@ -from ui.list_items import * -from PyQt5 import QtWidgets from contacts.friend import * from user_data.settings import * from wrapper.toxcore_enums_and_consts import * -from util.util import log, curr_directory -from network.tox_dns import tox_dns +from util.util import log from history.database import * from file_transfers.file_transfers import * import time -from av import calls -import plugin_support from contacts import basecontact -from ui import items_factory, av_widgets -import cv2 -import threading from contacts.group_chat import * -import re import util.ui as util_ui diff --git a/toxygen/middleware/callbacks.py b/toxygen/middleware/callbacks.py index 153f341..e139883 100644 --- a/toxygen/middleware/callbacks.py +++ b/toxygen/middleware/callbacks.py @@ -40,62 +40,62 @@ def self_connection_status(tox, profile): def friend_status(profile, settings): - def wrapped(tox, friend_num, new_status, user_data): + def wrapped(tox, friend_number, new_status, user_data): """ Check friend's status (none, busy, away) """ - print("Friend's #{} status changed!".format(friend_num)) - friend = profile.get_friend_by_number(friend_num) + print("Friend's #{} status changed!".format(friend_number)) + friend = profile.get_friend_by_number(friend_number) if friend.status is None and settings['sound_notifications'] and profile.status != TOX_USER_STATUS['BUSY']: sound_notification(SOUND_NOTIFICATION['FRIEND_CONNECTION_STATUS']) invoke_in_main_thread(friend.set_status, new_status) - invoke_in_main_thread(QtCore.QTimer.singleShot, 5000, lambda: profile.send_files(friend_num)) + invoke_in_main_thread(QtCore.QTimer.singleShot, 5000, lambda: profile.send_files(friend_number)) invoke_in_main_thread(profile.update_filtration) return wrapped def friend_connection_status(profile, settings, plugin_loader): - def wrapped(tox, friend_num, new_status, user_data): + def wrapped(tox, friend_number, new_status, user_data): """ Check friend's connection status (offline, udp, tcp) """ - print("Friend #{} connection status: {}".format(friend_num, new_status)) - friend = profile.get_friend_by_number(friend_num) + print("Friend #{} connection status: {}".format(friend_number, new_status)) + friend = profile.get_friend_by_number(friend_number) if new_status == TOX_CONNECTION['NONE']: - invoke_in_main_thread(profile.friend_exit, friend_num) + invoke_in_main_thread(profile.friend_exit, friend_number) invoke_in_main_thread(profile.update_filtration) if settings['sound_notifications'] and profile.status != TOX_USER_STATUS['BUSY']: sound_notification(SOUND_NOTIFICATION['FRIEND_CONNECTION_STATUS']) elif friend.status is None: - invoke_in_main_thread(profile.send_avatar, friend_num) - invoke_in_main_thread(plugin_loader.friend_online, friend_num) + invoke_in_main_thread(profile.send_avatar, friend_number) + invoke_in_main_thread(plugin_loader.friend_online, friend_number) return wrapped def friend_name(profile): - def wrapped(tox, friend_num, name, size, user_data): + def wrapped(tox, friend_number, name, size, user_data): """ Friend changed his name """ - print('New name friend #' + str(friend_num)) - invoke_in_main_thread(profile.new_name, friend_num, name) + print('New name friend #' + str(friend_number)) + invoke_in_main_thread(profile.new_name, friend_number, name) return wrapped def friend_status_message(profile): - def wrapped(tox, friend_num, status_message, size, user_data): + def wrapped(tox, friend_number, status_message, size, user_data): """ :return: function for callback friend_status_message. It updates friend's status message and calls window repaint """ - friend = profile.get_friend_by_number(friend_num) + friend = profile.get_friend_by_number(friend_number) invoke_in_main_thread(friend.set_status_message, status_message) - print('User #{} has new status'.format(friend_num)) - invoke_in_main_thread(profile.send_messages, friend_num) - if profile.get_active_number() == friend_num: + print('User #{} has new status'.format(friend_number)) + invoke_in_main_thread(profile.send_messages, friend_number) + if profile.get_active_number() == friend_number: invoke_in_main_thread(profile.set_active) return wrapped diff --git a/toxygen/middleware/threads.py b/toxygen/middleware/threads.py index 5d722f0..e654a66 100644 --- a/toxygen/middleware/threads.py +++ b/toxygen/middleware/threads.py @@ -42,7 +42,7 @@ class InitThread(BaseThread): time.sleep(1) while not self._tox.self_get_connection_status(): try: - for data in generate_nodes(): + for data in generate_nodes(None): if self._stop_thread: return self._tox.bootstrap(*data) @@ -137,4 +137,3 @@ _invoker = Invoker() def invoke_in_main_thread(fn, *args, **kwargs): QtCore.QCoreApplication.postEvent(_invoker, InvokeEvent(fn, *args, **kwargs)) - diff --git a/toxygen/smileys/smileys.py b/toxygen/smileys/smileys.py index c20d1a7..fc40a69 100644 --- a/toxygen/smileys/smileys.py +++ b/toxygen/smileys/smileys.py @@ -48,8 +48,8 @@ class SmileyLoader: return util.join_path(util.get_smileys_directory(), self._curr_pack) if self._curr_pack is not None else None @staticmethod - def get_packs_list(self): - d = util.curr_directory() + '/smileys/' + def get_packs_list(): + d = util.get_smileys_directory() return [x[1] for x in os.walk(d)][0] def get_smileys(self): diff --git a/toxygen/ui/main_screen.py b/toxygen/ui/main_screen.py index 73f4d4e..41c7c38 100644 --- a/toxygen/ui/main_screen.py +++ b/toxygen/ui/main_screen.py @@ -2,27 +2,32 @@ from ui.menu import * from contacts.profile import * from ui.list_items import * from ui.widgets import MultilineEdit, ComboBox -import plugin_support from ui.main_screen_widgets import * -from user_data import toxes, settings import util.util as util import util.ui as util_ui class MainWindow(QtWidgets.QMainWindow): - def __init__(self, settings, tox, reset, tray): + def __init__(self, settings, tox, tray): super().__init__() self._settings = settings - self.reset = reset self.tray = tray + self._widget_factory = None + self._modal_window = None self.setAcceptDrops(True) self.initUI(tox) self._saved = False - if settings['show_welcome_screen']: - self.ws = WelcomeScreen() self.profile = None + def set_widget_factory(self, widget_factory): + self._widget_factory = widget_factory + + def show(self): + super().show() + if self._settings['show_welcome_screen']: + self._modal_window = self._widget_factory.create_welcome_window() + def setup_menu(self, window): self.menubar = QtWidgets.QMenuBar(window) self.menubar.setObjectName("menubar") @@ -366,7 +371,7 @@ class MainWindow(QtWidgets.QMainWindow): self._settings['width'] = self.width() self._settings['height'] = self.height() self._settings.save() - QtWidgets.QApplication.closeAllWindows() + util_ui.close_all_windows() event.accept() elif QtWidgets.QSystemTrayIcon.isSystemTrayAvailable(): event.ignore() @@ -407,7 +412,7 @@ class MainWindow(QtWidgets.QMainWindow): elif event.key() == QtCore.Qt.Key_F and event.modifiers() & QtCore.Qt.ControlModifier: self.show_search_field() else: - super(MainWindow, self).keyPressEvent(event) + super().keyPressEvent(event) # ----------------------------------------------------------------------------------------------------------------- # Functions which called when user click in menu @@ -420,81 +425,66 @@ class MainWindow(QtWidgets.QMainWindow): util_ui.message_box(text, title) def network_settings(self): - self.n_s = NetworkSettings(self.reset) - self.n_s.show() + self._modal_window = self._widget_factory.create_network_settings_window() + self._modal_window.show() def plugins_menu(self): - self.p_s = PluginsSettings() - self.p_s.show() + self._modal_window = self._widget_factory.create_plugins_settings_window() + self._modal_window.show() def add_contact(self, link=''): - self.a_c = AddContact(link or '') - self.a_c.show() + self._modal_window = self._widget_factory.create_add_contact_window(link or '') + self._modal_window.show() def create_gc(self): self.profile.create_group_chat() def profile_settings(self, *args): - self.p_s = ProfileSettings() - self.p_s.show() + self._modal_window = self._widget_factory.create_profile_settings_window() + self._modal_window.show() def privacy_settings(self): - self.priv_s = PrivacySettings() - self.priv_s.show() + self._modal_window = self._widget_factory.create_privacy_settings_window() + self._modal_window.show() def notification_settings(self): - self.notif_s = NotificationsSettings() - self.notif_s.show() + self._modal_window = self._widget_factory.create_notification_settings_window() + self._modal_window.show() def interface_settings(self): - self.int_s = InterfaceSettings() - self.int_s.show() + self._modal_window = self._widget_factory.create_interface_settings_window() + self._modal_window.show() def audio_settings(self): - self.audio_s = AudioSettings() - self.audio_s.show() + self._modal_window = self._widget_factory.create_audio_settings_window() + self._modal_window.show() def video_settings(self): - self.video_s = VideoSettings() - self.video_s.show() + self._modal_window = self._widget_factory.create_video_settings_window() + self._modal_window.show() def update_settings(self): - self.update_s = UpdateSettings() - self.update_s.show() + self._modal_window = self._widget_factory.create_update_settings_window() + self._modal_window.show() def reload_plugins(self): - plugin_loader = plugin_support.PluginLoader.get_instance() - if plugin_loader is not None: - plugin_loader.reload() + if self._plugin_loader is not None: + self._plugin_loader.reload() def import_plugin(self): - import util - directory = QtWidgets.QFileDialog.getExistingDirectory(self, - util_ui.tr('Choose folder with plugin'), - util.curr_directory(), - QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) + directory = util_ui.directory_dialog(util_ui.tr('Choose folder with plugin')) if directory: src = directory + '/' - dest = curr_directory() + '/plugins/' + dest = util.get_plugins_directory() util.copy(src, dest) - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle( - util_ui.tr("Restart Toxygen")) - msgBox.setText( - util_ui.tr('Plugin will be loaded after restart')) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Plugin will be loaded after restart'), util_ui.tr("Restart Toxygen")) def lock_app(self): - if toxes.ToxES.get_instance().has_password(): - Settings.get_instance().locked = True + if self._toxes.has_password(): + self._settings.locked = True self.hide() else: - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle( - util_ui.tr("Cannot lock app")) - msgBox.setText( - util_ui.tr('Error. Profile password is not set.')) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Error. Profile password is not set.'), util_ui.tr("Cannot lock app")) def show_menu(self): if not hasattr(self, 'menu'): @@ -516,8 +506,8 @@ class MainWindow(QtWidgets.QMainWindow): def send_file(self): self.menu.hide() if self.profile.active_friend + 1and self.profile.is_active_a_friend(): - choose = util_ui.tr('Choose file') - name = QtWidgets.QFileDialog.getOpenFileName(self, choose, options=QtWidgets.QFileDialog.DontUseNativeDialog) + caption = util_ui.tr('Choose file') + name = util_ui.file_dialog(caption) if name[0]: self.profile.send_file(name[0]) @@ -533,7 +523,7 @@ class MainWindow(QtWidgets.QMainWindow): self.menu.hide() if self.profile.active_friend + 1: self.smiley = SmileyWindow(self) - self.smiley.setGeometry(QtCore.QRect(self.x() if Settings.get_instance()['mirror_mode'] else 270 + self.x(), + self.smiley.setGeometry(QtCore.QRect(self.x() if self._settings['mirror_mode'] else 270 + self.x(), self.y() + self.height() - 200, self.smiley.width(), self.smiley.height())) @@ -543,7 +533,7 @@ class MainWindow(QtWidgets.QMainWindow): self.menu.hide() if self.profile.active_friend + 1 and self.profile.is_active_a_friend(): self.sticker = StickerWindow(self) - self.sticker.setGeometry(QtCore.QRect(self.x() if Settings.get_instance()['mirror_mode'] else 270 + self.x(), + self.sticker.setGeometry(QtCore.QRect(self.x() if self._settings['mirror_mode'] else 270 + self.x(), self.y() + self.height() - 200, self.sticker.width(), self.sticker.height())) @@ -580,7 +570,6 @@ class MainWindow(QtWidgets.QMainWindow): friend = Profile.get_instance().get_friend(num) if friend is None: return - settings = Settings.get_instance() allowed = friend.tox_id in settings['auto_accept_from_friends'] auto = util_ui.tr('Disallow auto accept') if allowed else util_ui.tr('Allow auto accept') if item is not None: @@ -614,9 +603,8 @@ class MainWindow(QtWidgets.QMainWindow): item = invite_menu.addAction(name) item.triggered.connect(lambda: self.invite_friend_to_gc(num, number)) - plugins_loader = plugin_support.PluginLoader.get_instance() - if plugins_loader is not None: - submenu = plugins_loader.get_menu(self.listMenu, num) + if self._plugins_loader is not None: + submenu = self._plugins_loader.get_menu(self.listMenu, num) if len(submenu): plug = self.listMenu.addMenu(util_ui.tr('Plugins')) plug.addActions(submenu) @@ -640,29 +628,23 @@ class MainWindow(QtWidgets.QMainWindow): self.listMenu.show() def show_note(self, friend): - s = Settings.get_instance() - note = s['notes'][friend.tox_id] if friend.tox_id in s['notes'] else '' + note = self._settings['notes'][friend.tox_id] if friend.tox_id in s['notes'] else '' user = util_ui.tr('Notes about user') user = '{} {}'.format(user, friend.name) def save_note(text): - if friend.tox_id in s['notes']: - del s['notes'][friend.tox_id] + if friend.tox_id in self._settings['notes']: + del self._settings['notes'][friend.tox_id] if text: - s['notes'][friend.tox_id] = text - s.save() + self._settings['notes'][friend.tox_id] = text + self._settings.save() self.note = MultilineEdit(user, note, save_note) self.note.show() def export_history(self, num, as_text=True): s = self.profile.export_history(num, as_text) extension = 'txt' if as_text else 'html' - file_name, _ = QtWidgets.QFileDialog.getSaveFileName(None, - QtWidgets.QApplication.translate("MainWindow", - 'Choose file name'), - curr_directory(), - filter=extension, - options=QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) + file_name, _ = util_ui.save_file_dialog(util_ui.tr('Choose file name'), extension) if file_name: if not file_name.endswith('.' + extension): @@ -703,13 +685,12 @@ class MainWindow(QtWidgets.QMainWindow): self.profile.set_title(num) def auto_accept(self, num, value): - settings = Settings.get_instance() tox_id = self.profile.friend_public_key(num) if value: - settings['auto_accept_from_friends'].append(tox_id) + self._settings['auto_accept_from_friends'].append(tox_id) else: - settings['auto_accept_from_friends'].remove(tox_id) - settings.save() + self._settings['auto_accept_from_friends'].remove(tox_id) + self._settings.save() def invite_friend_to_gc(self, friend_number, group_number): self.profile.invite_friend(friend_number, group_number) diff --git a/toxygen/ui/menu.py b/toxygen/ui/menu.py index c509359..9369fdd 100644 --- a/toxygen/ui/menu.py +++ b/toxygen/ui/menu.py @@ -5,8 +5,7 @@ from util.util import curr_directory, copy from ui.widgets import CenteredWidget, DataLabel, LineEdit, RubberBandWindow import pyaudio from user_data import toxes -import plugin_support -import updater +import updater.updater as updater import util.ui as util_ui @@ -228,8 +227,7 @@ class ProfileSettings(CenteredWidget): def copy(self): clipboard = QtWidgets.QApplication.clipboard() - profile = Profile.get_instance() - clipboard.setText(profile.tox_id) + clipboard.setText(self._profile.tox_id) pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png') icon = QtGui.QIcon(pixmap) self.copyId.setIcon(icon) @@ -237,8 +235,7 @@ class ProfileSettings(CenteredWidget): def copy_public_key(self): clipboard = QtWidgets.QApplication.clipboard() - profile = Profile.get_instance() - clipboard.setText(profile.tox_id[:64]) + clipboard.setText(self._profile.tox_id[:64]) pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png') icon = QtGui.QIcon(pixmap) self.copy_pk.setIcon(icon) @@ -252,8 +249,7 @@ class ProfileSettings(CenteredWidget): def set_avatar(self): choose = util_ui.tr("Choose avatar") - name = QtWidgets.QFileDialog.getOpenFileName(self, choose, None, 'Images (*.png)', - options=QtWidgets.QFileDialog.DontUseNativeDialog) + name = util_ui.file_dialog(choose, 'Images (*.png)') if name[0]: bitmap = QtGui.QPixmap(name[0]) bitmap.scaled(QtCore.QSize(128, 128), aspectRatioMode=QtCore.Qt.KeepAspectRatio, @@ -263,24 +259,21 @@ class ProfileSettings(CenteredWidget): buffer = QtCore.QBuffer(byte_array) buffer.open(QtCore.QIODevice.WriteOnly) bitmap.save(buffer, 'PNG') - Profile.get_instance().set_avatar(bytes(byte_array.data())) + self._profile.set_avatar(bytes(byte_array.data())) def export_profile(self): directory = util_ui.directory_dialog() + '/' if directory != '/': reply = util_ui.question(util_ui.tr('Do you want to move your profile to this location?'), util_ui.tr('Use new path')) - settings = Settings.get_instance() settings.export(directory) - profile = Profile.get_instance() - profile.export_db(directory) + self._profile.export_db(directory) ProfileManager.get_instance().export_profile(directory, reply) def closeEvent(self, event): - profile = Profile.get_instance() - profile.set_name(self.nick.text()) - profile.set_status_message(self.status_message.text().encode('utf-8')) - profile.set_status(self.status.currentIndex()) + self._profile.set_name(self.nick.text()) + self._profile.set_status_message(self.status_message.text().encode('utf-8')) + self._profile.set_status(self.status.currentIndex()) class NetworkSettings(CenteredWidget): @@ -367,7 +360,7 @@ class NetworkSettings(CenteredWidget): self._settings['download_nodes_list'] = self.nodes.isChecked() self._settings.save() # recreate tox instance - Profile.get_instance().reset(self.reset) + self._profile.reset() self.close() except Exception as ex: log('Exception in restart: ' + str(ex)) @@ -376,8 +369,13 @@ class NetworkSettings(CenteredWidget): class PrivacySettings(CenteredWidget): """Privacy settings form: history, typing notifications""" - def __init__(self): + def __init__(self, contacts_manager, settings): + """ + :type contacts_manager: ContactsManager + """ super().__init__() + self._contacts_manager = contacts_manager + self._settings = settings self.initUI() self.center() @@ -404,15 +402,14 @@ class PrivacySettings(CenteredWidget): self.path.setGeometry(QtCore.QRect(10, 265, 350, 45)) self.change_path = QtWidgets.QPushButton(self) self.change_path.setGeometry(QtCore.QRect(10, 320, 350, 30)) - settings = Settings.get_instance() - self.typingNotifications.setChecked(settings['typing_notifications']) - self.fileautoaccept.setChecked(settings['allow_auto_accept']) - self.saveHistory.setChecked(settings['save_history']) - self.inlines.setChecked(settings['allow_inline']) - self.saveUnsentOnly.setChecked(settings['save_unsent_only']) - self.saveUnsentOnly.setEnabled(settings['save_history']) + self.typingNotifications.setChecked(self._settings['typing_notifications']) + self.fileautoaccept.setChecked(self._settings['allow_auto_accept']) + self.saveHistory.setChecked(self._settings['save_history']) + self.inlines.setChecked(self._settings['allow_inline']) + self.saveUnsentOnly.setChecked(self._settings['save_unsent_only']) + self.saveUnsentOnly.setEnabled(self._settings['save_history']) self.saveHistory.stateChanged.connect(self.update) - self.path.setPlainText(settings['auto_accept_path'] or curr_directory()) + self.path.setPlainText(self._settings['auto_accept_path'] or curr_directory()) self.change_path.clicked.connect(self.new_path) self.block_user_label = QtWidgets.QLabel(self) self.block_user_label.setGeometry(QtCore.QRect(10, 360, 350, 30)) @@ -420,12 +417,12 @@ class PrivacySettings(CenteredWidget): self.block_id.setGeometry(QtCore.QRect(10, 390, 350, 30)) self.block = QtWidgets.QPushButton(self) self.block.setGeometry(QtCore.QRect(10, 430, 350, 30)) - self.block.clicked.connect(lambda: Profile.get_instance().block_user(self.block_id.toPlainText()) or self.close()) + self.block.clicked.connect(lambda: self._contacts_manager.block_user(self.block_id.toPlainText()) or self.close()) self.blocked_users_label = QtWidgets.QLabel(self) self.blocked_users_label.setGeometry(QtCore.QRect(10, 470, 350, 30)) self.comboBox = QtWidgets.QComboBox(self) self.comboBox.setGeometry(QtCore.QRect(10, 500, 350, 30)) - self.comboBox.addItems(settings['blocked']) + self.comboBox.addItems(self._settings['blocked']) self.unblock = QtWidgets.QPushButton(self) self.unblock.setGeometry(QtCore.QRect(10, 540, 350, 30)) self.unblock.clicked.connect(lambda: self.unblock_user()) @@ -433,18 +430,18 @@ class PrivacySettings(CenteredWidget): QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate("privacySettings", "Privacy settings")) - self.saveHistory.setText(QtWidgets.QApplication.translate("privacySettings", "Save chat history")) - self.fileautoaccept.setText(QtWidgets.QApplication.translate("privacySettings", "Allow file auto accept")) - self.typingNotifications.setText(QtWidgets.QApplication.translate("privacySettings", "Send typing notifications")) - self.auto_path.setText(QtWidgets.QApplication.translate("privacySettings", "Auto accept default path:")) - self.change_path.setText(QtWidgets.QApplication.translate("privacySettings", "Change")) - self.inlines.setText(QtWidgets.QApplication.translate("privacySettings", "Allow inlines")) - self.block_user_label.setText(QtWidgets.QApplication.translate("privacySettings", "Block by public key:")) - self.blocked_users_label.setText(QtWidgets.QApplication.translate("privacySettings", "Blocked users:")) - self.unblock.setText(QtWidgets.QApplication.translate("privacySettings", "Unblock")) - self.block.setText(QtWidgets.QApplication.translate("privacySettings", "Block user")) - self.saveUnsentOnly.setText(QtWidgets.QApplication.translate("privacySettings", "Save unsent messages only")) + self.setWindowTitle(util_ui.tr("Privacy settings")) + self.saveHistory.setText(util_ui.tr("Save chat history")) + self.fileautoaccept.setText(util_ui.tr("Allow file auto accept")) + self.typingNotifications.setText(util_ui.tr("Send typing notifications")) + self.auto_path.setText(util_ui.tr("Auto accept default path:")) + self.change_path.setText(util_ui.tr("Change")) + self.inlines.setText(util_ui.tr("Allow inlines")) + self.block_user_label.setText(util_ui.tr("Block by public key:")) + self.blocked_users_label.setText(util_ui.tr("Blocked users:")) + self.unblock.setText(util_ui.tr("Unblock")) + self.block.setText(util_ui.tr("Block user")) + self.saveUnsentOnly.setText(util_ui.tr("Save unsent messages only")) def update(self, new_state): self.saveUnsentOnly.setEnabled(new_state) @@ -454,58 +451,48 @@ class PrivacySettings(CenteredWidget): def unblock_user(self): if not self.comboBox.count(): return - title = QtWidgets.QApplication.translate("privacySettings", "Add to friend list") - info = QtWidgets.QApplication.translate("privacySettings", "Do you want to add this user to friend list?") - reply = QtWidgets.QMessageBox.question(None, title, info, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) - Profile.get_instance().unblock_user(self.comboBox.currentText(), reply == QtWidgets.QMessageBox.Yes) + title = util_ui.tr("Add to friend list") + info = util_ui.tr("Do you want to add this user to friend list?") + reply = util_ui.question(info, title) + self._contacts_manager.unblock_user(self.comboBox.currentText(), reply) self.close() def closeEvent(self, event): - settings = Settings.get_instance() - settings['typing_notifications'] = self.typingNotifications.isChecked() - settings['allow_auto_accept'] = self.fileautoaccept.isChecked() + self._settings['typing_notifications'] = self.typingNotifications.isChecked() + self._settings['allow_auto_accept'] = self.fileautoaccept.isChecked() + text = util_ui.tr('History will be cleaned! Continue?') + title = util_ui.tr('Chat history') - if settings['save_history'] and not self.saveHistory.isChecked(): # clear history - reply = QtWidgets.QMessageBox.question(None, - QtWidgets.QApplication.translate("privacySettings", - 'Chat history'), - QtWidgets.QApplication.translate("privacySettings", - 'History will be cleaned! Continue?'), - QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.No) - if reply == QtWidgets.QMessageBox.Yes: - Profile.get_instance().clear_history() - settings['save_history'] = self.saveHistory.isChecked() + if self._settings['save_history'] and not self.saveHistory.isChecked(): # clear history + reply = util_ui.question(text, title) + if reply: + self._history_loader.clear_history() + self._settings['save_history'] = self.saveHistory.isChecked() else: - settings['save_history'] = self.saveHistory.isChecked() - if self.saveUnsentOnly.isChecked() and not settings['save_unsent_only']: - reply = QtWidgets.QMessageBox.question(None, - QtWidgets.QApplication.translate("privacySettings", - 'Chat history'), - QtWidgets.QApplication.translate("privacySettings", - 'History will be cleaned! Continue?'), - QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.No) - if reply == QtWidgets.QMessageBox.Yes: - Profile.get_instance().clear_history(None, True) - settings['save_unsent_only'] = self.saveUnsentOnly.isChecked() + self._settings['save_history'] = self.saveHistory.isChecked() + if self.saveUnsentOnly.isChecked() and not self._settings['save_unsent_only']: + reply = util_ui.question(text, title) + if reply: + self._history_loader.clear_history(None, True) + self._settings['save_unsent_only'] = self.saveUnsentOnly.isChecked() else: - settings['save_unsent_only'] = self.saveUnsentOnly.isChecked() - settings['auto_accept_path'] = self.path.toPlainText() - settings['allow_inline'] = self.inlines.isChecked() - settings.save() + self._settings['save_unsent_only'] = self.saveUnsentOnly.isChecked() + self._settings['auto_accept_path'] = self.path.toPlainText() + self._settings['allow_inline'] = self.inlines.isChecked() + self._settings.save() def new_path(self): - directory = QtWidgets.QFileDialog.getExistingDirectory(options=QtWidgets.QFileDialog.DontUseNativeDialog) + '/' - if directory != '/': + directory = util_ui.directory_dialog() + if directory: self.path.setPlainText(directory) class NotificationsSettings(CenteredWidget): """Notifications settings form""" - def __init__(self): - super(NotificationsSettings, self).__init__() + def __init__(self, setttings): + super().__init__() + self._settings = setttings self.initUI() self.center() @@ -523,40 +510,40 @@ class NotificationsSettings(CenteredWidget): self.groupNotifications = QtWidgets.QCheckBox(self) self.groupNotifications.setGeometry(QtCore.QRect(10, 120, 340, 18)) font = QtGui.QFont() - s = Settings.get_instance() - font.setFamily(s['font']) + font.setFamily(self._settings['font']) font.setPointSize(12) self.callsSound.setFont(font) self.soundNotifications.setFont(font) self.enableNotifications.setFont(font) self.groupNotifications.setFont(font) - self.enableNotifications.setChecked(s['notifications']) - self.soundNotifications.setChecked(s['sound_notifications']) - self.groupNotifications.setChecked(s['group_notifications']) - self.callsSound.setChecked(s['calls_sound']) + self.enableNotifications.setChecked(self._settings['notifications']) + self.soundNotifications.setChecked(self._settings['sound_notifications']) + self.groupNotifications.setChecked(self._settings['group_notifications']) + self.callsSound.setChecked(self._settings['calls_sound']) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate("notificationsForm", "Notification settings")) - self.enableNotifications.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable notifications")) - self.groupNotifications.setText(QtWidgets.QApplication.translate("notificationsForm", "Notify about all messages in groups")) - self.callsSound.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable call\'s sound")) - self.soundNotifications.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable sound notifications")) + self.setWindowTitle(util_ui.tr("Notification settings")) + self.enableNotifications.setText(util_ui.tr("Enable notifications")) + self.groupNotifications.setText(util_ui.tr("Notify about all messages in groups")) + self.callsSound.setText(util_ui.tr("Enable call\'s sound")) + self.soundNotifications.setText(util_ui.tr("Enable sound notifications")) def closeEvent(self, *args, **kwargs): - settings = Settings.get_instance() - settings['notifications'] = self.enableNotifications.isChecked() - settings['sound_notifications'] = self.soundNotifications.isChecked() - settings['group_notifications'] = self.groupNotifications.isChecked() - settings['calls_sound'] = self.callsSound.isChecked() - settings.save() + self._settings['notifications'] = self.enableNotifications.isChecked() + self._settings['sound_notifications'] = self.soundNotifications.isChecked() + self._settings['group_notifications'] = self.groupNotifications.isChecked() + self._settings['calls_sound'] = self.callsSound.isChecked() + self._settings.save() class InterfaceSettings(CenteredWidget): """Interface settings form""" - def __init__(self): - super(InterfaceSettings, self).__init__() + def __init__(self, settings, smiley_loader): + super().__init__() + self._settings = settings + self._smiley_loader = smiley_loader self.initUI() self.center() @@ -566,18 +553,17 @@ class InterfaceSettings(CenteredWidget): self.setMaximumSize(QtCore.QSize(400, 650)) self.label = QtWidgets.QLabel(self) self.label.setGeometry(QtCore.QRect(30, 10, 370, 20)) - settings = Settings.get_instance() font = QtGui.QFont() font.setPointSize(14) font.setBold(True) - font.setFamily(settings['font']) + font.setFamily(self._settings['font']) self.label.setFont(font) self.themeSelect = QtWidgets.QComboBox(self) self.themeSelect.setGeometry(QtCore.QRect(30, 40, 120, 30)) - self.themeSelect.addItems(list(settings.built_in_themes().keys())) - theme = settings['theme'] - if theme in settings.built_in_themes().keys(): - index = list(settings.built_in_themes().keys()).index(theme) + self.themeSelect.addItems(list(self._settings.built_in_themes().keys())) + theme = self._settings['theme'] + if theme in self._settings.built_in_themes().keys(): + index = list(self._settings.built_in_themes().keys()).index(theme) else: index = 0 self.themeSelect.setCurrentIndex(index) @@ -586,28 +572,27 @@ class InterfaceSettings(CenteredWidget): supported = sorted(Settings.supported_languages().keys(), reverse=True) for key in supported: self.lang_choose.insertItem(0, key) - if settings['language'] == key: + if self._settings['language'] == key: self.lang_choose.setCurrentIndex(0) self.lang = QtWidgets.QLabel(self) self.lang.setGeometry(QtCore.QRect(30, 80, 370, 20)) self.lang.setFont(font) self.mirror_mode = QtWidgets.QCheckBox(self) self.mirror_mode.setGeometry(QtCore.QRect(30, 160, 370, 20)) - self.mirror_mode.setChecked(settings['mirror_mode']) + self.mirror_mode.setChecked(self._settings['mirror_mode']) self.smileys = QtWidgets.QCheckBox(self) self.smileys.setGeometry(QtCore.QRect(30, 190, 120, 20)) - self.smileys.setChecked(settings['smileys']) + self.smileys.setChecked(self._settings['smileys']) self.smiley_pack_label = QtWidgets.QLabel(self) self.smiley_pack_label.setGeometry(QtCore.QRect(30, 230, 370, 20)) self.smiley_pack_label.setFont(font) self.smiley_pack = QtWidgets.QComboBox(self) self.smiley_pack.setGeometry(QtCore.QRect(30, 260, 160, 30)) - sm = smileys.SmileyLoader.get_instance() - self.smiley_pack.addItems(sm.get_packs_list()) + self.smiley_pack.addItems(self._smiley_loader.get_packs_list()) try: - ind = sm.get_packs_list().index(settings['smiley_pack']) + ind = self._smiley_loader.get_packs_list().index(self._settings['smiley_pack']) except: - ind = sm.get_packs_list().index('default') + ind = self._smiley_loader.get_packs_list().index('default') self.smiley_pack.setCurrentIndex(ind) self.messages_font_size_label = QtWidgets.QLabel(self) self.messages_font_size_label.setGeometry(QtCore.QRect(30, 300, 370, 20)) @@ -615,7 +600,7 @@ class InterfaceSettings(CenteredWidget): self.messages_font_size = QtWidgets.QComboBox(self) self.messages_font_size.setGeometry(QtCore.QRect(30, 330, 160, 30)) self.messages_font_size.addItems([str(x) for x in range(10, 25)]) - self.messages_font_size.setCurrentIndex(settings['message_font_size'] - 10) + self.messages_font_size.setCurrentIndex(self._settings['message_font_size'] - 10) self.unread = QtWidgets.QPushButton(self) self.unread.setGeometry(QtCore.QRect(30, 470, 340, 30)) @@ -623,15 +608,15 @@ class InterfaceSettings(CenteredWidget): self.compact_mode = QtWidgets.QCheckBox(self) self.compact_mode.setGeometry(QtCore.QRect(30, 380, 370, 20)) - self.compact_mode.setChecked(settings['compact_mode']) + self.compact_mode.setChecked(self._settings['compact_mode']) self.close_to_tray = QtWidgets.QCheckBox(self) self.close_to_tray.setGeometry(QtCore.QRect(30, 410, 370, 20)) - self.close_to_tray.setChecked(settings['close_to_tray']) + self.close_to_tray.setChecked(self._settings['close_to_tray']) self.show_avatars = QtWidgets.QCheckBox(self) self.show_avatars.setGeometry(QtCore.QRect(30, 440, 370, 20)) - self.show_avatars.setChecked(settings['show_avatars']) + self.show_avatars.setChecked(self._settings['show_avatars']) self.choose_font = QtWidgets.QPushButton(self) self.choose_font.setGeometry(QtCore.QRect(30, 510, 340, 30)) @@ -649,54 +634,43 @@ class InterfaceSettings(CenteredWidget): QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): - self.show_avatars.setText(QtWidgets.QApplication.translate("interfaceForm", "Show avatars in chat")) - self.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", "Interface settings")) - self.label.setText(QtWidgets.QApplication.translate("interfaceForm", "Theme:")) - self.lang.setText(QtWidgets.QApplication.translate("interfaceForm", "Language:")) - self.smileys.setText(QtWidgets.QApplication.translate("interfaceForm", "Smileys")) - self.smiley_pack_label.setText(QtWidgets.QApplication.translate("interfaceForm", "Smiley pack:")) - self.mirror_mode.setText(QtWidgets.QApplication.translate("interfaceForm", "Mirror mode")) - self.messages_font_size_label.setText(QtWidgets.QApplication.translate("interfaceForm", "Messages font size:")) - self.unread.setText(QtWidgets.QApplication.translate("interfaceForm", "Select unread messages notification color")) - self.compact_mode.setText(QtWidgets.QApplication.translate("interfaceForm", "Compact contact list")) - self.import_smileys.setText(QtWidgets.QApplication.translate("interfaceForm", "Import smiley pack")) - self.import_stickers.setText(QtWidgets.QApplication.translate("interfaceForm", "Import sticker pack")) - self.close_to_tray.setText(QtWidgets.QApplication.translate("interfaceForm", "Close to tray")) - self.choose_font.setText(QtWidgets.QApplication.translate("interfaceForm", "Select font")) + self.show_avatars.setText(util_ui.tr("Show avatars in chat")) + self.setWindowTitle(util_ui.tr("Interface settings")) + self.label.setText(util_ui.tr("Theme:")) + self.lang.setText(util_ui.tr("Language:")) + self.smileys.setText(util_ui.tr("Smileys")) + self.smiley_pack_label.setText(util_ui.tr("Smiley pack:")) + self.mirror_mode.setText(util_ui.tr("Mirror mode")) + self.messages_font_size_label.setText(util_ui.tr("Messages font size:")) + self.unread.setText(util_ui.tr("Select unread messages notification color")) + self.compact_mode.setText(util_ui.tr("Compact contact list")) + self.import_smileys.setText(util_ui.tr("Import smiley pack")) + self.import_stickers.setText(util_ui.tr("Import sticker pack")) + self.close_to_tray.setText(util_ui.tr("Close to tray")) + self.choose_font.setText(util_ui.tr("Select font")) def import_st(self): - directory = QtWidgets.QFileDialog.getExistingDirectory(self, - QtWidgets.QApplication.translate("MainWindow", - 'Choose folder with sticker pack'), - curr_directory(), - QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) - + directory = util_ui.directory_dialog(util_ui.tr('Choose folder with sticker pack')) if directory: src = directory + '/' dest = curr_directory() + '/stickers/' + os.path.basename(directory) + '/' copy(src, dest) def import_sm(self): - directory = QtWidgets.QFileDialog.getExistingDirectory(self, - QtWidgets.QApplication.translate("MainWindow", - 'Choose folder with smiley pack'), - curr_directory(), - QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) - + directory = util_ui.directory_dialog(util_ui.tr('Choose folder with smiley pack')) if directory: src = directory + '/' dest = curr_directory() + '/smileys/' + os.path.basename(directory) + '/' copy(src, dest) def new_font(self): - settings = Settings.get_instance() - font, ok = QtWidgets.QFontDialog.getFont(QtGui.QFont(settings['font'], 10), self) + font, ok = QtWidgets.QFontDialog.getFont(QtGui.QFont(self._settings['font'], 10), self) if ok: - settings['font'] = font.family() - settings.save() + self._settings['font'] = font.family() + self._settings.save() msgBox = QtWidgets.QMessageBox() - text = QtWidgets.QApplication.translate("interfaceForm", 'Restart app to apply settings') - msgBox.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", 'Restart required')) + text = util_ui.tr('Restart app to apply settings') + msgBox.setWindowTitle(util_ui.tr('Restart required')) msgBox.setText(text) msgBox.exec_() @@ -747,11 +721,7 @@ class InterfaceSettings(CenteredWidget): Profile.get_instance().update() settings.save() if restart: - msgBox = QtWidgets.QMessageBox() - text = QtWidgets.QApplication.translate("interfaceForm", 'Restart app to apply settings') - msgBox.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", 'Restart required')) - msgBox.setText(text) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Restart app to apply settings'), util_ui.tr('Restart required')) class AudioSettings(CenteredWidget): @@ -759,8 +729,9 @@ class AudioSettings(CenteredWidget): Audio calls settings form """ - def __init__(self): - super(AudioSettings, self).__init__() + def __init__(self, settings): + super().__init__() + self._settings = settings self.initUI() self.retranslateUi() self.center() @@ -774,11 +745,10 @@ class AudioSettings(CenteredWidget): self.in_label.setGeometry(QtCore.QRect(25, 5, 350, 20)) self.out_label = QtWidgets.QLabel(self) self.out_label.setGeometry(QtCore.QRect(25, 65, 350, 20)) - settings = Settings.get_instance() font = QtGui.QFont() font.setPointSize(16) font.setBold(True) - font.setFamily(settings['font']) + font.setFamily(self._settings['font']) self.in_label.setFont(font) self.out_label.setFont(font) self.input = QtWidgets.QComboBox(self) @@ -795,20 +765,19 @@ class AudioSettings(CenteredWidget): if device["maxOutputChannels"]: self.output.addItem(str(device["name"])) self.out_indexes.append(i) - self.input.setCurrentIndex(self.in_indexes.index(settings.audio['input'])) - self.output.setCurrentIndex(self.out_indexes.index(settings.audio['output'])) + self.input.setCurrentIndex(self.in_indexes.index(self._settings.audio['input'])) + self.output.setCurrentIndex(self.out_indexes.index(self._settings.audio['output'])) QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate("audioSettingsForm", "Audio settings")) - self.in_label.setText(QtWidgets.QApplication.translate("audioSettingsForm", "Input device:")) - self.out_label.setText(QtWidgets.QApplication.translate("audioSettingsForm", "Output device:")) + self.setWindowTitle(util_ui.tr("Audio settings")) + self.in_label.setText(util_ui.tr("Input device:")) + self.out_label.setText(util_ui.tr("Output device:")) def closeEvent(self, event): - settings = Settings.get_instance() - settings.audio['input'] = self.in_indexes[self.input.currentIndex()] - settings.audio['output'] = self.out_indexes[self.output.currentIndex()] - settings.save() + self._settings.audio['input'] = self.in_indexes[self.input.currentIndex()] + self._settings.audio['output'] = self.out_indexes[self.output.currentIndex()] + self._settings.save() class DesktopAreaSelectionWindow(RubberBandWindow): @@ -828,8 +797,9 @@ class VideoSettings(CenteredWidget): Audio calls settings form """ - def __init__(self): + def __init__(self, settings): super().__init__() + self._settings = settings self.initUI() self.retranslateUi() self.center() @@ -842,11 +812,10 @@ class VideoSettings(CenteredWidget): self.setMaximumSize(QtCore.QSize(400, 120)) self.in_label = QtWidgets.QLabel(self) self.in_label.setGeometry(QtCore.QRect(25, 5, 350, 20)) - settings = Settings.get_instance() font = QtGui.QFont() font.setPointSize(16) font.setBold(True) - font.setFamily(settings['font']) + font.setFamily(self._settings['font']) self.in_label.setFont(font) self.video_size = QtWidgets.QComboBox(self) self.video_size.setGeometry(QtCore.QRect(25, 70, 350, 30)) @@ -861,7 +830,7 @@ class VideoSettings(CenteredWidget): screen = QtWidgets.QApplication.primaryScreen() size = screen.size() self.frame_max_sizes = [(size.width(), size.height())] - desktop = QtWidgets.QApplication.translate("videoSettingsForm", "Desktop") + desktop = util_ui.tr("Desktop") self.input.addItem(desktop) for i in range(10): v = cv2.VideoCapture(i) @@ -876,15 +845,15 @@ class VideoSettings(CenteredWidget): self.frame_max_sizes.append((width, height)) self.input.addItem('Device #' + str(i)) try: - index = self.devices.index(settings.video['device']) + index = self.devices.index(self._settings.video['device']) self.input.setCurrentIndex(index) except: print('Video devices error!') def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate("videoSettingsForm", "Video settings")) - self.in_label.setText(QtWidgets.QApplication.translate("videoSettingsForm", "Device:")) - self.button.setText(QtWidgets.QApplication.translate("videoSettingsForm", "Select region")) + self.setWindowTitle(util_ui.tr("Video settings")) + self.in_label.setText(util_ui.tr("Device:")) + self.button.setText(util_ui.tr("Select region")) def button_clicked(self): self.desktopAreaSelection = DesktopAreaSelectionWindow(self) @@ -893,24 +862,22 @@ class VideoSettings(CenteredWidget): if self.input.currentIndex() == 0: return try: - settings = Settings.get_instance() - settings.video['device'] = self.devices[self.input.currentIndex()] + self._settings.video['device'] = self.devices[self.input.currentIndex()] text = self.video_size.currentText() - settings.video['width'] = int(text.split(' ')[0]) - settings.video['height'] = int(text.split(' ')[-1]) - settings.save() + self._settings.video['width'] = int(text.split(' ')[0]) + self._settings.video['height'] = int(text.split(' ')[-1]) + self._settings.save() except Exception as ex: print('Saving video settings error: ' + str(ex)) def save(self, x, y, width, height): self.desktopAreaSelection = None - settings = Settings.get_instance() - settings.video['device'] = -1 - settings.video['width'] = width - settings.video['height'] = height - settings.video['x'] = x - settings.video['y'] = y - settings.save() + self._settings.video['device'] = -1 + self._settings.video['width'] = width + self._settings.video['height'] = height + self._settings.video['x'] = x + self._settings.video['y'] = y + self._settings.save() def selectionChanged(self): if self.input.currentIndex() == 0: @@ -940,8 +907,10 @@ class PluginsSettings(CenteredWidget): Plugins settings form """ - def __init__(self): - super(PluginsSettings, self).__init__() + def __init__(self, plugin_loader): + super().__init__() + self._plugin_loader = plugin_loader + self._window = None self.initUI() self.center() self.retranslateUi() @@ -961,32 +930,27 @@ class PluginsSettings(CenteredWidget): self.open = QtWidgets.QPushButton(self) self.open.setGeometry(QtCore.QRect(30, 170, 340, 30)) self.open.clicked.connect(self.open_plugin) - self.pl_loader = plugin_support.PluginLoader.get_instance() self.update_list() self.comboBox.currentIndexChanged.connect(self.show_data) self.show_data() def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate('PluginsForm', "Plugins")) - self.open.setText(QtWidgets.QApplication.translate('PluginsForm', "Open selected plugin")) + self.setWindowTitle(util_ui.tr("Plugins")) + self.open.setText(util_ui.tr("Open selected plugin")) def open_plugin(self): ind = self.comboBox.currentIndex() plugin = self.data[ind] window = self.pl_loader.plugin_window(plugin[-1]) if window is not None: - self.window = window - self.window.show() + self._window = window + self._window.show() else: - msgBox = QtWidgets.QMessageBox() - text = QtWidgets.QApplication.translate("PluginsForm", 'No GUI found for this plugin') - msgBox.setWindowTitle(QtWidgets.QApplication.translate("PluginsForm", 'Error')) - msgBox.setText(text) - msgBox.exec_() + util_ui.message_box(util_ui.tr('No GUI found for this plugin'), util_ui.tr('Error')) def update_list(self): self.comboBox.clear() - data = self.pl_loader.get_plugins_list() + data = self._plugin_loader.get_plugins_list() self.comboBox.addItems(list(map(lambda x: x[0], data))) self.data = data @@ -994,26 +958,26 @@ class PluginsSettings(CenteredWidget): ind = self.comboBox.currentIndex() if len(self.data): plugin = self.data[ind] - descr = plugin[2] or QtWidgets.QApplication.translate("PluginsForm", "No description available") + descr = plugin[2] or util_ui.tr("No description available") self.label.setText(descr) if plugin[1]: - self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Disable plugin")) + self.button.setText(util_ui.tr("Disable plugin")) else: - self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Enable plugin")) + self.button.setText(util_ui.tr("Enable plugin")) else: self.open.setVisible(False) self.button.setVisible(False) - self.label.setText(QtWidgets.QApplication.translate("PluginsForm", "No plugins found")) + self.label.setText(util_ui.tr("No plugins found")) def button_click(self): ind = self.comboBox.currentIndex() plugin = self.data[ind] - self.pl_loader.toggle_plugin(plugin[-1]) + self._plugin_loader.toggle_plugin(plugin[-1]) plugin[1] = not plugin[1] if plugin[1]: - self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Disable plugin")) + self.button.setText(util_ui.tr("Disable plugin")) else: - self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Enable plugin")) + self.button.setText(util_ui.tr("Enable plugin")) class UpdateSettings(CenteredWidget): @@ -1021,8 +985,9 @@ class UpdateSettings(CenteredWidget): Updates settings form """ - def __init__(self): - super(UpdateSettings, self).__init__() + def __init__(self, settings): + super().__init__() + self._settings = settings self.initUI() self.center() @@ -1033,61 +998,44 @@ class UpdateSettings(CenteredWidget): self.setMaximumSize(QtCore.QSize(400, 120)) self.in_label = QtWidgets.QLabel(self) self.in_label.setGeometry(QtCore.QRect(25, 5, 350, 20)) - settings = Settings.get_instance() font = QtGui.QFont() font.setPointSize(16) font.setBold(True) - font.setFamily(settings['font']) + font.setFamily(self._settings['font']) self.in_label.setFont(font) self.autoupdate = QtWidgets.QComboBox(self) self.autoupdate.setGeometry(QtCore.QRect(25, 30, 350, 30)) self.button = QtWidgets.QPushButton(self) self.button.setGeometry(QtCore.QRect(25, 70, 350, 30)) - self.button.setEnabled(settings['update']) + self.button.setEnabled(self._settings['update']) self.button.clicked.connect(self.update_client) self.retranslateUi() - self.autoupdate.setCurrentIndex(settings['update']) + self.autoupdate.setCurrentIndex(self._settings['update']) QtCore.QMetaObject.connectSlotsByName(self) def retranslateUi(self): - self.setWindowTitle(QtWidgets.QApplication.translate("updateSettingsForm", "Update settings")) - self.in_label.setText(QtWidgets.QApplication.translate("updateSettingsForm", "Select update mode:")) - self.button.setText(QtWidgets.QApplication.translate("updateSettingsForm", "Update Toxygen")) - self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Disabled")) - self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Manual")) - self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Auto")) + self.setWindowTitle(util_ui.tr("Update settings")) + self.in_label.setText(util_ui.tr("Select update mode:")) + self.button.setText(util_ui.tr("Update Toxygen")) + self.autoupdate.addItem(util_ui.tr("Disabled")) + self.autoupdate.addItem(util_ui.tr("Manual")) + self.autoupdate.addItem(util_ui.tr("Auto")) def closeEvent(self, event): - settings = Settings.get_instance() - settings['update'] = self.autoupdate.currentIndex() - settings.save() + self._settings['update'] = self.autoupdate.currentIndex() + self._settings.save() def update_client(self): if not updater.connection_available(): - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle( - QtWidgets.QApplication.translate("updateSettingsForm", "Error")) - text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Problems with internet connection')) - msgBox.setText(text) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Problems with internet connection'), util_ui.tr("Error")) return if not updater.updater_available(): - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle( - QtWidgets.QApplication.translate("updateSettingsForm", "Error")) - text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Updater not found')) - msgBox.setText(text) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Updater not found'), util_ui.tr("Error")) return version = updater.check_for_updates() if version is not None: updater.download(version) - QtWidgets.QApplication.closeAllWindows() + util_ui.close_all_windows() else: - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle( - QtWidgets.QApplication.translate("updateSettingsForm", "No updates found")) - text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Toxygen is up to date')) - msgBox.setText(text) - msgBox.exec_() + util_ui.message_box(util_ui.tr('Toxygen is up to date'), util_ui.tr("No updates found")) diff --git a/toxygen/ui/widgets_factory.py b/toxygen/ui/widgets_factory.py index 60ae8c3..46c7c5c 100644 --- a/toxygen/ui/widgets_factory.py +++ b/toxygen/ui/widgets_factory.py @@ -4,12 +4,13 @@ from ui.menu import * class WidgetsFactory: - def __init__(self, settings, profile, contacts_manager, file_transfer_handler, smiley_loader): + def __init__(self, settings, profile, contacts_manager, file_transfer_handler, smiley_loader, plugin_loader): self._settings = settings self._profile = profile self._contacts_manager = contacts_manager self._file_transfer_handler = file_transfer_handler self._smiley_loader = smiley_loader + self._plugin_loader = plugin_loader def create_screenshot_window(self, *args): return ScreenShotWindow(self._file_transfer_handler, *args) @@ -25,3 +26,31 @@ class WidgetsFactory: def create_network_settings_window(self): return NetworkSettings(self._settings, self._profile.reset) + + def create_audio_settings_window(self): + return AudioSettings(self._settings) + + def create_video_settings_window(self): + return VideoSettings(self._settings) + + def create_update_settings_window(self): + return UpdateSettings(self._settings) + + def create_plugins_settings_window(self): + return PluginsSettings(self._plugin_loader) + + def create_add_contact_window(self, tox_id): + return AddContact(self._contacts_manager, tox_id) + + def create_welcome_window(self): + return WelcomeScreen(self._settings) + + def create_privacy_settings_window(self): + return PrivacySettings(self._contacts_manager, self._settings) + + def create_interface_settings_window(self): + return InterfaceSettings(self._settings, self._smiley_loader) + + def create_notification_settings_window(self): + return NotificationsSettings(self._settings) + diff --git a/toxygen/util/ui.py b/toxygen/util/ui.py index a117202..b2b5712 100644 --- a/toxygen/util/ui.py +++ b/toxygen/util/ui.py @@ -31,4 +31,19 @@ def directory_dialog(caption=''): QtWidgets.QFileDialog.DontUseNativeDialog) -# TODO: move all dialogs here +def file_dialog(caption, file_filter=None): + return QtWidgets.QFileDialog.getOpenFileName(None, caption, util.curr_directory(), file_filter, + options=QtWidgets.QFileDialog.DontUseNativeDialog) + + +def save_file_dialog(caption, filter=None): + return QtWidgets.QFileDialog.getSaveFileName(None, caption, util.curr_directory(), + filter=filter, + options=QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) + + +def close_all_windows(): + QtWidgets.QApplication.closeAllWindows() + + +# TODO: all dialogs diff --git a/toxygen/util/util.py b/toxygen/util/util.py index b93a45a..f7ac9ff 100644 --- a/toxygen/util/util.py +++ b/toxygen/util/util.py @@ -65,6 +65,11 @@ def get_translations_directory(): return get_app_directory('translations') +@cached +def get_plugins_directory(): + return get_app_directory('plugins') + + def get_app_directory(directory_name): return os.path.join(get_base_directory(), directory_name) @@ -126,12 +131,6 @@ def time_offset(): return result -def append_slash(s): - if len(s) and s[-1] not in ('\\', '/'): - s += '/' - return s - - @cached def is_64_bit(): return sys.maxsize > 2 ** 32