From 633b8f9561b0ee7ca317a4ff3cb8a513b7b7c93c Mon Sep 17 00:00:00 2001 From: emdee Date: Sat, 8 Oct 2022 17:59:45 +0000 Subject: [PATCH] trying to fix group addition --- .gitignore | 1 - toxygen/app.py | 133 ++++++++++++++------------- toxygen/contacts/contact_provider.py | 20 +++- toxygen/contacts/contacts_manager.py | 33 +++++-- toxygen/contacts/group_chat.py | 1 + toxygen/contacts/group_factory.py | 6 ++ toxygen/groups/groups_service.py | 24 ++++- toxygen/main.py | 7 +- toxygen/messenger/messenger.py | 5 +- toxygen/middleware/callbacks.py | 46 ++++++--- toxygen/notifications/tray.py | 2 +- toxygen/styles/light_style.qss | 19 ---- toxygen/ui/group_invites_widgets.py | 5 + toxygen/ui/main_screen.py | 104 +++++++++++++++++---- 14 files changed, 271 insertions(+), 135 deletions(-) delete mode 100644 toxygen/styles/light_style.qss diff --git a/.gitignore b/.gitignore index 6d1e7dd..0a8182a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ Toxygen.egg-info .cache *.db -.pylint.sh diff --git a/toxygen/app.py b/toxygen/app.py index b81b779..d596d6e 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -9,11 +9,9 @@ from time import sleep from gevent import monkey; monkey.patch_all(); del monkey # noqa import gevent -import wrapper_tests.support_testing as ts -from wrapper_tests.tests_wrapper import bootstrap_iNodeInfo -from user_data import settings - -IDLE_PERIOD = 0.10 +from PyQt5 import QtWidgets, QtGui, QtCore +from qtpy.QtCore import QTimer +from qtpy.QtWidgets import QApplication try: import coloredlogs @@ -23,9 +21,66 @@ try: except ImportError as e: coloredlogs = False +try: + # https://github.com/pyqtconsole/pyqtconsole + from pyqtconsole.console import PythonConsole +except Exception as e: + PythonConsole = None + +try: + import qdarkstylexxx +except ImportError: + qdarkstyle = None + +from middleware import threads +import middleware.callbacks as callbacks +import updater.updater as updater +from middleware.tox_factory import tox_factory +import wrapper.toxencryptsave as tox_encrypt_save +import user_data.toxes +from user_data import settings +from user_data.settings import get_user_config_path, merge_args_into_settings +from user_data.settings import Settings +from user_data.profile_manager import ProfileManager + +from plugin_support.plugin_support import PluginLoader + +import ui.password_screen as password_screen +from ui.login_screen import LoginScreen +from ui.main_screen import MainWindow +from ui import tray + +import utils.ui as util_ui +import utils.util as util +from av.calls_manager import CallsManager +from common.provider import Provider +from contacts.contact_provider import ContactProvider +from contacts.contacts_manager import ContactsManager +from contacts.friend_factory import FriendFactory +from contacts.group_factory import GroupFactory +from contacts.group_peer_factory import GroupPeerFactory +from contacts.profile import Profile +from file_transfers.file_transfers_handler import FileTransfersHandler +from file_transfers.file_transfers_messages_service import FileTransfersMessagesService +from groups.groups_service import GroupsService +from history.database import Database +from history.history import History +from messenger.messenger import Messenger +from network.tox_dns import ToxDns +from smileys.smileys import SmileyLoader +from ui.create_profile_screen import CreateProfileScreen +from ui.items_factories import MessagesItemsFactory, ContactItemsFactory +from ui.widgets_factory import WidgetsFactory +from user_data.backup_service import BackupService +import styles.style # TODO: dynamic loading + +import wrapper_tests.support_testing as ts +from wrapper_tests.tests_wrapper import bootstrap_iNodeInfo + global LOG import logging LOG = logging.getLogger('app') +IDLE_PERIOD = 0.10 def setup_logging(oArgs): global LOG @@ -68,57 +123,6 @@ logging.getLogger('PyQt5.uic').setLevel(logging.ERROR) logging.getLogger('PyQt5.uic.uiparser').setLevel(logging.ERROR) logging.getLogger('PyQt5.uic.properties').setLevel(logging.ERROR) -from PyQt5 import QtWidgets, QtGui, QtCore -from qtpy.QtCore import QTimer -from qtpy.QtWidgets import QApplication - -try: - import qdarkstylexxx -except ImportError: - qdarkstyle = None - -from middleware import threads -import middleware.callbacks as callbacks -import ui.password_screen as password_screen -import updater.updater as updater -from middleware.tox_factory import tox_factory -import wrapper.toxencryptsave as tox_encrypt_save -import user_data.toxes -from user_data import settings -from user_data.settings import get_user_config_path, merge_args_into_settings - -from user_data.settings import Settings -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 utils.ui as util_ui -import utils.util as util -from contacts.profile import Profile -from file_transfers.file_transfers_handler import FileTransfersHandler -from contacts.contact_provider import ContactProvider -from contacts.friend_factory import FriendFactory -from contacts.group_factory import GroupFactory -from contacts.contacts_manager import ContactsManager -from av.calls_manager import CallsManager -from history.database import Database -from ui.widgets_factory import WidgetsFactory -from smileys.smileys import SmileyLoader -from ui.items_factories import MessagesItemsFactory, ContactItemsFactory -from messenger.messenger import Messenger -from network.tox_dns import ToxDns -from history.history import History -from file_transfers.file_transfers_messages_service import FileTransfersMessagesService -from groups.groups_service import GroupsService -from ui.create_profile_screen import CreateProfileScreen -from common.provider import Provider -from contacts.group_peer_factory import GroupPeerFactory -from user_data.backup_service import BackupService -import styles.style # TODO: dynamic loading - -from wrapper_tests.support_testing import lLOCAL, lGOOD, lNEW, lRELAYS -from wrapper_tests.tests_wrapper import main as oTOX_OPTIONS, iMain, ToxOptions, iNodeInfo global iI iI = 0 @@ -147,18 +151,19 @@ sSTYLE = """ from copy import deepcopy class App: - def __init__(self, version, args): + def __init__(self, version, oArgs): global LOG - self._args = args - self._path = path_to_profile = args.profile - uri = args.uri - logfile = args.logfile - loglevel = args.loglevel + self._args = oArgs + self.oArgs = oArgs + self._path = path_to_profile = oArgs.profile + uri = oArgs.uri + logfile = oArgs.logfile + loglevel = oArgs.loglevel - setup_logging(args) + setup_logging(oArgs) # sys.stderr.write( 'Command line args: ' +repr(oArgs) +'\n') LOG.info("Command line: " +' '.join(sys.argv[1:])) - LOG.debug(f'oArgs = {args!r}') + LOG.debug(f'oArgs = {oArgs!r}') LOG.info("Starting toxygen version " +version) self._version = version diff --git a/toxygen/contacts/contact_provider.py b/toxygen/contacts/contact_provider.py index 8dda974..33bb187 100644 --- a/toxygen/contacts/contact_provider.py +++ b/toxygen/contacts/contact_provider.py @@ -1,5 +1,11 @@ +# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- + import common.tox_save as tox_save +global LOG +import logging +LOG = logging.getLogger(__name__) + class ContactProvider(tox_save.ToxSave): @@ -54,11 +60,21 @@ class ContactProvider(tox_save.ToxSave): def get_group_by_number(self, group_number): try: - public_key = self._tox.group_get_chat_id(group_number) + if True: + # original code + public_key = self._tox.group_get_chat_id(group_number) + LOG.info(f"group_get_chat_id {group_number} {public_key}") + return self.get_group_by_public_key(public_key) + else: + # guessing + chat_id = self._tox.group_get_chat_id(group_number) + LOG.info(f"group_get_chat_id {group_number} {chat_id}") + group = self.get_contact_by_tox_id(chat_id) + return group except Exception as e: + LOG.warn(f"group_get_chat_id {group_number} {e}") return None - return self.get_group_by_public_key(public_key) def get_group_by_public_key(self, public_key): group = self._get_contact_from_cache(public_key) diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index b30fc12..0c56f64 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -201,6 +201,12 @@ class ContactsManager(ToxSave): part2 = sorted(part2, key=key_lambda) self._contacts = part1 + part2 elif sorting == 0: + # AttributeError: 'NoneType' object has no attribute 'number' + for (i, contact) in enumerate(self._contacts): + if contact is None or not hasattr(contact, 'number'): + LOG.error("Contact {i} is None or not hasattr 'number'") + del self._contacts[i] + continue contacts = sorted(self._contacts, key=lambda c: c.number) friends = filter(lambda c: type(c) is Friend, contacts) groups = filter(lambda c: type(c) is GroupChat, contacts) @@ -370,13 +376,19 @@ class ContactsManager(ToxSave): return list(filter(lambda c: type(c) is GroupChat, self._contacts)) def add_group(self, group_number): - group = self._contact_provider.get_group_by_number(group_number) index = len(self._contacts) - self._contacts.append(group) - group.reset_avatar(self._settings['identicons']) - self._save_profile() - self.set_active(index) - self.update_filtration() + group = self._contact_provider.get_group_by_number(group_number) + if not group: + LOG.warn(f"CM.add_group: NO group {group_number}") + else: + LOG.info(f"CM.add_group: Adding group {group._name}") + self._contacts.append(group) + LOG.info(f"contacts_manager.add_group: saving profile") + self._save_profile() + group.reset_avatar(self._settings['identicons']) + LOG.info(f"contacts_manager.add_group: setting active") + self.set_active(index) + self.update_filtration() def delete_group(self, group_number): group = self.get_group_by_number(group_number) @@ -503,6 +515,7 @@ class ContactsManager(ToxSave): def update_groups_numbers(self): groups = self._contact_provider.get_all_groups() + LOG.info("update_groups_numbers len(groups)={len(groups)}") for i in range(len(groups)): chat_id = self._tox.group_get_chat_id(i) group = self.get_contact_by_tox_id(chat_id) @@ -523,7 +536,13 @@ class ContactsManager(ToxSave): self._load_groups() if len(self._contacts): self.set_active(0) - for contact in filter(lambda c: not c.has_avatar(), self._contacts): + # filter(lambda c: not c.has_avatar(), self._contacts) + for (i, contact) in enumerate(self._contacts): + if not contact: + LOG.warn("_load_contacts NULL contact {i}") + del self._contacts[i] + continue + if contact.has_avatar(): continue contact.reset_avatar(self._settings['identicons']) self.update_filtration() diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index 1e1d5a2..068790e 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -87,6 +87,7 @@ class GroupChat(contact.Contact, ToxSave): LOG_WARN(f"add_peer id={peer_id} > {self._peers_limit}") return + LOG_INFO(f"add_peer id={peer_id}") peer = GroupChatPeer(peer_id, self._tox.group_peer_get_name(self._number, peer_id), self._tox.group_peer_get_status(self._number, peer_id), diff --git a/toxygen/contacts/group_factory.py b/toxygen/contacts/group_factory.py index 4083438..b1c935d 100644 --- a/toxygen/contacts/group_factory.py +++ b/toxygen/contacts/group_factory.py @@ -1,7 +1,12 @@ +# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- + from contacts.group_chat import GroupChat from common.tox_save import ToxSave import wrapper.toxcore_enums_and_consts as constants +global LOG +import logging +LOG = logging.getLogger(__name__) class GroupFactory(ToxSave): @@ -18,6 +23,7 @@ class GroupFactory(ToxSave): return self.create_group_by_number(group_number) def create_group_by_number(self, group_number): + LOG.info(f"create_group_by_number {group_number}") aliases = self._settings['friends_aliases'] tox_id = self._tox.group_get_chat_id(group_number) try: diff --git a/toxygen/groups/groups_service.py b/toxygen/groups/groups_service.py index 952e0b1..bf165a9 100644 --- a/toxygen/groups/groups_service.py +++ b/toxygen/groups/groups_service.py @@ -50,8 +50,11 @@ class GroupsService(tox_save.ToxSave): def join_gc_by_id(self, chat_id, password, nick, status): group_number = self._tox.group_join(chat_id, password, nick, status) + LOG.debug(f"_join_gc_via_id {group_number}") self._add_new_group_by_number(group_number) - + group = self._get_group_by_number(group_number) + group.status = constants.TOX_USER_STATUS['NONE'] + # ----------------------------------------------------------------------------------------------------------------- # Groups reconnect and leaving # ----------------------------------------------------------------------------------------------------------------- @@ -92,6 +95,8 @@ class GroupsService(tox_save.ToxSave): def process_group_invite(self, friend_number, group_name, invite_data): friend = self._get_friend_by_number(friend_number) + # binary {invite_data} + LOG.debug(f"process_group_invite {friend_number} {group_name}") invite = GroupInvite(friend.tox_id, group_name, invite_data) self._group_invites.append(invite) self._update_invites_button_state() @@ -99,6 +104,7 @@ class GroupsService(tox_save.ToxSave): def accept_group_invite(self, invite, name, status, password): pk = invite.friend_public_key friend = self._get_friend_by_public_key(pk) + LOG.debug(f"accept_group_invite {name}") self._join_gc_via_invite(invite.invite_data, friend.number, name, status, password) self._delete_group_invite(invite) self._update_invites_button_state() @@ -230,6 +236,7 @@ class GroupsService(tox_save.ToxSave): # ----------------------------------------------------------------------------------------------------------------- def _add_new_group_by_number(self, group_number): + LOG.debug(f"_add_new_group_by_number {group_number}") self._contacts_manager.add_group(group_number) def _get_group_by_number(self, group_number): @@ -256,14 +263,21 @@ class GroupsService(tox_save.ToxSave): self._group_invites.remove(invite) def _join_gc_via_invite(self, invite_data, friend_number, nick, status, password): - if nick is None: nick = '' - if invite_data is None: invite_data = '' + LOG.debug(f"_join_gc_via_invite friend_number={friend_number} nick={nick} datalen={len(invite_data)}") + if nick is None: + nick = '' + if invite_data is None: + invite_data = b'' try: group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, status, password) except Exception as e: - LOG.error(f"_join_gc_via_invite {e}") - else: + LOG.error(f"_join_gc_via_invite ERROR {e}") + return + try: self._add_new_group_by_number(group_number) + except Exception as e: + LOG.error(f"_join_gc_via_invite group_number={group_number} {e}") + return def _update_invites_button_state(self): self._main_screen.update_gc_invites_button_state() diff --git a/toxygen/main.py b/toxygen/main.py index 0990ce2..966c9f8 100644 --- a/toxygen/main.py +++ b/toxygen/main.py @@ -333,8 +333,6 @@ lKEEP_SETTINGS = ['uri', class A(): pass -global oAPP -oAPP = None def main(lArgs): global oPYA from argparse import Namespace @@ -385,9 +383,8 @@ def main(lArgs): oArgs = aArgs toxygen = app.App(__version__, oArgs) - global oAPP - oAPP = toxygen - __builtins__['app'] = toxygen + # for pyqtconsole + __builtins__.app = toxygen i = toxygen.iMain() return i diff --git a/toxygen/messenger/messenger.py b/toxygen/messenger/messenger.py index 08a0b67..5474d55 100644 --- a/toxygen/messenger/messenger.py +++ b/toxygen/messenger/messenger.py @@ -148,9 +148,12 @@ class Messenger(tox_save.ToxSave): """ t = util.get_unix_time() group = self._get_group_by_number(group_number) + if not group: + LOG.error(f"FixMe new_group_message _get_group_by_number({group_number})") + return peer = group.get_peer_by_id(peer_id) if not peer: - LOG.warn('FixMe new_group_message group.get_peer_by_id ' + str(peer_id)) + LOG.error('FixMe new_group_message group.get_peer_by_id ' + str(peer_id)) return text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), t, message_type) self._add_message(text_message, group) diff --git a/toxygen/middleware/callbacks.py b/toxygen/middleware/callbacks.py index 2f1b8d5..8c9c618 100644 --- a/toxygen/middleware/callbacks.py +++ b/toxygen/middleware/callbacks.py @@ -14,11 +14,18 @@ from notifications.sound import * from datetime import datetime iMAX_INT32 = 4294967295 +# callbacks can be called in any thread so were being careful def LOG_ERROR(l): print('EROR< '+l) def LOG_WARN(l): print('WARN< '+l) -def LOG_INFO(l): print('INFO< '+l) -def LOG_DEBUG(l): print('DBUG< '+l) -def LOG_TRACE(l): pass # print('TRACE+ '+l) +def LOG_INFO(l): + bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 20-1 + if bIsVerbose: print('INFO< '+l) +def LOG_DEBUG(l): + bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 10-1 + if bIsVerbose: print('DBUG< '+l) +def LOG_TRACE(l): + bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel < 10-1 + pass # print('TRACE+ '+l) global aTIMES aTIMES=dict() @@ -185,7 +192,9 @@ def friend_message(messenger, contacts_manager, profile, settings, window, tray) invoke_in_main_thread(messenger.new_message, friend_number, message_type, message) if not window.isActiveWindow(): friend = contacts_manager.get_friend_by_number(friend_number) - if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and not settings.locked: + if settings['notifications'] \ + and profile.status != TOX_USER_STATUS['BUSY'] \ + and not settings.locked: invoke_in_main_thread(tray_notification, friend.name, message, tray, window) if settings['sound_notifications'] and profile.status != TOX_USER_STATUS['BUSY']: sound_notification(SOUND_NOTIFICATION['MESSAGE']) @@ -249,7 +258,9 @@ def tox_file_recv(window, tray, profile, file_transfer_handler, contacts_manager file_name) if not window.isActiveWindow(): friend = contacts_manager.get_friend_by_number(friend_number) - if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and not settings.locked: + if settings['notifications'] \ + and profile.status != TOX_USER_STATUS['BUSY'] \ + and not settings.locked: file_from = util_ui.tr("File from") invoke_in_main_thread(tray_notification, file_from + ' ' + friend.name, file_name, tray, window) if settings['sound_notifications'] and profile.status != TOX_USER_STATUS['BUSY']: @@ -452,13 +463,14 @@ def group_message(window, tray, tox, messenger, settings, profile): if settings['sound_notifications'] and bl and \ profile.status != TOX_USER_STATUS['BUSY']: sound_notification(SOUND_NOTIFICATION['MESSAGE']) - if False and settings['tray_icon']: + if False and settings['tray_icon'] and tray: if settings['notifications'] and \ profile.status != TOX_USER_STATUS['BUSY'] and \ (not settings.locked) and bl: invoke_in_main_thread(tray_notification, name, message, tray, window) - icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png') - invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon)) + if tray: + icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png') + invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon)) return wrapped @@ -475,7 +487,9 @@ def group_private_message(window, tray, tox, messenger, settings, profile): return bl = settings['notify_all_gc'] or profile.name in message name = tox.group_peer_get_name(group_number, peer_id) - if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and (not settings.locked) and bl: + if settings['notifications'] and settings['tray_icon'] \ + and profile.status != TOX_USER_STATUS['BUSY'] \ + and (not settings.locked) and bl: invoke_in_main_thread(tray_notification, name, message, tray, window) if settings['sound_notifications'] and bl and profile.status != TOX_USER_STATUS['BUSY']: sound_notification(SOUND_NOTIFICATION['MESSAGE']) @@ -485,7 +499,7 @@ def group_private_message(window, tray, tox, messenger, settings, profile): return wrapped - +# Exception ignored on calling ctypes callback function: .wrapped at 0x7ffede910700> def group_invite(window, settings, tray, profile, groups_service, contacts_provider): def wrapped(tox, friend_number, invite_data, length, group_name, group_name_length, user_data): LOG_DEBUG(f"group_invite friend_number={friend_number}") @@ -495,14 +509,18 @@ def group_invite(window, settings, tray, profile, groups_service, contacts_provi bytes(invite_data[:length])) if window.isActiveWindow(): return - if settings['notifications'] and \ - profile.status != TOX_USER_STATUS['BUSY'] and not settings.locked: + bHasTray = tray and settings['tray_icon'] + if settings['notifications'] \ + and bHasTray \ + and profile.status != TOX_USER_STATUS['BUSY'] \ + and not settings.locked: friend = contacts_provider.get_friend_by_number(friend_number) title = util_ui.tr('New invite to group chat') text = util_ui.tr('{} invites you to group "{}"').format(friend.name, group_name) invoke_in_main_thread(tray_notification, title, text, tray, window) - icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png') - invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon)) + if tray: + icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png') + invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon)) return wrapped diff --git a/toxygen/notifications/tray.py b/toxygen/notifications/tray.py index 4232253..0858b83 100644 --- a/toxygen/notifications/tray.py +++ b/toxygen/notifications/tray.py @@ -10,7 +10,7 @@ def tray_notification(title, text, tray, window): :param tray: ref to tray icon :param window: main window """ - if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable(): + if tray and QtWidgets.QSystemTrayIcon.isSystemTrayAvailable(): if len(text) > 30: text = text[:27] + '...' tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000) diff --git a/toxygen/styles/light_style.qss b/toxygen/styles/light_style.qss deleted file mode 100644 index 7e31b39..0000000 --- a/toxygen/styles/light_style.qss +++ /dev/null @@ -1,19 +0,0 @@ -.QWidget {font-family Helvetica;} -.QCheckBox { font-family Helvetica;} -.QComboBox { font-family Helvetica;} -.QGroupBox { font-family Helvetica;} -.QLabel {font-family Helvetica;} -.QLineEdit { font-family Helvetica;} -.QListWidget { font-family Helvetica;} -.QListWidgetItem { font-family Helvetica;} -.QMainWindow {font-family Helvetica;} -.QMenu {font-family Helvetica;} -.QMenuBar {font-family Helvetica;} -.QPlainText {font-family Courier; weight: 75;} -.QPlainTextEdit {font-family Courier;} -.QPushButton {font-family Helvetica;} -.QRadioButton { font-family Helvetica; } -.QText {font-family Courier; weight: 75; } -.QTextBrowser {font-family Courier; weight: 75; } -.QTextSingleLine {font-family Courier; weight: 75; } -.QToolBar { font-weight: bold; } diff --git a/toxygen/ui/group_invites_widgets.py b/toxygen/ui/group_invites_widgets.py index 476af5c..ff61370 100644 --- a/toxygen/ui/group_invites_widgets.py +++ b/toxygen/ui/group_invites_widgets.py @@ -2,6 +2,9 @@ from PyQt5 import uic, QtWidgets import utils.util as util from ui.widgets import * +global LOG +import logging +LOG = logging.getLogger('app') class GroupInviteItem(QtWidgets.QWidget): @@ -73,6 +76,7 @@ class GroupInvitesScreen(CenteredWidget): nick = self._tox.self_get_name() selected_invites = self._get_selected_invites() for invite in selected_invites: + LOG.debug(f"_accept_invites {nick}") self._groups_service.accept_group_invite(invite, nick, status, password) self._refresh_invites_list() @@ -81,6 +85,7 @@ class GroupInvitesScreen(CenteredWidget): def _decline_invites(self): selected_invites = self._get_selected_invites() for invite in selected_invites: + LOG.debug(f"_groups_service.decline_group_invite") self._groups_service.decline_group_invite(invite) self._refresh_invites_list() diff --git a/toxygen/ui/main_screen.py b/toxygen/ui/main_screen.py index bbb3fc4..22b0455 100644 --- a/toxygen/ui/main_screen.py +++ b/toxygen/ui/main_screen.py @@ -1,19 +1,65 @@ # -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- import os import logging + +from PyQt5 import uic +from PyQt5 import QtWidgets, QtGui +from qtpy.QtGui import (QColor, QTextCharFormat, QFont, QSyntaxHighlighter) + from ui.contact_items import * from ui.widgets import MultilineEdit from ui.main_screen_widgets import * import utils.util as util import utils.ui as util_ui -from PyQt5 import uic -from PyQt5 import QtWidgets, QtGui from user_data.settings import Settings -iMAX = 70 global LOG LOG = logging.getLogger('app.'+'mains') +iMAX = 70 + +try: + # https://github.com/pyqtconsole/pyqtconsole + from pyqtconsole.console import PythonConsole + import pyqtconsole.highlighter as hl +except Exception as e: + LOG.warn(e) + PythonConsole = None +else: + def hl_format(color, style=''): + """Return a QTextCharFormat with the given attributes. + unused + """ + _color = QColor() + _color.setNamedColor(color) + + _format = QTextCharFormat() + _format.setBackground(_color) + if 'bold' in style: + _format.setFontWeight(QFont.Bold) + if 'italic' in style: + _format.setFontItalic(True) + + _fgcolor = QColor() + _fgcolor.setNamedColor('white') + _format.setForeground(_fgcolor) + return _format + + aFORMATS = { + 'keyword': hl.format('blue', 'bold'), + 'operator': hl.format('red'), + 'brace': hl.format('darkGray'), + 'defclass': hl.format('black', 'bold'), + 'string': hl.format('magenta'), + 'string2': hl.format('darkMagenta'), + 'comment': hl.format('darkGreen', 'italic'), + 'self': hl.format('black', 'italic'), + 'numbers': hl.format('brown'), + 'inprompt': hl.format('darkBlue', 'bold'), + 'outprompt': hl.format('darkRed', 'bold'), + } + + class QTextEditLogger(logging.Handler): def __init__(self, parent, app): super().__init__() @@ -564,21 +610,45 @@ class MainWindow(QtWidgets.QMainWindow): self._me.show() def python_console(self): - try: - if not self._pe: - from pyqtconsole.console import PythonConsole - self._pe = PythonConsole(sFont="Courier New", bBold=True) - self._pe.show() - self._pe.eval_queued() - # self._pe.eval_in_thread() - except Exception as e: - LOG.debug(e) - self._me.show() + if PythonConsole: + app = self._app + if app and app._settings: + size = app._settings['message_font_size'] + font_name = app._settings['font'] + else: + size = 12 + font_name = "Courier New" + + size = font_width = 10 + font_name = "DejaVu Sans Mono" + + try: + if not self._pe: + self._pe = PythonConsole(sFont=font_name, + formats=aFORMATS, + bBold=True, + font_width=size) + self._pe.setWindowTitle('variable: app is the application') +# self._pe.edit.setStyleSheet('foreground: white; background-color: black;}') + # Fix the pyconsole geometry + geometry = self._pe.geometry() + geometry.setWidth(font_width*80+20) + geometry.setHeight(font_width*40) + self._pe.setGeometry(geometry) + self._pe.resize(font_width*80+20, font_width*40) + + self._pe.show() + self._pe.eval_queued() + # or self._pe.eval_in_thread() + return + except Exception as e: + LOG.debug(e) + self._me.show() def about_program(self): # TODO: replace with window text = util_ui.tr('Toxygen is Tox client written in Python.\nVersion: ') - text += '' + '\nGitHub: https://github.com/toxygen-project/toxygen/' + text += '' + '\nGitHub: https://git.plastiras.org/emdee/toxygen' title = util_ui.tr('About') util_ui.message_box(text, title) @@ -861,8 +931,10 @@ class MainWindow(QtWidgets.QMainWindow): def update_gc_invites_button_state(self): invites_count = self._groups_service.group_invites_count - LOG.debug(f"invites_count={invites_count}") + LOG.debug(f"update_gc_invites_button_state invites_count={invites_count}") + + # Fixme self.groupInvitesPushButton.setVisible(True) # invites_count > 0 - text = util_ui.tr('{} new invites to group chats').format(invites_count) + text = util_ui.tr(f'{invites_count} new invites to group chats') self.groupInvitesPushButton.setText(text) self.resizeEvent()