From dec4990d32a093e247b7e476d9f0da4aa7903148 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Wed, 18 Apr 2018 23:55:51 +0300 Subject: [PATCH] contacts minor refactoring --- toxygen/app.py | 22 +-- toxygen/av/calls.py | 16 +-- toxygen/av/calls_manager.py | 11 +- toxygen/contacts/basecontact.py | 25 ++-- toxygen/contacts/contact.py | 6 +- toxygen/contacts/contacts_manager.py | 201 +++++++++++++++++---------- toxygen/contacts/friend.py | 4 +- toxygen/contacts/group_chat.py | 16 +-- toxygen/contacts/profile.py | 64 +-------- toxygen/user_data/profile_manager.py | 2 +- toxygen/util/ui.py | 21 ++- toxygen/util/util.py | 4 + 12 files changed, 204 insertions(+), 188 deletions(-) diff --git a/toxygen/app.py b/toxygen/app.py index 85da363..e038980 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -22,7 +22,7 @@ class App: def __init__(self, version, path_to_profile=None, uri=None): self._version = version self._app = self._settings = self._profile_manager = self._plugin_loader = None - self._tox = self._ms = self._init = self.tray = self._main_loop = self._av_loop = None + self._tox = self._ms = self._init = 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:] @@ -63,15 +63,7 @@ class App: else: auto_profile = Settings.get_auto_profile() if auto_profile is None: # no default profile - # show login screen if default profile not found - self.load_login_screen_translations() - ls = LoginScreen() - ls.setWindowIconText("Toxygen") - profiles = ProfileManager.find_profiles() - ls.update_select(profiles) - ls.show() - self._app.exec_() - result = ls.result + result = self.select_profile() if result is None: return if result.is_new_profile(): # create new profile @@ -208,6 +200,16 @@ class App: def create_tox(self, data): return tox_factory(data, self._settings) + def select_profile(self): + self.load_login_screen_translations() + ls = LoginScreen() + profiles = ProfileManager.find_profiles() + ls.update_select(profiles) + ls.show() + self._app.exec_() + + return ls.result + def load_existing_profile(self, profile_path): self._settings = Settings(self._toxes, profile_path.replace('.tox', '.json')) self._profile_manager = ProfileManager(self._settings, self._toxes, profile_path) diff --git a/toxygen/av/calls.py b/toxygen/av/calls.py index 20684b2..3782318 100644 --- a/toxygen/av/calls.py +++ b/toxygen/av/calls.py @@ -1,12 +1,12 @@ import pyaudio import time import threading -from user_data import settings from wrapper.toxav_enums import * import cv2 import itertools import numpy as np from av import screen_sharing +from av.call import Call # TODO: play sound until outgoing call will be started or cancelled @@ -14,8 +14,9 @@ from av import screen_sharing class AV: - def __init__(self, toxav): + def __init__(self, toxav, settings): self._toxav = toxav + self._settings = settings self._running = True self._calls = {} # dict: key - friend number, value - Call instance @@ -118,7 +119,7 @@ class AV: rate=self._audio_rate, channels=self._audio_channels, input=True, - input_device_index=settings.Settings.get_instance().audio['input'], + input_device_index=self._settings.audio['input'], frames_per_buffer=self._audio_sample_count * 10) self._audio_thread = threading.Thread(target=self.send_audio) @@ -147,15 +148,14 @@ class AV: return self._video_running = True - s = settings.Settings.get_instance() self._video_width = s.video['width'] self._video_height = s.video['height'] if s.video['device'] == -1: - self._video = screen_sharing.DesktopGrabber(s.video['x'], s.video['y'], - s.video['width'], s.video['height']) + self._video = screen_sharing.DesktopGrabber(self._settings.video['x'], self._settings.video['y'], + self._settings.video['width'], self._settings.video['height']) else: - self._video = cv2.VideoCapture(s.video['device']) + self._video = cv2.VideoCapture(self._settings.video['device']) self._video.set(cv2.CAP_PROP_FPS, 25) self._video.set(cv2.CAP_PROP_FRAME_WIDTH, self._video_width) self._video.set(cv2.CAP_PROP_FRAME_HEIGHT, self._video_height) @@ -185,7 +185,7 @@ class AV: self._out_stream = self._audio.open(format=pyaudio.paInt16, channels=channels_count, rate=rate, - output_device_index=settings.Settings.get_instance().audio['output'], + output_device_index=self._settings.audio['output'], output=True) self._out_stream.write(samples) diff --git a/toxygen/av/calls_manager.py b/toxygen/av/calls_manager.py index 6cfe543..8060881 100644 --- a/toxygen/av/calls_manager.py +++ b/toxygen/av/calls_manager.py @@ -4,15 +4,16 @@ import av.calls from PyQt5 import QtWidgets from messenger.messages import * import time +from ui import av_widgets class CallsManager: - def __init__(self, tox): + def __init__(self, tox, settings): self._call = av.calls.AV(tox.AV) # object with data about calls self._call_widgets = {} # dict of incoming call widgets self._incoming_calls = set() - + self._settings = settings # ----------------------------------------------------------------------------------------------------------------- # AV support @@ -29,7 +30,7 @@ class CallsManager: if not self.is_active_a_friend(): return if num not in self._call and self.is_active_online(): # start call - if not Settings.get_instance().audio['enabled']: + if not self._settings.audio['enabled']: return self._call(num, audio, video) self._screen.active_call() @@ -47,7 +48,7 @@ class CallsManager: """ Incoming call from friend. """ - if not Settings.get_instance().audio['enabled']: + if not self._settings.audio['enabled']: return friend = self.get_friend_by_number(friend_number) if video: @@ -62,7 +63,7 @@ class CallsManager: self._messages.scrollToBottom() else: friend.actions = True - self._call_widgets[friend_number] = avwidgets.IncomingCallWidget(friend_number, text, friend.name) + self._call_widgets[friend_number] = av_widgets.IncomingCallWidget(friend_number, text, friend.name) self._call_widgets[friend_number].set_pixmap(friend.get_pixmap()) self._call_widgets[friend_number].show() diff --git a/toxygen/contacts/basecontact.py b/toxygen/contacts/basecontact.py index 34c100c..da992de 100644 --- a/toxygen/contacts/basecontact.py +++ b/toxygen/contacts/basecontact.py @@ -1,6 +1,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 class BaseContact: @@ -11,13 +12,14 @@ class BaseContact: Base class for all contacts. """ - def __init__(self, name, status_message, widget, tox_id): + def __init__(self, profile_manager, name, status_message, widget, tox_id): """ :param name: name, example: 'Toxygen user' :param status_message: status message, example: 'Toxing on Toxygen' :param widget: ContactItem instance :param tox_id: tox id of contact """ + self._profile_manager = profile_manager self._name, self._status_message = name, status_message self._status, self._widget = None, widget self._tox_id = tox_id @@ -81,11 +83,7 @@ class BaseContact: """ Tries to load avatar of contact or uses default avatar """ - return - prefix = ProfileManager.get_path() + 'avatars/' - avatar_path = prefix + '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) - if not os.path.isfile(avatar_path) or not os.path.getsize(avatar_path): # load default image - avatar_path = curr_directory() + '/images/avatar.png' + avatar_path = self.get_avatar_path() width = self._widget.avatar_label.width() pixmap = QtGui.QPixmap(avatar_path) self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio, @@ -93,13 +91,13 @@ class BaseContact: self._widget.avatar_label.repaint() def reset_avatar(self): - avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) + avatar_path = self.get_avatar_path() if os.path.isfile(avatar_path): os.remove(avatar_path) self.load_avatar() def set_avatar(self, avatar): - avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) + avatar_path = self.get_avatar_path() with open(avatar_path, 'wb') as f: f.write(avatar) self.load_avatar() @@ -107,6 +105,17 @@ class BaseContact: def get_pixmap(self): return self._widget.avatar_label.pixmap() + def get_avatar_path(self): + directory = util.join_path(self._profile_manager.get_path(), 'avatars') + avatar_path = util.join_path(directory, '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])) + if not os.path.isfile(avatar_path) or not os.path.getsize(avatar_path): # load default image + avatar_path = util.join_path(util.get_images_directory(), self.get_default_avatar_name()) + + return avatar_path + + @staticmethod + def get_default_avatar_name(): + return 'avatar.png' # ----------------------------------------------------------------------------------------------------------------- # Widgets # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/contacts/contact.py b/toxygen/contacts/contact.py index 22191a7..ecaeec2 100644 --- a/toxygen/contacts/contact.py +++ b/toxygen/contacts/contact.py @@ -1,6 +1,6 @@ from history.database import * from contacts import basecontact -import util +import util.util as util from messenger.messages import * from file_transfers import file_transfers as ft import re @@ -12,12 +12,12 @@ class Contact(basecontact.BaseContact): Properties: number, message getter, history etc. Base class for friend and gc classes """ - def __init__(self, message_getter, number, name, status_message, widget, tox_id): + def __init__(self, message_getter, number, profile_manager, name, status_message, widget, tox_id): """ :param message_getter: gets messages from db :param number: number of friend. """ - super().__init__(name, status_message, widget, tox_id) + super().__init__(profile_manager, name, status_message, widget, tox_id) self._number = number self._new_messages = False self._visible = True diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index 7653b56..122db5c 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -1,36 +1,56 @@ +import util.util as util +import util.ui as util_ui +from contacts.friend import Friend +import os +from PyQt5 import QtCore, QtGui, QtWidgets +from messenger.messages import * +from wrapper.toxcore_enums_and_consts import * +from network.tox_dns import tox_dns class ContactsManager: - def __init__(self, tox, settings, screen): + def __init__(self, tox, settings, screen, profile_manager): self._tox = tox self._settings = settings + self._screen = screen + self._profile_manager = profile_manager + self._messages = screen.messages self._contacts, self._active_friend = [], -1 self._sorting = settings['sorting'] - data = tox.self_get_friend_list() self._filter_string = '' self._friend_item_height = 40 if settings['compact_mode'] else 70 screen.online_contacts.setCurrentIndex(int(self._sorting)) - aliases = settings['friends_aliases'] - for i in data: # creates list of friends - tox_id = tox.friend_get_public_key(i) + self.load_contacts() + + def load_contacts(self): + self.load_friends() + self.load_groups() + if len(self._contacts): + self.set_active(0) + self.filtration_and_sorting(self._sorting) + + def load_friends(self): + aliases = self._settings['friends_aliases'] + friend_numbers = self._tox.self_get_friend_list() + for friend_number in friend_numbers: # creates list of friends + tox_id = self._tox.friend_get_public_key(friend_number) try: alias = list(filter(lambda x: x[0] == tox_id, aliases))[0][1] except: alias = '' item = self.create_friend_item() - name = alias or tox.friend_get_name(i) or tox_id - status_message = tox.friend_get_status_message(i) + name = alias or self._tox.friend_get_name(friend_number) or tox_id + status_message = self._tox.friend_get_status_message(i) if not self._history.friend_exists_in_db(tox_id): self._history.add_friend_to_db(tox_id) message_getter = self._history.messages_getter(tox_id) - friend = Friend(message_getter, i, name, status_message, item, tox_id) + friend = Friend(self._profile_manager, message_getter, friend_number, name, status_message, item, tox_id) friend.set_alias(alias) self._contacts.append(friend) - if len(self._contacts): - self.set_active(0) - self.filtration_and_sorting(self._sorting) + def load_groups(self): + pass def get_friend(self, num): if num < 0 or num >= len(self._contacts): @@ -40,6 +60,10 @@ class ContactsManager: def get_curr_friend(self): return self._contacts[self._active_friend] if self._active_friend + 1 else None + def save_profile(self): + data = self._tox.get_savedata() + self._profile_manager.save_profile(data) + # ----------------------------------------------------------------------------------------------------------------- # Work with active friend # ----------------------------------------------------------------------------------------------------------------- @@ -78,7 +102,7 @@ class ContactsManager: self._screen.messageEdit.setPlainText(friend.curr_text) self._active_friend = value friend.reset_messages() - if not Settings.get_instance()['save_history']: + if not self._settings['save_history']: friend.delete_old_messages() self._messages.clear() friend.load_corr() @@ -128,19 +152,14 @@ class ContactsManager: self._screen.account_name.setText(friend.name) self._screen.account_status.setText(friend.status_message) self._screen.account_status.setToolTip(friend.get_full_status()) - if friend.tox_id is None: - avatar_path = curr_directory() + '/images/group.png' - else: - avatar_path = (ProfileManager.get_path() + 'avatars/{}.png').format(friend.tox_id[:TOX_PUBLIC_KEY_SIZE * 2]) - if not os.path.isfile(avatar_path): # load default image - avatar_path = curr_directory() + '/images/avatar.png' + avatar_path = friend.get_avatar_path() os.chdir(os.path.dirname(avatar_path)) pixmap = QtGui.QPixmap(avatar_path) self._screen.account_avatar.setPixmap(pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)) except Exception as ex: # no friend found. ignore - log('Friend value: ' + str(value)) - log('Error in set active: ' + str(ex)) + util.log('Friend value: ' + str(value)) + util.log('Error in set active: ' + str(ex)) raise def set_active_by_number_and_type(self, number, is_friend): @@ -167,7 +186,6 @@ class ContactsManager: :param filter_str: show contacts which name contains this substring """ filter_str = filter_str.lower() - settings = Settings.get_instance() number = self.get_active_number() is_friend = self.is_active_a_friend() if sorting > 1: @@ -203,8 +221,8 @@ class ContactsManager: else: self._screen.friends_list.item(index).setSizeHint(QtCore.QSize(250, 0)) self._sorting, self._filter_string = sorting, filter_str - settings['sorting'] = self._sorting - settings.save() + self._settings['sorting'] = self._sorting + self._settings.save() self.set_active_by_number_and_type(number, is_friend) def update_filtration(self): @@ -213,7 +231,6 @@ class ContactsManager: """ self.filtration_and_sorting(self._sorting, self._filter_string) - def create_friend_item(self): """ Method-factory @@ -221,7 +238,42 @@ class ContactsManager: """ return self._factory.friend_item() + # ----------------------------------------------------------------------------------------------------------------- + # Friend getters + # ----------------------------------------------------------------------------------------------------------------- + def get_friend_by_number(self, num): + return list(filter(lambda x: x.number == num and type(x) is Friend, self._contacts))[0] + + def get_last_message(self): + if self._active_friend + 1: + return self.get_curr_friend().get_last_message_text() + else: + return '' + + def get_active_number(self): + return self.get_curr_friend().number if self._active_friend + 1 else -1 + + def get_active_name(self): + return self.get_curr_friend().name if self._active_friend + 1 else '' + + def is_active_online(self): + return self._active_friend + 1 and self.get_curr_friend().status is not None + + def new_name(self, number, name): + friend = self.get_friend_by_number(number) + tmp = friend.name + friend.set_name(name) + name = str(name, 'utf-8') + if friend.name == name and tmp != name: + message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}') + message = message.format(tmp, name) + friend.append_message(InfoMessage(message, time.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) @@ -233,19 +285,11 @@ class ContactsManager: """ friend = self._contacts[num] name = friend.name - dialog = QtWidgets.QApplication.translate('MainWindow', - "Enter new alias for friend {} or leave empty to use friend's name:") - dialog = dialog.format(name) - title = QtWidgets.QApplication.translate('MainWindow', - 'Set alias') - text, ok = QtWidgets.QInputDialog.getText(None, - title, - dialog, - QtWidgets.QLineEdit.Normal, - name) + text = util_ui.tr("Enter new alias for friend {} or leave empty to use friend's name:").format(name) + title = util_ui.tr('Set alias') + text, ok = util_ui.text_dialog(text, title, name) if ok: - settings = Settings.get_instance() - aliases = settings['friends_aliases'] + aliases = self._settings['friends_aliases'] if text: friend.name = bytes(text, 'utf-8') try: @@ -262,7 +306,7 @@ class ContactsManager: del aliases[index] except: pass - settings.save() + self._settings.save() if num == self.get_active_number() and self.is_active_a_friend(): self.update() @@ -275,15 +319,14 @@ class ContactsManager: :param num: number of friend in list """ friend = self._contacts[num] - settings = Settings.get_instance() try: - index = list(map(lambda x: x[0], settings['friends_aliases'])).index(friend.tox_id) - del settings['friends_aliases'][index] + index = list(map(lambda x: x[0], self._settings['friends_aliases'])).index(friend.tox_id) + del self._settings['friends_aliases'][index] except: pass - if friend.tox_id in settings['notes']: - del settings['notes'][friend.tox_id] - settings.save() + if friend.tox_id in self._settings['notes']: + del self._settings['notes'][friend.tox_id] + self._settings.save() self.clear_history(num) if self._history.friend_exists_in_db(friend.tox_id): self._history.delete_friend_from_db(friend.tox_id) @@ -296,7 +339,7 @@ class ContactsManager: else: self.set_active(0) data = self._tox.get_savedata() - ProfileManager.get_instance().save_profile(data) + self._profile_manager.save_profile(data) def add_friend(self, tox_id): """ @@ -309,7 +352,7 @@ class ContactsManager: self._history.add_friend_to_db(tox_id) message_getter = self._history.messages_getter(tox_id) except Exception as ex: # something is wrong - log('Accept friend request failed! ' + str(ex)) + util.log('Accept friend request failed! ' + str(ex)) message_getter = None friend = Friend(message_getter, num, tox_id, '', item, tox_id) self._contacts.append(friend) @@ -319,17 +362,15 @@ class ContactsManager: Block user with specified tox id (or public key) - delete from friends list and ignore friend requests """ tox_id = tox_id[:TOX_PUBLIC_KEY_SIZE * 2] - if tox_id == self.tox_id[:TOX_PUBLIC_KEY_SIZE * 2]: + if tox_id == self._tox.self_get_address[:TOX_PUBLIC_KEY_SIZE * 2]: return - settings = Settings.get_instance() - if tox_id not in settings['blocked']: - settings['blocked'].append(tox_id) - settings.save() + if tox_id not in self._settings['blocked']: + self._settings['blocked'].append(tox_id) + self._settings.save() try: num = self._tox.friend_by_public_key(tox_id) self.delete_friend(num) - data = self._tox.get_savedata() - ProfileManager.get_instance().save_profile(data) + self.save_profile() except: # not in friend list pass @@ -339,13 +380,11 @@ class ContactsManager: :param tox_id: tox id of contact :param add_to_friend_list: add this contact to friend list or not """ - s = Settings.get_instance() - s['blocked'].remove(tox_id) - s.save() + self._settings['blocked'].remove(tox_id) + self._settings.save() if add_to_friend_list: self.add_friend(tox_id) - data = self._tox.get_savedata() - ProfileManager.get_instance().save_profile(data) + self.save_profile() # ----------------------------------------------------------------------------------------------------------------- # Friend requests @@ -366,11 +405,9 @@ class ContactsManager: raise Exception('TOX DNS lookup failed') if len(tox_id) == TOX_PUBLIC_KEY_SIZE * 2: # public key self.add_friend(tox_id) - msgBox = QtWidgets.QMessageBox() - msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Friend added")) - text = (QtWidgets.QApplication.translate("MainWindow", 'Friend added without sending friend request')) - msgBox.setText(text) - msgBox.exec_() + title = util_ui.tr('Friend added') + text = util_ui.tr('Friend added without sending friend request') + util_ui.message_box(text, title) else: result = self._tox.friend_add(tox_id, message.encode('utf-8')) tox_id = tox_id[:TOX_PUBLIC_KEY_SIZE * 2] @@ -380,11 +417,10 @@ class ContactsManager: message_getter = self._history.messages_getter(tox_id) friend = Friend(message_getter, result, tox_id, '', item, tox_id) self._contacts.append(friend) - data = self._tox.get_savedata() - ProfileManager.get_instance().save_profile(data) + self.save_profile() return True except Exception as ex: # wrong data - log('Friend request failed with ' + str(ex)) + util.log('Friend request failed with ' + str(ex)) return str(ex) def process_friend_request(self, tox_id, message): @@ -396,13 +432,34 @@ class ContactsManager: if tox_id in self._settings['blocked']: return try: - text = QtWidgets.QApplication.translate('MainWindow', 'User {} wants to add you to contact list. Message:\n{}') - info = text.format(tox_id, message) - fr_req = QtWidgets.QApplication.translate('MainWindow', 'Friend request') - reply = QtWidgets.QMessageBox.question(None, fr_req, info, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) - if reply == QtWidgets.QMessageBox.Yes: # accepted + text = util_ui.tr('User {} wants to add you to contact list. Message:\n{}') + reply = util_ui.question(text.format(tox_id, message), util_ui.tr('Friend request')) + if reply: # accepted self.add_friend(tox_id) data = self._tox.get_savedata() - ProfileManager.get_instance().save_profile(data) + self._profile_manager.save_profile(data) except Exception as ex: # something is wrong - log('Accept friend request failed! ' + str(ex)) + util.log('Accept friend request failed! ' + str(ex)) + + # ----------------------------------------------------------------------------------------------------------------- + # Typing notifications + # ----------------------------------------------------------------------------------------------------------------- + + def send_typing(self, typing): + """ + Send typing notification to a friend + """ + if self._settings['typing_notifications'] and self._active_friend + 1: + try: + friend = self.get_curr_friend() + if friend.status is not None: + self._tox.self_set_typing(friend.number, typing) + except: + pass + + def friend_typing(self, friend_number, typing): + """ + Display incoming typing notification + """ + if friend_number == self.get_active_number() and self.is_active_a_friend(): + self._screen.typing.setVisible(typing) diff --git a/toxygen/contacts/friend.py b/toxygen/contacts/friend.py index b80032a..4a22329 100644 --- a/toxygen/contacts/friend.py +++ b/toxygen/contacts/friend.py @@ -8,8 +8,8 @@ class Friend(contact.Contact): Friend in list of friends. """ - def __init__(self, message_getter, number, name, status_message, widget, tox_id): - super().__init__(message_getter, number, name, status_message, widget, tox_id) + def __init__(self, profile_manager, message_getter, number, name, status_message, widget, tox_id): + super().__init__(profile_manager, message_getter, number, name, status_message, widget, tox_id) self._receipts = 0 # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index 05faaa9..b247281 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -1,5 +1,5 @@ from contacts import contact -import util +import util.util as util from PyQt5 import QtGui, QtCore from wrapper import toxcore_enums_and_consts as constants @@ -8,8 +8,8 @@ from wrapper import toxcore_enums_and_consts as constants class GroupChat(contact.Contact): - def __init__(self, name, status_message, widget, tox, group_number): - super().__init__(None, group_number, name, status_message, widget, None) + def __init__(self, profile_manager, name, status_message, widget, tox, group_number): + super().__init__(None, group_number, profile_manager, name, status_message, widget, None) self._tox = tox self.set_status(constants.TOX_USER_STATUS['NONE']) @@ -23,13 +23,9 @@ class GroupChat(contact.Contact): def new_title(self, title): super().set_name(title) - def load_avatar(self): - path = util.curr_directory() + '/images/group.png' - width = self._widget.avatar_label.width() - pixmap = QtGui.QPixmap(path) - self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio, - QtCore.Qt.SmoothTransformation)) - self._widget.avatar_label.repaint() + @staticmethod + def get_default_avatar_name(): + return 'group.png' def remove_invalid_unsent_files(self): pass diff --git a/toxygen/contacts/profile.py b/toxygen/contacts/profile.py index ef26a51..a107602 100644 --- a/toxygen/contacts/profile.py +++ b/toxygen/contacts/profile.py @@ -22,12 +22,13 @@ class Profile(basecontact.BaseContact): """ Profile of current toxygen user. Contains friends list, tox instance """ - def __init__(self, tox, screen): + def __init__(self, profile_manager, tox, screen): """ :param tox: tox instance :param screen: ref to main screen """ basecontact.BaseContact.__init__(self, + profile_manager, tox.self_get_name(), tox.self_get_status_message(), screen.user_info, @@ -86,43 +87,6 @@ class Profile(basecontact.BaseContact): self._tox_id = self._tox.self_get_address() return self._tox_id - # ----------------------------------------------------------------------------------------------------------------- - # Friend getters - # ----------------------------------------------------------------------------------------------------------------- - - def get_friend_by_number(self, num): - return list(filter(lambda x: x.number == num and type(x) is Friend, self._contacts))[0] - - def get_last_message(self): - if self._active_friend + 1: - return self.get_curr_friend().get_last_message_text() - else: - return '' - - def get_active_number(self): - return self.get_curr_friend().number if self._active_friend + 1 else -1 - - def get_active_name(self): - return self.get_curr_friend().name if self._active_friend + 1 else '' - - def is_active_online(self): - return self._active_friend + 1 and self.get_curr_friend().status is not None - - def new_name(self, number, name): - friend = self.get_friend_by_number(number) - tmp = friend.name - friend.set_name(name) - name = str(name, 'utf-8') - if friend.name == name and tmp != name: - message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}') - message = message.format(tmp, name) - friend.append_message(InfoMessage(message, time.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) - # ----------------------------------------------------------------------------------------------------------------- # Friend connection status callbacks # ----------------------------------------------------------------------------------------------------------------- @@ -168,29 +132,6 @@ class Profile(basecontact.BaseContact): self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, True, ft.total_size()] self.cancel_transfer(friend_num, file_num, True) - # ----------------------------------------------------------------------------------------------------------------- - # Typing notifications - # ----------------------------------------------------------------------------------------------------------------- - - def send_typing(self, typing): - """ - Send typing notification to a friend - """ - if Settings.get_instance()['typing_notifications'] and self._active_friend + 1: - try: - friend = self.get_curr_friend() - if friend.status is not None: - self._tox.self_set_typing(friend.number, typing) - except: - pass - - def friend_typing(self, friend_number, typing): - """ - Display incoming typing notification - """ - if friend_number == self.get_active_number() and self.is_active_a_friend(): - self._screen.typing.setVisible(typing) - # ----------------------------------------------------------------------------------------------------------------- # Private messages # ----------------------------------------------------------------------------------------------------------------- @@ -294,7 +235,6 @@ class Profile(basecontact.BaseContact): # Friend, message and file transfer items creation # ----------------------------------------------------------------------------------------------------------------- - def create_message_item(self, text, time, owner, message_type, append=True): if message_type == MESSAGE_TYPE['INFO_MESSAGE']: name = '' diff --git a/toxygen/user_data/profile_manager.py b/toxygen/user_data/profile_manager.py index b897fc3..823dbc0 100644 --- a/toxygen/user_data/profile_manager.py +++ b/toxygen/user_data/profile_manager.py @@ -13,7 +13,7 @@ class ProfileManager: self._path = path self._directory = os.path.basename(path) # create /avatars if not exists: - directory = path + 'avatars' + directory = util.join_path(self._directory, 'avatars') if not os.path.exists(directory): os.makedirs(directory) diff --git a/toxygen/util/ui.py b/toxygen/util/ui.py index c485de4..4b9e806 100644 --- a/toxygen/util/ui.py +++ b/toxygen/util/ui.py @@ -1,21 +1,28 @@ -import PyQt5 +from PyQt5 import QtWidgets def tr(s): - return PyQt5.QtWidgets.QApplication.translate('Toxygen', s) + return QtWidgets.QApplication.translate('Toxygen', s) 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 + reply = QtWidgets.QMessageBox.question(None, title or 'Toxygen', text, + QtWidgets.QMessageBox.Yes, + QtWidgets.QMessageBox.No) + return reply == QtWidgets.QMessageBox.Yes def message_box(text, title=None): - m_box = PyQt5.QtWidgets.QMessageBox() + m_box = QtWidgets.QMessageBox() m_box.setText(tr(text)) m_box.setWindowTitle(title or 'Toxygen') m_box.exec_() + +def text_dialog(text, title='', default_value=''): + text, ok = QtWidgets.QInputDialog.getText(None, title, text, QtWidgets.QLineEdit.Normal, default_value) + + return text, ok + + # TODO: move all dialogs here diff --git a/toxygen/util/util.py b/toxygen/util/util.py index 5bf5f99..61df479 100644 --- a/toxygen/util/util.py +++ b/toxygen/util/util.py @@ -79,6 +79,10 @@ def curr_time(): return time.strftime('%H:%M') +def join_path(a, b): + return os.path.join(a, b) + + def copy(src, dest): if not os.path.exists(dest): os.makedirs(dest)