refactoring - app.py, files moved to different folders
This commit is contained in:
		
							parent
							
								
									91d3f885c0
								
							
						
					
					
						commit
						8a2665ed4d
					
				
					 26 changed files with 287 additions and 302 deletions
				
			
		
							
								
								
									
										4
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								setup.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2,11 +2,11 @@ from setuptools import setup
 | 
			
		|||
from setuptools.command.install import install
 | 
			
		||||
from platform import system
 | 
			
		||||
from subprocess import call
 | 
			
		||||
from toxygen.util import program_version
 | 
			
		||||
import main
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
version = program_version + '.0'
 | 
			
		||||
version = main.__version__ + '.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if system() == 'Windows':
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@ import toxygen.util as util
 | 
			
		|||
import time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# TODO: fic
 | 
			
		||||
 | 
			
		||||
class TestTox:
 | 
			
		||||
 | 
			
		||||
    def test_creation(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										214
									
								
								toxygen/app.py
									
										
									
									
									
								
							
							
						
						
									
										214
									
								
								toxygen/app.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,11 +1,10 @@
 | 
			
		|||
import communication.callbacks
 | 
			
		||||
import threads
 | 
			
		||||
from middleware import threads
 | 
			
		||||
from PyQt5 import QtWidgets, QtGui, QtCore
 | 
			
		||||
import ui.password_screen as passwordscreen
 | 
			
		||||
from util.util import *
 | 
			
		||||
import updater.updater as updater
 | 
			
		||||
import os
 | 
			
		||||
from communication.tox_factory import tox_factory
 | 
			
		||||
from middleware.tox_factory import tox_factory
 | 
			
		||||
import wrapper.toxencryptsave as tox_encrypt_save
 | 
			
		||||
import user_data.toxes
 | 
			
		||||
from user_data.settings import Settings
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +12,8 @@ from ui.login_screen import LoginScreen
 | 
			
		|||
from user_data.profile_manager import ProfileManager
 | 
			
		||||
from plugin_support.plugin_support import PluginLoader
 | 
			
		||||
from ui.main_screen import MainWindow
 | 
			
		||||
from ui import tray
 | 
			
		||||
import util.ui as util_ui
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class App:
 | 
			
		||||
| 
						 | 
				
			
			@ -20,21 +21,20 @@ class App:
 | 
			
		|||
    def __init__(self, version, path_to_profile=None, uri=None):
 | 
			
		||||
        self._version = version
 | 
			
		||||
        self._app = None
 | 
			
		||||
        self.tox = self.ms = self.init = self.app = self.tray = self.mainloop = self.avloop = None
 | 
			
		||||
        self.uri = self.path = self.toxes = None
 | 
			
		||||
        self._tox = self._ms = self._init = self._app = self.tray = self._main_loop = self._av_loop = None
 | 
			
		||||
        self.uri = self._toxes = self._tray = None
 | 
			
		||||
        if uri is not None and uri.startswith('tox:'):
 | 
			
		||||
            self.uri = uri[4:]
 | 
			
		||||
        if path_to_profile is not None:
 | 
			
		||||
            self.path = path_to_profile
 | 
			
		||||
        self._path = path_to_profile
 | 
			
		||||
 | 
			
		||||
    def enter_pass(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Show password screen
 | 
			
		||||
        """
 | 
			
		||||
        p = passwordscreen.PasswordScreen(self.toxes, data)
 | 
			
		||||
        p = passwordscreen.PasswordScreen(self._toxes, data)
 | 
			
		||||
        p.show()
 | 
			
		||||
        self.app.lastWindowClosed.connect(self.app.quit)
 | 
			
		||||
        self.app.exec_()
 | 
			
		||||
        self._app.lastWindowClosed.connect(self._app.quit)
 | 
			
		||||
        self._app.exec_()
 | 
			
		||||
        result = p.result
 | 
			
		||||
        if result is None:
 | 
			
		||||
            raise SystemExit()
 | 
			
		||||
| 
						 | 
				
			
			@ -45,30 +45,29 @@ class App:
 | 
			
		|||
        """
 | 
			
		||||
        Main function of app. loads login screen if needed and starts main screen
 | 
			
		||||
        """
 | 
			
		||||
        app = QtWidgets.QApplication([])
 | 
			
		||||
        self._app= QtWidgets.QApplication([])
 | 
			
		||||
        icon_file = os.path.join(get_images_directory(), 'icon.png')
 | 
			
		||||
        app.setWindowIcon(QtGui.QIcon(icon_file))
 | 
			
		||||
        self._app = app
 | 
			
		||||
        self._app.setWindowIcon(QtGui.QIcon(icon_file))
 | 
			
		||||
 | 
			
		||||
        if get_platform() == 'Linux':
 | 
			
		||||
            QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
 | 
			
		||||
 | 
			
		||||
        with open(os.path.join(get_styles_directory(), 'dark_style.qss')) as fl:
 | 
			
		||||
            style = fl.read()
 | 
			
		||||
        app.setStyleSheet(style)
 | 
			
		||||
        self._app.setStyleSheet(style)
 | 
			
		||||
 | 
			
		||||
        encrypt_save = tox_encrypt_save.ToxEncryptSave()
 | 
			
		||||
        self._toxes = user_data.toxes.ToxES(encrypt_save)
 | 
			
		||||
 | 
			
		||||
        if self.path is not None:
 | 
			
		||||
            path = os.path.dirname(self.path) + '/'
 | 
			
		||||
            name = os.path.basename(self.path)[:-4]
 | 
			
		||||
            self._settings = Settings(self._toxes, self.path.replace('.tox', '.json'))
 | 
			
		||||
        if self._path is not None:
 | 
			
		||||
            path = os.path.dirname(self._path) + '/'
 | 
			
		||||
            name = os.path.basename(self._path)[:-4]
 | 
			
		||||
            self._settings = Settings(self._toxes, self._path.replace('.tox', '.json'))
 | 
			
		||||
            self._profile_manager = ProfileManager(self._settings, self._toxes, path)
 | 
			
		||||
            data = self._profile_manager.open_profile()
 | 
			
		||||
            if encrypt_save.is_data_encrypted(data):
 | 
			
		||||
                data = self.enter_pass(data)
 | 
			
		||||
            self.tox = tox_factory(data, self._settings)
 | 
			
		||||
            self._tox = self.create_tox(data)
 | 
			
		||||
        else:
 | 
			
		||||
            auto_profile = Settings.get_auto_profile()
 | 
			
		||||
            if not auto_profile[0]:
 | 
			
		||||
| 
						 | 
				
			
			@ -79,15 +78,15 @@ class App:
 | 
			
		|||
                if curr_lang in langs:
 | 
			
		||||
                    lang_path = langs[curr_lang]
 | 
			
		||||
                    translator = QtCore.QTranslator()
 | 
			
		||||
                    translator.load(curr_directory() + '/translations/' + lang_path)
 | 
			
		||||
                    app.installTranslator(translator)
 | 
			
		||||
                    app.translator = translator
 | 
			
		||||
                    translator.load(get_translations_directory() + lang_path)
 | 
			
		||||
                    self._app.installTranslator(translator)
 | 
			
		||||
                    self._app.translator = translator
 | 
			
		||||
                ls = LoginScreen()
 | 
			
		||||
                ls.setWindowIconText("Toxygen")
 | 
			
		||||
                profiles = ProfileManager.find_profiles()
 | 
			
		||||
                ls.update_select(profiles)
 | 
			
		||||
                ls.show()
 | 
			
		||||
                app.exec_()
 | 
			
		||||
                self._app.exec_()
 | 
			
		||||
                result = ls.result
 | 
			
		||||
                if result is None:
 | 
			
		||||
                    return
 | 
			
		||||
| 
						 | 
				
			
			@ -95,47 +94,22 @@ class App:
 | 
			
		|||
                    name = get_profile_name_from_path(result.profile_path) or 'toxygen_user'
 | 
			
		||||
                    pr = map(lambda x: x[1], ProfileManager.find_profiles())
 | 
			
		||||
                    if name in list(pr):
 | 
			
		||||
                        msgBox = QtWidgets.QMessageBox()
 | 
			
		||||
                        msgBox.setWindowTitle(
 | 
			
		||||
                            QtWidgets.QApplication.translate("MainWindow", "Error"))
 | 
			
		||||
                        text = (QtWidgets.QApplication.translate("MainWindow",
 | 
			
		||||
                                                                 'Profile with this name already exists'))
 | 
			
		||||
                        msgBox.setText(text)
 | 
			
		||||
                        msgBox.exec_()
 | 
			
		||||
                        util_ui.message_box(util_ui.tr('Profile with this name already exists'),
 | 
			
		||||
                                            util_ui.tr('Error'))
 | 
			
		||||
                        return
 | 
			
		||||
                    self.tox = tox_factory()
 | 
			
		||||
                    self.tox.self_set_name(bytes(name, 'utf-8') if name else b'Toxygen User')
 | 
			
		||||
                    self.tox.self_set_status_message(b'Toxing on Toxygen')
 | 
			
		||||
                    reply = QtWidgets.QMessageBox.question(None,
 | 
			
		||||
                                                           'Profile {}'.format(name),
 | 
			
		||||
                                                           QtWidgets.QApplication.translate("login",
 | 
			
		||||
                                                                                            'Do you want to set profile password?'),
 | 
			
		||||
                                                           QtWidgets.QMessageBox.Yes,
 | 
			
		||||
                                                           QtWidgets.QMessageBox.No)
 | 
			
		||||
                    if reply == QtWidgets.QMessageBox.Yes:
 | 
			
		||||
                        set_pass = SetProfilePasswordScreen(encrypt_save)
 | 
			
		||||
                        set_pass.show()
 | 
			
		||||
                        self.app.lastWindowClosed.connect(self.app.quit)
 | 
			
		||||
                        self.app.exec_()
 | 
			
		||||
                    reply = QtWidgets.QMessageBox.question(None,
 | 
			
		||||
                                                           'Profile {}'.format(name),
 | 
			
		||||
                                                           QtWidgets.QApplication.translate("login",
 | 
			
		||||
                                                                                            'Do you want to save profile in default folder? If no, profile will be saved in program folder'),
 | 
			
		||||
                                                           QtWidgets.QMessageBox.Yes,
 | 
			
		||||
                                                           QtWidgets.QMessageBox.No)
 | 
			
		||||
                    if reply == QtWidgets.QMessageBox.Yes:
 | 
			
		||||
                        path = Settings.get_default_path()
 | 
			
		||||
                    else:
 | 
			
		||||
                        path = curr_directory() + '/'
 | 
			
		||||
                    self._tox = tox_factory()
 | 
			
		||||
                    self._tox.self_set_name(bytes(name, 'utf-8') if name else b'Toxygen User')
 | 
			
		||||
                    self._tox.self_set_status_message(b'Toxing on Toxygen')
 | 
			
		||||
                    # TODO: set profile password
 | 
			
		||||
                    path = result.profile_path
 | 
			
		||||
                    self._profile_manager = ProfileManager(self._toxes, path)
 | 
			
		||||
                    try:
 | 
			
		||||
                        ProfileManager(path, name).save_profile(self.tox.get_savedata())
 | 
			
		||||
                        self._profile_manager.save_profile(self._tox.get_savedata())
 | 
			
		||||
                    except Exception as ex:
 | 
			
		||||
                        print(str(ex))
 | 
			
		||||
                        log('Profile creation exception: ' + str(ex))
 | 
			
		||||
                        msgBox = QtWidgets.QMessageBox()
 | 
			
		||||
                        msgBox.setText(QtWidgets.QApplication.translate("login",
 | 
			
		||||
                                                                        'Profile saving error! Does Toxygen have permission to write to this directory?'))
 | 
			
		||||
                        msgBox.exec_()
 | 
			
		||||
                        text = util_ui.tr('Profile saving error! Does Toxygen have permission to write to this directory?')
 | 
			
		||||
                        util_ui.message_box(text, util_ui.tr('Error'))
 | 
			
		||||
                        return
 | 
			
		||||
                    path = Settings.get_default_path()
 | 
			
		||||
                    self._settings = Settings()
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +125,7 @@ class App:
 | 
			
		|||
                    data = self._profile_manager.open_profile()
 | 
			
		||||
                    if self._toxes.is_data_encrypted(data):
 | 
			
		||||
                        data = self.enter_pass(data)
 | 
			
		||||
                    self._tox = tox_factory(data, self._settings)
 | 
			
		||||
                    self._tox = self.create_tox(data)
 | 
			
		||||
            else:
 | 
			
		||||
                path, name = auto_profile
 | 
			
		||||
                self._settings = Settings(self._toxes, path + name + '.json')
 | 
			
		||||
| 
						 | 
				
			
			@ -159,15 +133,13 @@ class App:
 | 
			
		|||
                data = self._profile_manager.open_profile()
 | 
			
		||||
                if encrypt_save.is_data_encrypted(data):
 | 
			
		||||
                    data = self.enter_pass(data)
 | 
			
		||||
                self.tox = tox_factory(data, self._settings)
 | 
			
		||||
                self.tox = self.create_tox(data)
 | 
			
		||||
 | 
			
		||||
        if Settings.is_active_profile(path, get_profile_name_from_path(path)):  # profile is in use
 | 
			
		||||
            reply = QtWidgets.QMessageBox.question(None,
 | 
			
		||||
                                                   'Profile {}'.format(name),
 | 
			
		||||
                                                   QtWidgets.QApplication.translate("login", 'Other instance of Toxygen uses this profile or profile was not properly closed. Continue?'),
 | 
			
		||||
                                                   QtWidgets.QMessageBox.Yes,
 | 
			
		||||
                                                   QtWidgets.QMessageBox.No)
 | 
			
		||||
            if reply != QtWidgets.QMessageBox.Yes:
 | 
			
		||||
            title = util_ui.tr('Profile {}').format(name)
 | 
			
		||||
            text = util_ui.tr('Other instance of Toxygen uses this profile or profile was not properly closed. Continue?')
 | 
			
		||||
            reply = util_ui.question(text, title)
 | 
			
		||||
            if not reply:
 | 
			
		||||
                return
 | 
			
		||||
        else:
 | 
			
		||||
            self._settings.set_active_profile()
 | 
			
		||||
| 
						 | 
				
			
			@ -175,82 +147,49 @@ class App:
 | 
			
		|||
        self.load_app_styles()
 | 
			
		||||
        self.load_app_translations()
 | 
			
		||||
 | 
			
		||||
        # tray icon
 | 
			
		||||
 | 
			
		||||
        self.ms = MainWindow(self._settings, self._tox, self.reset, self.tray)
 | 
			
		||||
        self._profile = self.ms.profile
 | 
			
		||||
        self.ms.show()
 | 
			
		||||
 | 
			
		||||
        updating = updater.start_update_if_needed(self._version, self._settings)
 | 
			
		||||
        if updating:
 | 
			
		||||
            data = self.tox.get_savedata()
 | 
			
		||||
            self._profile_manager.save_profile(data)
 | 
			
		||||
            self._settings.close()
 | 
			
		||||
            del self.tox
 | 
			
		||||
        if self.try_to_update():
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        plugin_helper = PluginLoader(self._tox, self._toxes, self._profile, self._settings)  # plugin support
 | 
			
		||||
        plugin_helper.load()
 | 
			
		||||
        self._ms = MainWindow(self._settings, self._tox, self.reset, self._tray)
 | 
			
		||||
        self._profile = self._ms.profile
 | 
			
		||||
        self._ms.show()
 | 
			
		||||
 | 
			
		||||
        # init thread
 | 
			
		||||
        self.init = threads.InitThread(self.tox, self.ms, self.tray)
 | 
			
		||||
        self.init.start()
 | 
			
		||||
        self._tray = tray.init_tray(self._profile, self._settings, self._ms)
 | 
			
		||||
        self._tray.show()
 | 
			
		||||
 | 
			
		||||
        # starting threads for tox iterate and toxav iterate
 | 
			
		||||
        self.mainloop = threads.ToxIterateThread(self._tox)
 | 
			
		||||
        self.mainloop.start()
 | 
			
		||||
        self.avloop = threads.ToxAVIterateThread(self._tox.AV)
 | 
			
		||||
        self.avloop.start()
 | 
			
		||||
        self._plugin_loader = PluginLoader(self._tox, self._toxes, self._profile, self._settings)  # plugins support
 | 
			
		||||
        self._plugin_loader.load()  # TODO; move to separate thread?
 | 
			
		||||
 | 
			
		||||
        if self.uri is not None:
 | 
			
		||||
            self.ms.add_contact(self.uri)
 | 
			
		||||
            self._ms.add_contact(self.uri)
 | 
			
		||||
 | 
			
		||||
        app.lastWindowClosed.connect(app.quit)
 | 
			
		||||
        app.exec_()
 | 
			
		||||
        self._app.lastWindowClosed.connect(self._app.quit)
 | 
			
		||||
        self._app.exec_()
 | 
			
		||||
 | 
			
		||||
        self.init.stop = True
 | 
			
		||||
        self.mainloop.stop = True
 | 
			
		||||
        self.avloop.stop = True
 | 
			
		||||
        plugin_helper.stop()
 | 
			
		||||
        self.mainloop.wait()
 | 
			
		||||
        self.init.wait()
 | 
			
		||||
        self.avloop.wait()
 | 
			
		||||
        self.tray.hide()
 | 
			
		||||
        data = self.tox.get_savedata()
 | 
			
		||||
        self._plugin_loader.stop()
 | 
			
		||||
        self.stop_threads()
 | 
			
		||||
        self._tray.hide()
 | 
			
		||||
        data = self._tox.get_savedata()
 | 
			
		||||
        self._profile_manager.save_profile(data)
 | 
			
		||||
        self._settings.close()
 | 
			
		||||
        del self.tox
 | 
			
		||||
        del self._tox
 | 
			
		||||
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        """
 | 
			
		||||
        Create new tox instance (new network settings)
 | 
			
		||||
        :return: tox instance
 | 
			
		||||
        """
 | 
			
		||||
        self.mainloop.stop = True
 | 
			
		||||
        self.init.stop = True
 | 
			
		||||
        self.avloop.stop = True
 | 
			
		||||
        self.mainloop.wait()
 | 
			
		||||
        self.init.wait()
 | 
			
		||||
        self.avloop.wait()
 | 
			
		||||
        data = self.tox.get_savedata()
 | 
			
		||||
        self.stop_threads()
 | 
			
		||||
        data = self._tox.get_savedata()
 | 
			
		||||
        self._profile_manager.save_profile(data)
 | 
			
		||||
        del self.tox
 | 
			
		||||
        del self._tox
 | 
			
		||||
        # create new tox instance
 | 
			
		||||
        self.tox = tox_factory(data, self._settings)
 | 
			
		||||
        # init thread
 | 
			
		||||
        self.init = threads.InitThread(self.tox, self.ms, self.tray)
 | 
			
		||||
        self.init.start()
 | 
			
		||||
        self._tox = tox_factory(data, self._settings)
 | 
			
		||||
        self.start_threads()
 | 
			
		||||
 | 
			
		||||
        # starting threads for tox iterate and toxav iterate
 | 
			
		||||
        self.mainloop = threads.ToxIterateThread(self.tox)
 | 
			
		||||
        self.mainloop.start()
 | 
			
		||||
        self._plugin_loader.set_tox(self._tox)
 | 
			
		||||
 | 
			
		||||
        self.avloop = threads.ToxAVIterateThread(self.tox.AV)
 | 
			
		||||
        self.avloop.start()
 | 
			
		||||
 | 
			
		||||
        self._plugin_loader.set_tox(self.tox)
 | 
			
		||||
 | 
			
		||||
        return self.tox
 | 
			
		||||
        return self._tox
 | 
			
		||||
 | 
			
		||||
    def load_app_styles(self):
 | 
			
		||||
        # application color scheme
 | 
			
		||||
| 
						 | 
				
			
			@ -266,3 +205,32 @@ class App:
 | 
			
		|||
        translator.load(curr_directory(__file__) + '/translations/' + lang)
 | 
			
		||||
        self._app.installTranslator(translator)
 | 
			
		||||
        self._app.translator = translator
 | 
			
		||||
 | 
			
		||||
    def try_to_update(self):
 | 
			
		||||
        updating = updater.start_update_if_needed(self._version, self._settings)
 | 
			
		||||
        if updating:
 | 
			
		||||
            data = self._tox.get_savedata()
 | 
			
		||||
            self._profile_manager.save_profile(data)
 | 
			
		||||
            self._settings.close()
 | 
			
		||||
            del self._tox
 | 
			
		||||
        return updating
 | 
			
		||||
 | 
			
		||||
    def start_threads(self):
 | 
			
		||||
        # init thread
 | 
			
		||||
        self._init = threads.InitThread(self._tox, self._ms, self._tray)
 | 
			
		||||
        self._init.start()
 | 
			
		||||
 | 
			
		||||
        # starting threads for tox iterate and toxav iterate
 | 
			
		||||
        self._main_loop = threads.ToxIterateThread(self._tox)
 | 
			
		||||
        self._main_loop.start()
 | 
			
		||||
        self._av_loop = threads.ToxAVIterateThread(self._tox.AV)
 | 
			
		||||
        self._av_loop.start()
 | 
			
		||||
 | 
			
		||||
    def stop_threads(self):
 | 
			
		||||
        self._init.stop_thread()
 | 
			
		||||
 | 
			
		||||
        self._main_loop.stop_thread()
 | 
			
		||||
        self._av_loop.stop_thread()
 | 
			
		||||
 | 
			
		||||
    def create_tox(self, data):
 | 
			
		||||
        return tox_factory(data, self._settings)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ import time
 | 
			
		|||
from av import calls
 | 
			
		||||
import plugin_support
 | 
			
		||||
from contacts import basecontact
 | 
			
		||||
from ui import items_factory, avwidgets
 | 
			
		||||
from ui import items_factory, av_widgets
 | 
			
		||||
import cv2
 | 
			
		||||
import threading
 | 
			
		||||
from contacts.group_chat import *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +0,0 @@
 | 
			
		|||
class Login:
 | 
			
		||||
 | 
			
		||||
    def __init__(self, arr):
 | 
			
		||||
        self.arr = arr
 | 
			
		||||
 | 
			
		||||
    def login_screen_close(self, t, number=-1, default=False, name=None):
 | 
			
		||||
        """ Function which processes data from login screen
 | 
			
		||||
        :param t: 0 - window was closed, 1 - new profile was created, 2 - profile loaded
 | 
			
		||||
        :param number: num of chosen profile in list (-1 by default)
 | 
			
		||||
        :param default: was or not chosen profile marked as default
 | 
			
		||||
        :param name: name of new profile
 | 
			
		||||
        """
 | 
			
		||||
        self.t = t
 | 
			
		||||
        self.num = number
 | 
			
		||||
        self.default = default
 | 
			
		||||
        self.name = name
 | 
			
		||||
 | 
			
		||||
    def get_data(self):
 | 
			
		||||
        return self.arr[self.num]
 | 
			
		||||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ from user_data.settings import *
 | 
			
		|||
from util.util import curr_directory, remove
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__maintainer__ = 'Ingvar'
 | 
			
		||||
__version__ = '0.5.0'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
from PyQt5 import QtGui
 | 
			
		||||
from notifications import *
 | 
			
		||||
from user_data.settings import Settings
 | 
			
		||||
from contacts.profile import Profile
 | 
			
		||||
from wrapper.toxcore_enums_and_consts import *
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +7,7 @@ from wrapper.tox import bin_to_string
 | 
			
		|||
from plugin_support.plugin_support import PluginLoader
 | 
			
		||||
import cv2
 | 
			
		||||
import numpy as np
 | 
			
		||||
from threads import invoke_in_main_thread, execute
 | 
			
		||||
from middleware.threads import invoke_in_main_thread, execute
 | 
			
		||||
 | 
			
		||||
# TODO: use closures
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,17 +1,26 @@
 | 
			
		|||
from PyQt5 import QtCore
 | 
			
		||||
from bootstrap.bootstrap import *
 | 
			
		||||
import threading
 | 
			
		||||
import queue
 | 
			
		||||
from util import util
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseThread(threading.Thread):
 | 
			
		||||
 | 
			
		||||
class InitThread(QtCore.QThread):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self._stop = False
 | 
			
		||||
 | 
			
		||||
    def stop_thread(self):
 | 
			
		||||
        self._stop = True
 | 
			
		||||
        self.join()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InitThread(BaseThread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, tox, ms, tray):
 | 
			
		||||
        QtCore.QThread.__init__(self)
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.tox, self.ms, self.tray = tox, ms, tray
 | 
			
		||||
        self.stop = False
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        # initializing callbacks
 | 
			
		||||
| 
						 | 
				
			
			@ -21,71 +30,65 @@ class InitThread(QtCore.QThread):
 | 
			
		|||
        # bootstrap
 | 
			
		||||
        try:
 | 
			
		||||
            for data in generate_nodes():
 | 
			
		||||
                if self.stop:
 | 
			
		||||
                if self._stop:
 | 
			
		||||
                    return
 | 
			
		||||
                self.tox.bootstrap(*data)
 | 
			
		||||
                self.tox.add_tcp_relay(*data)
 | 
			
		||||
        except:
 | 
			
		||||
            pass
 | 
			
		||||
        for _ in range(10):
 | 
			
		||||
            if self.stop:
 | 
			
		||||
            if self._stop:
 | 
			
		||||
                return
 | 
			
		||||
            self.msleep(1000)
 | 
			
		||||
            time.sleep(1)
 | 
			
		||||
        while not self.tox.self_get_connection_status():
 | 
			
		||||
            try:
 | 
			
		||||
                for data in generate_nodes():
 | 
			
		||||
                    if self.stop:
 | 
			
		||||
                    if self._stop:
 | 
			
		||||
                        return
 | 
			
		||||
                    self.tox.bootstrap(*data)
 | 
			
		||||
                    self.tox.add_tcp_relay(*data)
 | 
			
		||||
            except:
 | 
			
		||||
                pass
 | 
			
		||||
            finally:
 | 
			
		||||
                self.msleep(5000)
 | 
			
		||||
                time.sleep(5)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ToxIterateThread(QtCore.QThread):
 | 
			
		||||
class ToxIterateThread(BaseThread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, tox):
 | 
			
		||||
        QtCore.QThread.__init__(self)
 | 
			
		||||
        self.tox = tox
 | 
			
		||||
        self.stop = False
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self._tox = tox
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        while not self.stop:
 | 
			
		||||
            self.tox.iterate()
 | 
			
		||||
            self.msleep(self.tox.iteration_interval())
 | 
			
		||||
        while not self._stop:
 | 
			
		||||
            self._tox.iterate()
 | 
			
		||||
            time.sleep(self._tox.iteration_interval() / 1000)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ToxAVIterateThread(QtCore.QThread):
 | 
			
		||||
class ToxAVIterateThread(BaseThread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, toxav):
 | 
			
		||||
        QtCore.QThread.__init__(self)
 | 
			
		||||
        self.toxav = toxav
 | 
			
		||||
        self.stop = False
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self._toxav = toxav
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        while not self.stop:
 | 
			
		||||
            self.toxav.iterate()
 | 
			
		||||
            self.msleep(self.toxav.iteration_interval())
 | 
			
		||||
        while not self._stop:
 | 
			
		||||
            self._toxav.iterate()
 | 
			
		||||
            time.sleep(self._toxav.iteration_interval() / 1000)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FileTransfersThread(threading.Thread):
 | 
			
		||||
class FileTransfersThread(BaseThread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self._queue = queue.Queue()
 | 
			
		||||
        self._timeout = 0.01
 | 
			
		||||
        self._continue = True
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
    def execute(self, func, *args, **kwargs):
 | 
			
		||||
        self._queue.put((func, args, kwargs))
 | 
			
		||||
 | 
			
		||||
    def stop(self):
 | 
			
		||||
        self._continue = False
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        while self._continue:
 | 
			
		||||
        while not self._stop:
 | 
			
		||||
            try:
 | 
			
		||||
                func, args, kwargs = self._queue.get(timeout=self._timeout)
 | 
			
		||||
                func(*args, **kwargs)
 | 
			
		||||
| 
						 | 
				
			
			@ -105,8 +108,7 @@ def start():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def stop():
 | 
			
		||||
    _thread.stop()
 | 
			
		||||
    _thread.join()
 | 
			
		||||
    _thread.stop_thread()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def execute(func, *args, **kwargs):
 | 
			
		||||
| 
						 | 
				
			
			@ -1,71 +0,0 @@
 | 
			
		|||
from PyQt5 import QtCore, QtWidgets
 | 
			
		||||
from util.util import curr_directory
 | 
			
		||||
import wave
 | 
			
		||||
import pyaudio
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SOUND_NOTIFICATION = {
 | 
			
		||||
    'MESSAGE': 0,
 | 
			
		||||
    'FRIEND_CONNECTION_STATUS': 1,
 | 
			
		||||
    'FILE_TRANSFER': 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def tray_notification(title, text, tray, window):
 | 
			
		||||
    """
 | 
			
		||||
    Show tray notification and activate window icon
 | 
			
		||||
    NOTE: different behaviour on different OS
 | 
			
		||||
    :param title: Name of user who sent message or file
 | 
			
		||||
    :param text: text of message or file info
 | 
			
		||||
    :param tray: ref to tray icon
 | 
			
		||||
    :param window: main window
 | 
			
		||||
    """
 | 
			
		||||
    if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
 | 
			
		||||
        if len(text) > 30:
 | 
			
		||||
            text = text[:27] + '...'
 | 
			
		||||
        tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000)
 | 
			
		||||
        QtWidgets.QApplication.alert(window, 0)
 | 
			
		||||
 | 
			
		||||
        def message_clicked():
 | 
			
		||||
            window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
 | 
			
		||||
            window.activateWindow()
 | 
			
		||||
        tray.messageClicked.connect(message_clicked)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AudioFile:
 | 
			
		||||
    chunk = 1024
 | 
			
		||||
 | 
			
		||||
    def __init__(self, fl):
 | 
			
		||||
        self.wf = wave.open(fl, 'rb')
 | 
			
		||||
        self.p = pyaudio.PyAudio()
 | 
			
		||||
        self.stream = self.p.open(
 | 
			
		||||
            format=self.p.get_format_from_width(self.wf.getsampwidth()),
 | 
			
		||||
            channels=self.wf.getnchannels(),
 | 
			
		||||
            rate=self.wf.getframerate(),
 | 
			
		||||
            output=True)
 | 
			
		||||
 | 
			
		||||
    def play(self):
 | 
			
		||||
        data = self.wf.readframes(self.chunk)
 | 
			
		||||
        while data:
 | 
			
		||||
            self.stream.write(data)
 | 
			
		||||
            data = self.wf.readframes(self.chunk)
 | 
			
		||||
 | 
			
		||||
    def close(self):
 | 
			
		||||
        self.stream.close()
 | 
			
		||||
        self.p.terminate()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sound_notification(t):
 | 
			
		||||
    """
 | 
			
		||||
    Plays sound notification
 | 
			
		||||
    :param t: type of notification
 | 
			
		||||
    """
 | 
			
		||||
    if t == SOUND_NOTIFICATION['MESSAGE']:
 | 
			
		||||
        f = curr_directory() + '/sounds/message.wav'
 | 
			
		||||
    elif t == SOUND_NOTIFICATION['FILE_TRANSFER']:
 | 
			
		||||
        f = curr_directory() + '/sounds/file.wav'
 | 
			
		||||
    else:
 | 
			
		||||
        f = curr_directory() + '/sounds/contact.wav'
 | 
			
		||||
    a = AudioFile(f)
 | 
			
		||||
    a.play()
 | 
			
		||||
    a.close()
 | 
			
		||||
							
								
								
									
										0
									
								
								toxygen/notifications/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toxygen/notifications/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										54
									
								
								toxygen/notifications/sound.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								toxygen/notifications/sound.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
import util.util
 | 
			
		||||
import wave
 | 
			
		||||
import pyaudio
 | 
			
		||||
import os.path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SOUND_NOTIFICATION = {
 | 
			
		||||
    'MESSAGE': 0,
 | 
			
		||||
    'FRIEND_CONNECTION_STATUS': 1,
 | 
			
		||||
    'FILE_TRANSFER': 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AudioFile:
 | 
			
		||||
    chunk = 1024
 | 
			
		||||
 | 
			
		||||
    def __init__(self, fl):
 | 
			
		||||
        self.wf = wave.open(fl, 'rb')
 | 
			
		||||
        self.p = pyaudio.PyAudio()
 | 
			
		||||
        self.stream = self.p.open(
 | 
			
		||||
            format=self.p.get_format_from_width(self.wf.getsampwidth()),
 | 
			
		||||
            channels=self.wf.getnchannels(),
 | 
			
		||||
            rate=self.wf.getframerate(),
 | 
			
		||||
            output=True)
 | 
			
		||||
 | 
			
		||||
    def play(self):
 | 
			
		||||
        data = self.wf.readframes(self.chunk)
 | 
			
		||||
        while data:
 | 
			
		||||
            self.stream.write(data)
 | 
			
		||||
            data = self.wf.readframes(self.chunk)
 | 
			
		||||
 | 
			
		||||
    def close(self):
 | 
			
		||||
        self.stream.close()
 | 
			
		||||
        self.p.terminate()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sound_notification(t):
 | 
			
		||||
    """
 | 
			
		||||
    Plays sound notification
 | 
			
		||||
    :param t: type of notification
 | 
			
		||||
    """
 | 
			
		||||
    if t == SOUND_NOTIFICATION['MESSAGE']:
 | 
			
		||||
        f = get_file_path('message.wav')
 | 
			
		||||
    elif t == SOUND_NOTIFICATION['FILE_TRANSFER']:
 | 
			
		||||
        f = get_file_path('file.wav')
 | 
			
		||||
    else:
 | 
			
		||||
        f = get_file_path('contact.wav')
 | 
			
		||||
    a = AudioFile(f)
 | 
			
		||||
    a.play()
 | 
			
		||||
    a.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_file_path(file_name):
 | 
			
		||||
    return os.path.join(util.util.get_sounds_directory(), file_name)
 | 
			
		||||
							
								
								
									
										22
									
								
								toxygen/notifications/tray.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								toxygen/notifications/tray.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
from PyQt5 import QtCore, QtWidgets
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def tray_notification(title, text, tray, window):
 | 
			
		||||
    """
 | 
			
		||||
    Show tray notification and activate window icon
 | 
			
		||||
    NOTE: different behaviour on different OS
 | 
			
		||||
    :param title: Name of user who sent message or file
 | 
			
		||||
    :param text: text of message or file info
 | 
			
		||||
    :param tray: ref to tray icon
 | 
			
		||||
    :param window: main window
 | 
			
		||||
    """
 | 
			
		||||
    if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
 | 
			
		||||
        if len(text) > 30:
 | 
			
		||||
            text = text[:27] + '...'
 | 
			
		||||
        tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000)
 | 
			
		||||
        QtWidgets.QApplication.alert(window, 0)
 | 
			
		||||
 | 
			
		||||
        def message_clicked():
 | 
			
		||||
            window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
 | 
			
		||||
            window.activateWindow()
 | 
			
		||||
        tray.messageClicked.connect(message_clicked)
 | 
			
		||||
							
								
								
									
										0
									
								
								toxygen/smileys/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toxygen/smileys/__init__.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -47,6 +47,7 @@ class SmileyLoader:
 | 
			
		|||
    def get_smileys_path(self):
 | 
			
		||||
        return util.curr_directory() + '/smileys/' + self._curr_pack + '/' if self._curr_pack is not None else None
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_packs_list(self):
 | 
			
		||||
        d = util.curr_directory() + '/smileys/'
 | 
			
		||||
        return [x[1] for x in os.walk(d)][0]
 | 
			
		||||
| 
						 | 
				
			
			@ -71,18 +72,3 @@ class SmileyLoader:
 | 
			
		|||
                if file_name.endswith('.gif'):  # animated smiley
 | 
			
		||||
                    edit.addAnimation(QtCore.QUrl(file_name), self.get_smileys_path() + file_name)
 | 
			
		||||
        return ' '.join(arr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sticker_loader():
 | 
			
		||||
    """
 | 
			
		||||
    :return list of stickers
 | 
			
		||||
    """
 | 
			
		||||
    result = []
 | 
			
		||||
    d = util.curr_directory() + '/stickers/'
 | 
			
		||||
    keys = [x[1] for x in os.walk(d)][0]
 | 
			
		||||
    for key in keys:
 | 
			
		||||
        path = d + key + '/'
 | 
			
		||||
        files = filter(lambda f: f.endswith('.png'), os.listdir(path))
 | 
			
		||||
        files = map(lambda f: str(path + f), files)
 | 
			
		||||
        result.extend(files)
 | 
			
		||||
    return result
 | 
			
		||||
							
								
								
									
										0
									
								
								toxygen/stickers/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toxygen/stickers/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										18
									
								
								toxygen/stickers/stickers.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								toxygen/stickers/stickers.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
import os
 | 
			
		||||
import util.util as util
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_stickers():
 | 
			
		||||
    """
 | 
			
		||||
    :return list of stickers
 | 
			
		||||
    """
 | 
			
		||||
    result = []
 | 
			
		||||
    d = util.get_stickers_directory()
 | 
			
		||||
    keys = [x[1] for x in os.walk(d)][0]
 | 
			
		||||
    for key in keys:
 | 
			
		||||
        path = d + key + '/'
 | 
			
		||||
        files = filter(lambda f: f.endswith('.png'), os.listdir(path))
 | 
			
		||||
        files = map(lambda f: str(path + f), files)
 | 
			
		||||
        result.extend(files)
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ 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):
 | 
			
		||||
| 
						 | 
				
			
			@ -414,12 +415,10 @@ class MainWindow(QtWidgets.QMainWindow):
 | 
			
		|||
    # -----------------------------------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    def about_program(self):
 | 
			
		||||
        import util
 | 
			
		||||
        msgBox = QtWidgets.QMessageBox()
 | 
			
		||||
        msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "About"))
 | 
			
		||||
        text = (QtWidgets.QApplication.translate("MainWindow", 'Toxygen is Tox client written on Python.\nVersion: '))
 | 
			
		||||
        msgBox.setText(text + util.program_version + '\nGitHub: https://github.com/toxygen-project/toxygen/')
 | 
			
		||||
        msgBox.exec_()
 | 
			
		||||
        text = util_ui.tr('Toxygen is Tox client written on Python.\nVersion: ')
 | 
			
		||||
        text += '' + '\nGitHub: https://github.com/toxygen-project/toxygen/'
 | 
			
		||||
        title = util_ui.tr('About')
 | 
			
		||||
        util_ui.message_box(text, title)
 | 
			
		||||
 | 
			
		||||
    def network_settings(self):
 | 
			
		||||
        self.n_s = NetworkSettings(self.reset)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
 | 
			
		|||
from ui.widgets import RubberBandWindow, create_menu, QRightClickButton, CenteredWidget, LineEdit
 | 
			
		||||
from contacts.profile import Profile
 | 
			
		||||
import smileys
 | 
			
		||||
import util
 | 
			
		||||
import util.util as util
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MessageArea(QtWidgets.QPlainTextEdit):
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +194,7 @@ class DropdownMenu(QtWidgets.QWidget):
 | 
			
		|||
        self.stickerButton = QtWidgets.QPushButton(self)
 | 
			
		||||
        self.stickerButton.setGeometry(QtCore.QRect(60, 0, 60, 60))
 | 
			
		||||
 | 
			
		||||
        pixmap = QtGui.QPixmap(util.curr_directory() + '/images/file.png')
 | 
			
		||||
        pixmap = QtGui.QPixmap(util.get_images_directory() + 'file.png')
 | 
			
		||||
        icon = QtGui.QIcon(pixmap)
 | 
			
		||||
        self.fileTransferButton.setIcon(icon)
 | 
			
		||||
        self.fileTransferButton.setIconSize(QtCore.QSize(50, 50))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
from PyQt5 import QtWidgets, QtGui, QtCore
 | 
			
		||||
from util.ui import tr
 | 
			
		||||
from util.util import curr_directory
 | 
			
		||||
from util.util import get_images_directory
 | 
			
		||||
import os.path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
 | 
			
		||||
| 
						 | 
				
			
			@ -8,11 +9,11 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
 | 
			
		|||
    leftClicked = QtCore.pyqtSignal()
 | 
			
		||||
 | 
			
		||||
    def __init__(self, icon, parent=None):
 | 
			
		||||
        super().__init__(self, icon, parent)
 | 
			
		||||
        self.activated.connect(self.iconActivated)
 | 
			
		||||
        super().__init__(icon, parent)
 | 
			
		||||
        self.activated.connect(self.icon_activated)
 | 
			
		||||
 | 
			
		||||
    def iconActivated(self, reason):
 | 
			
		||||
        if reason == QtGui.QSystemTrayIcon.Trigger:
 | 
			
		||||
    def icon_activated(self, reason):
 | 
			
		||||
        if reason == QtWidgets.QSystemTrayIcon.Trigger:
 | 
			
		||||
            self.leftClicked.emit()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,20 +53,21 @@ class Menu(QtWidgets.QMenu):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def init_tray(profile, settings, main_screen):
 | 
			
		||||
    tray = SystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
 | 
			
		||||
    icon = os.path.join(get_images_directory(), 'icon.png')
 | 
			
		||||
    tray = SystemTrayIcon(QtGui.QIcon(icon))
 | 
			
		||||
    tray.setObjectName('tray')
 | 
			
		||||
 | 
			
		||||
    m = Menu(settings, profile)
 | 
			
		||||
    show = m.addAction(tr('Open Toxygen'))
 | 
			
		||||
    sub = m.addMenu(tr('Set status'))
 | 
			
		||||
    menu = Menu(settings, profile)
 | 
			
		||||
    show = menu.addAction(tr('Open Toxygen'))
 | 
			
		||||
    sub = menu.addMenu(tr('Set status'))
 | 
			
		||||
    online = sub.addAction(tr('Online'))
 | 
			
		||||
    away = sub.addAction(tr('Away'))
 | 
			
		||||
    busy = sub.addAction(tr('Busy'))
 | 
			
		||||
    online.setCheckable(True)
 | 
			
		||||
    away.setCheckable(True)
 | 
			
		||||
    busy.setCheckable(True)
 | 
			
		||||
    m.act = sub
 | 
			
		||||
    exit = m.addAction(tr('Exit'))
 | 
			
		||||
    menu.act = sub
 | 
			
		||||
    exit = menu.addAction(tr('Exit'))
 | 
			
		||||
 | 
			
		||||
    def show_window():
 | 
			
		||||
        def show():
 | 
			
		||||
| 
						 | 
				
			
			@ -96,12 +98,12 @@ def init_tray(profile, settings, main_screen):
 | 
			
		|||
 | 
			
		||||
    show.triggered.connect(show_window)
 | 
			
		||||
    exit.triggered.connect(close_app)
 | 
			
		||||
    m.aboutToShow.connect(lambda: m.aboutToShowHandler())
 | 
			
		||||
    online.triggered.connect(lambda: m.newStatus(0))
 | 
			
		||||
    away.triggered.connect(lambda: m.newStatus(1))
 | 
			
		||||
    busy.triggered.connect(lambda: m.newStatus(2))
 | 
			
		||||
    menu.aboutToShow.connect(lambda: menu.aboutToShowHandler())
 | 
			
		||||
    online.triggered.connect(lambda: menu.newStatus(0))
 | 
			
		||||
    away.triggered.connect(lambda: menu.newStatus(1))
 | 
			
		||||
    busy.triggered.connect(lambda: menu.newStatus(2))
 | 
			
		||||
 | 
			
		||||
    tray.setContextMenu(m)
 | 
			
		||||
    tray.setContextMenu(menu)
 | 
			
		||||
    tray.show()
 | 
			
		||||
    tray.activated.connect(tray_activated)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,14 +118,8 @@ def start_update_if_needed(version, settings):
 | 
			
		|||
                download(version)
 | 
			
		||||
                updating = True
 | 
			
		||||
            else:
 | 
			
		||||
                reply = QtWidgets.QMessageBox.question(None,
 | 
			
		||||
                                                       'Toxygen',
 | 
			
		||||
                                                       QtWidgets.QApplication.translate("login",
 | 
			
		||||
                                                                                        'Update for Toxygen was found. Download and install it?'),
 | 
			
		||||
                                                       QtWidgets.QMessageBox.Yes,
 | 
			
		||||
                                                       QtWidgets.QMessageBox.No)
 | 
			
		||||
                if reply == QtWidgets.QMessageBox.Yes:
 | 
			
		||||
                reply = util_ui.question(util_ui.tr('Update for Toxygen was found. Download and install it?'))
 | 
			
		||||
                if reply:
 | 
			
		||||
                    download(version)
 | 
			
		||||
                    updating = True
 | 
			
		||||
 | 
			
		||||
    return updating
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import os
 | 
			
		|||
from util.util import log, curr_directory, append_slash
 | 
			
		||||
import pyaudio
 | 
			
		||||
from user_data.toxes import ToxES
 | 
			
		||||
import smileys_and_stickers as smileys
 | 
			
		||||
import smileys.smileys as smileys
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Settings(dict):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,10 +5,17 @@ def tr(s):
 | 
			
		|||
    return PyQt5.QtWidgets.QApplication.translate('Toxygen', s)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def question(text):
 | 
			
		||||
    reply = PyQt5.QtWidgets.QMessageBox.question(None, 'Toxygen', text,
 | 
			
		||||
def question(text, title=None):
 | 
			
		||||
    reply = PyQt5.QtWidgets.QMessageBox.question(None, title or 'Toxygen', text,
 | 
			
		||||
                                                 PyQt5.QtWidgets.QMessageBox.Yes,
 | 
			
		||||
                                                 PyQt5.QtWidgets.QMessageBox.No)
 | 
			
		||||
    return reply == PyQt5.QtWidgets.QMessageBox.Yes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def message_box(text, title=None):
 | 
			
		||||
    m_box = PyQt5.QtWidgets.QMessageBox()
 | 
			
		||||
    m_box.setText(tr(text))
 | 
			
		||||
    m_box.setWindowTitle(title or 'Toxygen')
 | 
			
		||||
    m_box.exec_()
 | 
			
		||||
 | 
			
		||||
# TODO: move all dialogs here
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,12 +35,33 @@ def get_base_directory(current_file=None):
 | 
			
		|||
    return os.path.dirname(curr_directory(current_file or __file__))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cached
 | 
			
		||||
def get_images_directory():
 | 
			
		||||
    return os.path.join(get_base_directory(), 'images')
 | 
			
		||||
    return get_app_directory('images')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cached
 | 
			
		||||
def get_styles_directory():
 | 
			
		||||
    return os.path.join(get_base_directory(), 'styles')
 | 
			
		||||
    return get_app_directory('styles')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cached
 | 
			
		||||
def get_sounds_directory():
 | 
			
		||||
    return get_app_directory('sounds')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cached
 | 
			
		||||
def get_stickers_directory():
 | 
			
		||||
    return get_app_directory('stickers')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cached
 | 
			
		||||
def get_translations_directory():
 | 
			
		||||
    return get_app_directory('translations')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_app_directory(directory_name):
 | 
			
		||||
    return os.path.join(get_base_directory(), directory_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_profile_name_from_path(path):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue