statuses fixed. events added.

This commit is contained in:
ingvar1995 2018-05-05 00:09:33 +03:00
parent c8443b56dd
commit ae903cf405
14 changed files with 126 additions and 47 deletions

View file

@ -27,6 +27,7 @@ from ui.widgets_factory import WidgetsFactory
from smileys.smileys import SmileyLoader
from ui.items_factory import ItemsFactory
from messenger.messenger import Messenger
from network.tox_dns import ToxDns
class App:
@ -36,7 +37,7 @@ class App:
self._app = self._settings = self._profile_manager = self._plugin_loader = self._messenger = None
self._tox = self._ms = self._init = self._main_loop = self._av_loop = None
self._uri = self._toxes = self._tray = self._file_transfer_handler = self._contacts_provider = None
self._friend_factory = self._calls_manager = self._contacts_manager = self._smiley_loader = None
self._friend_factory = self._calls_manager = self._contacts_manager = self._smiley_loader = self._tox_dns = None
if uri is not None and uri.startswith('tox:'):
self._uri = uri[4:]
self._path = path_to_profile
@ -114,9 +115,6 @@ class App:
while True:
try:
self._app.exec_()
except KeyboardInterrupt:
print('Closing Toxygen...')
break
except Exception as ex:
util.log('Unhandled exception: ' + str(ex))
else:
@ -288,6 +286,7 @@ class App:
def _create_dependencies(self):
self._smiley_loader = SmileyLoader(self._settings)
self._tox_dns = ToxDns(self._settings)
self._ms = MainWindow(self._settings, self._tray)
self._calls_manager = CallsManager(self._tox.AV, self._settings)
db = Database(self._path.replace('.tox', '.db'), self._toxes)
@ -298,10 +297,11 @@ class App:
self._friend_factory = FriendFactory(self._profile_manager, self._settings, self._tox, db, items_factory)
self._contacts_provider = ContactProvider(self._tox, self._friend_factory)
self._contacts_manager = ContactsManager(self._tox, self._settings, self._ms, self._profile_manager,
self._contacts_provider, db)
self._contacts_provider, db, self._tox_dns)
self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider)
widgets_factory = WidgetsFactory(self._settings, profile, self._contacts_manager, self._file_transfer_handler,
self._smiley_loader, self._plugin_loader, self._toxes, self._version)
widgets_factory = WidgetsFactory(self._settings, profile, self._profile_manager, self._contacts_manager,
self._file_transfer_handler, self._smiley_loader, self._plugin_loader,
self._toxes, self._version)
self._messenger = Messenger(self._tox, self._plugin_loader, self._ms, self._contacts_manager,
self._contacts_provider, items_factory, profile)
self._tray = tray.init_tray(profile, self._settings, self._ms)

View file

22
toxygen/common/event.py Normal file
View file

@ -0,0 +1,22 @@
class Event:
def __init__(self):
self._callbacks = set()
def __iadd__(self, callback):
self._callbacks.add(callback)
def __isub__(self, callback):
self.remove_callback(callback)
def __call__(self, *args, **kwargs):
for callback in self._callbacks:
callback(*args, **kwargs)
def add_callback(self, callback):
self._callbacks.add(callback)
def remove_callback(self, callback):
self._callbacks.discard(callback)

View file

@ -2,6 +2,7 @@ from user_data.settings import *
from PyQt5 import QtCore, QtGui
from wrapper.toxcore_enums_and_consts import TOX_PUBLIC_KEY_SIZE
import util.util as util
import common.event as event
class BaseContact:
@ -24,6 +25,9 @@ class BaseContact:
self._status, self._widget = None, widget
self._tox_id = tox_id
self.init_widget()
self._name_changed_event = event.Event()
self._status_message_changed_event = event.Event()
self._status_changed_event = event.Event()
# -----------------------------------------------------------------------------------------------------------------
# Name - current name or alias of user
@ -33,12 +37,20 @@ class BaseContact:
return self._name
def set_name(self, value):
self._name = str(value, 'utf-8')
self._widget.name.setText(self._name)
self._widget.name.repaint()
value = str(value, 'utf-8')
if self._name != value:
self._name = value
self._widget.name.setText(self._name)
self._widget.name.repaint()
self._name_changed_event(self._name)
name = property(get_name, set_name)
def get_name_changed_event(self):
return self._name_changed_event
name_changed_event = property(get_name_changed_event)
# -----------------------------------------------------------------------------------------------------------------
# Status message
# -----------------------------------------------------------------------------------------------------------------
@ -47,12 +59,20 @@ class BaseContact:
return self._status_message
def set_status_message(self, value):
self._status_message = str(value, 'utf-8')
self._widget.status_message.setText(self._status_message)
self._widget.status_message.repaint()
value = str(value, 'utf-8')
if self._status_message != value:
self._status_message = value
self._widget.status_message.setText(self._status_message)
self._widget.status_message.repaint()
self._status_message_changed_event(self._status_message)
status_message = property(get_status_message, set_status_message)
def get_status_message_changed_event(self):
return self._status_message_changed_event
status_message_changed_event = property(get_status_message_changed_event)
# -----------------------------------------------------------------------------------------------------------------
# Status
# -----------------------------------------------------------------------------------------------------------------
@ -61,11 +81,18 @@ class BaseContact:
return self._status
def set_status(self, value):
self._status = value
self._widget.connection_status.update(value)
if self._status != value:
self._status = value
self._widget.connection_status.update(value)
self._status_changed_event(self._status)
status = property(get_status, set_status)
def get_status_changed_event(self):
return self._status_changed_event
status_changed_event = property(get_status_changed_event)
# -----------------------------------------------------------------------------------------------------------------
# TOX ID. WARNING: for friend it will return public key, for profile - full address
# -----------------------------------------------------------------------------------------------------------------

View file

@ -12,12 +12,13 @@ class ContactsManager:
Represents contacts list.
"""
def __init__(self, tox, settings, screen, profile_manager, contact_provider, db):
def __init__(self, tox, settings, screen, profile_manager, contact_provider, db, tox_dns):
self._tox = tox
self._settings = settings
self._screen = screen
self._profile_manager = profile_manager
self._contact_provider = contact_provider
self._tox_dns = tox_dns
self._messages = screen.messages
self._contacts, self._active_contact = [], -1
self._sorting = settings['sorting']
@ -74,13 +75,17 @@ class ContactsManager:
try:
# self.send_typing(False) # TODO: fix
self._screen.typing.setVisible(False)
current_contact = self.get_curr_contact()
if current_contact is not None:
self._unsubscribe_from_events(current_contact)
if value is not None:
if self._active_contact + 1 and self._active_contact != value:
try:
self.get_curr_contact().curr_text = self._screen.messageEdit.toPlainText()
current_contact.curr_text = self._screen.messageEdit.toPlainText()
except:
pass
friend = self._contacts[value]
self._subscribe_to_events(friend)
friend.remove_invalid_unsent_files()
if self._active_contact != value:
self._screen.messageEdit.setPlainText(friend.curr_text)
@ -133,8 +138,7 @@ class ContactsManager:
else:
friend = self.get_curr_contact()
# TODO: to separate method
self._screen.account_name.setText(friend.name)
self._screen.account_status.setText(friend.status_message)
self._screen.account_status.setToolTip(friend.get_full_status())
avatar_path = friend.get_avatar_path()
pixmap = QtGui.QPixmap(avatar_path)
@ -244,14 +248,15 @@ class ContactsManager:
friend.set_name(name)
name = str(name, 'utf-8')
if friend.name == name and tmp != name:
# TODO: move to friend?
message = util_ui.tr('User {} is now known as {}')
message = message.format(tmp, name)
friend.append_message(InfoMessage(0, message, util.get_unix_time()))
friend.actions = True
if number == self.get_active_number():
self.create_message_item(message, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE'])
self._messages.scrollToBottom()
self.set_active(None)
# message = message.format(tmp, name)
# friend.append_message(InfoMessage(0, message, util.get_unix_time()))
# friend.actions = True
# if number == self.get_active_number():
# self.create_message_item(message, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE'])
# self._messages.scrollToBottom()
# self.set_active(None)
# -----------------------------------------------------------------------------------------------------------------
# Work with friends (remove, block, set alias, get public key)
@ -369,7 +374,7 @@ class ContactsManager:
try:
message = message or 'Hello! Add me to your contact list please'
if '@' in tox_id: # value like groupbot@toxme.io
tox_id = tox_dns(tox_id)
tox_id = self._tox_dns.lookup(tox_id)
if tox_id is None:
raise Exception('TOX DNS lookup failed')
if len(tox_id) == TOX_PUBLIC_KEY_SIZE * 2: # public key
@ -428,3 +433,16 @@ class ContactsManager:
def _load_groups(self):
self._contacts.extend(self._contact_provider.get_all_groups())
# -----------------------------------------------------------------------------------------------------------------
# Current contact subscriptions
# -----------------------------------------------------------------------------------------------------------------
def _subscribe_to_events(self, contact):
contact.name_changed_event.add_callback(self._current_contact_name_changed)
def _unsubscribe_from_events(self, contact):
contact.name_changed_event.remove_callback(self._current_contact_name_changed)
def _current_contact_name_changed(self, name):
self._screen.account_name.setText(name)

View file

@ -1,7 +1,6 @@
from file_transfers.file_transfers import *
from messenger.messages import *
from history.database import MESSAGE_AUTHOR
import os
from ui.list_items import *
from PyQt5 import QtWidgets
import util.util as util

View file

@ -3,6 +3,8 @@ from wrapper.toxcore_enums_and_consts import *
from messenger.messages import *
# TODO: sub profile name changed event?
class Messenger(util.ToxSave):
def __init__(self, tox, plugin_loader, screen, contacts_manager, contacts_provider, items_factory, profile):
@ -100,6 +102,13 @@ class Messenger(util.ToxSave):
except Exception as ex:
util.log('Sending pending messages failed with ' + str(ex))
# -----------------------------------------------------------------------------------------------------------------
# Message receipts
# -----------------------------------------------------------------------------------------------------------------
def receipt(self, friend_number, message_id):
pass # TODO: process
# -----------------------------------------------------------------------------------------------------------------
# Typing notifications
# -----------------------------------------------------------------------------------------------------------------

View file

@ -12,7 +12,7 @@ from middleware.threads import invoke_in_main_thread, execute
from notifications.tray import tray_notification
from notifications.sound import *
# TODO: gc callbacks and refactoring
# TODO: gc callbacks and refactoring. Use contact provider instead of manager
# -----------------------------------------------------------------------------------------------------------------
# Callbacks - current user
@ -140,11 +140,9 @@ def friend_typing(messenger):
return wrapped
def friend_read_receipt(contacts_manager):
def friend_read_receipt(messenger):
def wrapped(tox, friend_number, message_id, user_data):
contacts_manager.get_friend_by_number(friend_number).dec_receipt()
if friend_number == contacts_manager.get_active_number():
invoke_in_main_thread(contacts_manager.receipt)
invoke_in_main_thread(messenger.receipt, friend_number, message_id)
return wrapped
@ -398,7 +396,7 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager,
tox.callback_friend_status_message(friend_status_message(contacts_manager, messenger), 0)
tox.callback_friend_request(friend_request(contacts_manager), 0)
tox.callback_friend_typing(friend_typing(messenger), 0)
tox.callback_friend_read_receipt(friend_read_receipt(contacts_manager), 0)
tox.callback_friend_read_receipt(friend_read_receipt(messenger), 0)
# file transfer
tox.callback_file_recv(tox_file_recv(main_window, tray, profile, file_transfer_handler,

View file

@ -13,10 +13,6 @@ class ItemsFactory:
self._friends_list = main_screen.friends_list
self._message_edit = main_screen.messageEdit
def _create_message_browser(self, text, width, message_type, parent=None):
return MessageBrowser(self._settings, self._message_edit, self._smiley_loader, self._plugin_loader,
text, width, message_type, parent)
def friend_item(self):
item = ContactItem(self._settings)
elem = QtWidgets.QListWidgetItem(self._friends_list)
@ -75,3 +71,7 @@ class ItemsFactory:
self._messages.insertItem(0, elem)
self._messages.setItemWidget(elem, item)
return item
def _create_message_browser(self, text, width, message_type, parent=None):
return MessageBrowser(self._settings, self._message_edit, self._smiley_loader, self._plugin_loader,
text, width, message_type, parent)

View file

@ -71,7 +71,7 @@ class StatusCircle(QtWidgets.QWidget):
self.label.setGeometry(QtCore.QRect(0, 0, 32, 32))
else:
self.label.setGeometry(QtCore.QRect(2, 0, 32, 32))
pixmap = QtGui.QPixmap(curr_directory() + '/images/{}.png'.format(name))
pixmap = QtGui.QPixmap(join_path(get_images_directory(), '{}.png'.format(name)))
self.label.setPixmap(pixmap)
@ -121,6 +121,7 @@ class FileTransferItem(QtWidgets.QListWidget):
self.name.setGeometry(QtCore.QRect(3, 7, 95, 25))
self.name.setTextFormat(QtCore.Qt.PlainText)
font = QtGui.QFont()
# FIXME
font.setFamily(settings.Settings.get_instance()['font'])
font.setPointSize(11)
font.setBold(True)
@ -281,7 +282,7 @@ class UnsentFileItem(FileTransferItem):
TOX_FILE_TRANSFER_STATE['PAUSED_BY_FRIEND'], width, parent)
self._time = time
self.pb.setVisible(False)
movie = QtGui.QMovie(curr_directory() + '/images/spinner.gif')
movie = QtGui.QMovie(join_path(get_images_directory(), 'spinner.gif'))
self.time.setMovie(movie)
movie.start()
@ -331,6 +332,7 @@ class InlineImageItem(QtWidgets.QScrollArea):
self._full_size = not self._full_size
self._elem.setSizeHint(QtCore.QSize(self.width(), self.height()))
elif event.button() == QtCore.Qt.RightButton: # save inline
# TODO: dialog
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow",
'Choose folder'),

View file

@ -444,7 +444,7 @@ class MainWindow(QtWidgets.QMainWindow):
def create_gc(self):
self.profile.create_group_chat()
def profile_settings(self):
def profile_settings(self, *args):
self._modal_window = self._widget_factory.create_profile_settings_window()
self._modal_window.show()

View file

@ -84,9 +84,10 @@ class AddContact(CenteredWidget):
class ProfileSettings(CenteredWidget):
"""Form with profile settings such as name, status, TOX ID"""
def __init__(self, profile, settings, toxes):
def __init__(self, profile, profile_manager, settings, toxes):
super().__init__()
self._profile = profile
self._profile_manager = profile_manager
self._settings = settings
self._toxes = toxes
self.initUI()
@ -166,7 +167,7 @@ class ProfileSettings(CenteredWidget):
self.default = QtWidgets.QPushButton(self)
self.default.setGeometry(QtCore.QRect(40, 550, 620, 30))
auto_profile = Settings.get_auto_profile()
self.auto = path + name == ProfileManager.get_path() + Settings.get_instance().name
# self.auto = path + name == ProfileManager.get_path() + Settings.get_instance().name
self.default.clicked.connect(self.auto_profile)
self.retranslateUi()
if self._profile.status is not None:
@ -243,7 +244,7 @@ class ProfileSettings(CenteredWidget):
self.copy_pk.setIconSize(QtCore.QSize(10, 10))
def new_no_spam(self):
self.tox_id.setText(Profile.get_instance().new_nospam())
self.tox_id.setText(self._profile.new_nospam())
def reset_avatar(self):
self._profile.reset_avatar()

View file

@ -4,10 +4,11 @@ from ui.menu import *
class WidgetsFactory:
def __init__(self, settings, profile, contacts_manager, file_transfer_handler, smiley_loader, plugin_loader,
toxes, version):
def __init__(self, settings, profile, profile_manager, contacts_manager, file_transfer_handler, smiley_loader,
plugin_loader, toxes, version):
self._settings = settings
self._profile = profile
self._profile_manager = profile_manager
self._contacts_manager = contacts_manager
self._file_transfer_handler = file_transfer_handler
self._smiley_loader = smiley_loader
@ -25,7 +26,7 @@ class WidgetsFactory:
return WelcomeScreen(self._settings)
def create_profile_settings_window(self):
return ProfileSettings(self._profile, self._settings, self._toxes)
return ProfileSettings(self._profile, self._profile_manager, self._settings, self._toxes)
def create_network_settings_window(self):
return NetworkSettings(self._settings, self._profile.reset)

View file

@ -158,6 +158,8 @@ def get_platform():
return platform.system()
# TODO: to common
class ToxSave:
def __init__(self, tox):