group creation, invites and message sending (untested)
This commit is contained in:
parent
c8bdb32e86
commit
f13274882a
8 changed files with 165 additions and 105 deletions
|
@ -91,10 +91,11 @@ class BaseContact:
|
||||||
if not os.path.isfile(avatar_path): # load default image
|
if not os.path.isfile(avatar_path): # load default image
|
||||||
avatar_path = default_path
|
avatar_path = default_path
|
||||||
os.chdir(curr_directory() + '/images/')
|
os.chdir(curr_directory() + '/images/')
|
||||||
pixmap = QtGui.QPixmap(QtCore.QSize(64, 64))
|
width = self._widget.avatar_label.width()
|
||||||
|
pixmap = QtGui.QPixmap(QtCore.QSize(width, width))
|
||||||
pixmap.load(avatar_path)
|
pixmap.load(avatar_path)
|
||||||
self._widget.avatar_label.setScaledContents(False)
|
self._widget.avatar_label.setScaledContents(False)
|
||||||
self._widget.avatar_label.setPixmap(pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio))
|
self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio))
|
||||||
self._widget.avatar_label.repaint()
|
self._widget.avatar_label.repaint()
|
||||||
|
|
||||||
def reset_avatar(self):
|
def reset_avatar(self):
|
||||||
|
|
|
@ -287,6 +287,20 @@ def callback_audio(toxav, friend_number, samples, audio_samples_per_channel, aud
|
||||||
rate)
|
rate)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
# Callbacks - group chats
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def group_message(tox, group_number, peer_id, message, length, user_data):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def group_invite(tox, friend_number, invite_data, length, user_data):
|
||||||
|
invoke_in_main_thread(Profile.get_instance().process_group_invite,
|
||||||
|
friend_number,
|
||||||
|
invite_data[:length])
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Callbacks - initialization
|
# Callbacks - initialization
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -5,9 +5,6 @@ except ImportError:
|
||||||
import basecontact
|
import basecontact
|
||||||
from messages import *
|
from messages import *
|
||||||
from history import *
|
from history import *
|
||||||
from settings import ProfileHelper
|
|
||||||
from toxcore_enums_and_consts import *
|
|
||||||
from util import curr_directory
|
|
||||||
|
|
||||||
|
|
||||||
class Contact(basecontact.BaseContact):
|
class Contact(basecontact.BaseContact):
|
||||||
|
@ -17,7 +14,7 @@ class Contact(basecontact.BaseContact):
|
||||||
widget - widget for update
|
widget - widget for update
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message_getter, name, status_message, widget, tox_id):
|
def __init__(self, number, message_getter, name, status_message, widget, tox_id):
|
||||||
"""
|
"""
|
||||||
:param name: name, example: 'Toxygen user'
|
:param name: name, example: 'Toxygen user'
|
||||||
:param status_message: status message, example: 'Toxing on Toxygen'
|
:param status_message: status message, example: 'Toxing on Toxygen'
|
||||||
|
@ -28,6 +25,7 @@ class Contact(basecontact.BaseContact):
|
||||||
self._message_getter = message_getter
|
self._message_getter = message_getter
|
||||||
self._new_messages = False
|
self._new_messages = False
|
||||||
self._visible = True
|
self._visible = True
|
||||||
|
self._number = number
|
||||||
self._corr = []
|
self._corr = []
|
||||||
self._unsaved_messages = 0
|
self._unsaved_messages = 0
|
||||||
self._history_loaded = self._new_actions = False
|
self._history_loaded = self._new_actions = False
|
||||||
|
@ -150,40 +148,5 @@ class Contact(basecontact.BaseContact):
|
||||||
self._widget.messages.update(self._new_messages)
|
self._widget.messages.update(self._new_messages)
|
||||||
self._widget.connection_status.update(self.status, False)
|
self._widget.connection_status.update(self.status, False)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
|
||||||
# Avatars
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def load_avatar(self):
|
|
||||||
"""
|
|
||||||
Tries to load avatar of contact or uses default avatar
|
|
||||||
"""
|
|
||||||
avatar_path = '{}.png'.format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
|
||||||
os.chdir(ProfileHelper.get_path() + 'avatars/')
|
|
||||||
if not os.path.isfile(avatar_path): # load default image
|
|
||||||
avatar_path = 'avatar.png'
|
|
||||||
os.chdir(curr_directory() + '/images/')
|
|
||||||
width = self._widget.avatar_label.width()
|
|
||||||
pixmap = QtGui.QPixmap(QtCore.QSize(width, width))
|
|
||||||
pixmap.load(avatar_path)
|
|
||||||
self._widget.avatar_label.setScaledContents(False)
|
|
||||||
self._widget.avatar_label.setPixmap(pixmap.scaled(width, width, QtCore.Qt.KeepAspectRatio))
|
|
||||||
self._widget.avatar_label.repaint()
|
|
||||||
|
|
||||||
def reset_avatar(self):
|
|
||||||
avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
|
||||||
if os.path.isfile(avatar_path):
|
|
||||||
os.remove(avatar_path)
|
|
||||||
self.load_avatar()
|
|
||||||
|
|
||||||
def set_avatar(self, avatar):
|
|
||||||
avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(self._tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
|
||||||
with open(avatar_path, 'wb') as f:
|
|
||||||
f.write(avatar)
|
|
||||||
self.load_avatar()
|
|
||||||
|
|
||||||
def get_pixmap(self):
|
|
||||||
return self._widget.avatar_label.pixmap()
|
|
||||||
|
|
||||||
messages = property(get_messages)
|
messages = property(get_messages)
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,11 @@ class Friend(contact.Contact):
|
||||||
Friend in list of friends. Can be hidden, properties 'has unread messages' and 'has alias' added
|
Friend in list of friends. Can be hidden, properties 'has unread messages' and 'has alias' added
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message_getter, number, *args):
|
def __init__(self, *args):
|
||||||
"""
|
"""
|
||||||
:param message_getter: gets messages from db
|
|
||||||
:param number: number of friend.
|
:param number: number of friend.
|
||||||
"""
|
"""
|
||||||
super(Friend, self).__init__(message_getter, *args)
|
super(Friend, self).__init__(*args)
|
||||||
self._number = number
|
|
||||||
self._alias = False
|
self._alias = False
|
||||||
self._receipts = 0
|
self._receipts = 0
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ import contact
|
||||||
|
|
||||||
class GroupChat(contact.Contact):
|
class GroupChat(contact.Contact):
|
||||||
|
|
||||||
def __init__(self, group_id, tox, *args):
|
def __init__(self, tox, *args):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
self._id = group_id
|
|
||||||
self._tox = tox
|
self._tox = tox
|
||||||
|
|
||||||
def load_avatar(self, default_path='group.png'):
|
def load_avatar(self, default_path='group.png'):
|
||||||
super().load_avatar(default_path)
|
super().load_avatar(default_path)
|
||||||
|
|
||||||
|
# TODO: get peers list and add other methods
|
||||||
|
|
|
@ -82,7 +82,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
self.actionAbout_program.triggered.connect(self.about_program)
|
self.actionAbout_program.triggered.connect(self.about_program)
|
||||||
self.actionNetwork.triggered.connect(self.network_settings)
|
self.actionNetwork.triggered.connect(self.network_settings)
|
||||||
self.actionAdd_friend.triggered.connect(self.add_contact)
|
self.actionAdd_friend.triggered.connect(self.add_contact)
|
||||||
self.actionSettings.triggered.connect(self.profilesettings)
|
self.actionSettings.triggered.connect(self.profile_settings)
|
||||||
self.actionPrivacy_settings.triggered.connect(self.privacy_settings)
|
self.actionPrivacy_settings.triggered.connect(self.privacy_settings)
|
||||||
self.actionInterface_settings.triggered.connect(self.interface_settings)
|
self.actionInterface_settings.triggered.connect(self.interface_settings)
|
||||||
self.actionNotifications.triggered.connect(self.notification_settings)
|
self.actionNotifications.triggered.connect(self.notification_settings)
|
||||||
|
@ -205,9 +205,9 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
Form.status_message.setObjectName("status_message")
|
Form.status_message.setObjectName("status_message")
|
||||||
self.connection_status = Form.connection_status = StatusCircle(Form)
|
self.connection_status = Form.connection_status = StatusCircle(Form)
|
||||||
Form.connection_status.setGeometry(QtCore.QRect(230, 35, 32, 32))
|
Form.connection_status.setGeometry(QtCore.QRect(230, 35, 32, 32))
|
||||||
self.avatar_label.mouseReleaseEvent = self.profilesettings
|
self.avatar_label.mouseReleaseEvent = self.profile_settings
|
||||||
self.status_message.mouseReleaseEvent = self.profilesettings
|
self.status_message.mouseReleaseEvent = self.profile_settings
|
||||||
self.name.mouseReleaseEvent = self.profilesettings
|
self.name.mouseReleaseEvent = self.profile_settings
|
||||||
self.connection_status.raise_()
|
self.connection_status.raise_()
|
||||||
Form.connection_status.setObjectName("connection_status")
|
Form.connection_status.setObjectName("connection_status")
|
||||||
|
|
||||||
|
@ -232,6 +232,11 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
font.setBold(False)
|
font.setBold(False)
|
||||||
self.account_status.setFont(font)
|
self.account_status.setFont(font)
|
||||||
self.account_status.setObjectName("account_status")
|
self.account_status.setObjectName("account_status")
|
||||||
|
|
||||||
|
self.account_status.mouseReleaseEvent = self.show_chat_menu
|
||||||
|
self.account_name.mouseReleaseEvent = self.show_chat_menu
|
||||||
|
self.account_avatar.mouseReleaseEvent = self.show_chat_menu
|
||||||
|
|
||||||
self.callButton = QtGui.QPushButton(Form)
|
self.callButton = QtGui.QPushButton(Form)
|
||||||
self.callButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
|
self.callButton.setGeometry(QtCore.QRect(550, 30, 50, 50))
|
||||||
self.callButton.setObjectName("callButton")
|
self.callButton.setObjectName("callButton")
|
||||||
|
@ -389,7 +394,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
self.a_c = AddContact(link)
|
self.a_c = AddContact(link)
|
||||||
self.a_c.show()
|
self.a_c.show()
|
||||||
|
|
||||||
def profilesettings(self, *args):
|
def profile_settings(self, *args):
|
||||||
self.p_s = ProfileSettings()
|
self.p_s = ProfileSettings()
|
||||||
self.p_s.show()
|
self.p_s.show()
|
||||||
|
|
||||||
|
@ -455,6 +460,11 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
self.gc = AddGroupchat()
|
self.gc = AddGroupchat()
|
||||||
self.gc.show()
|
self.gc.show()
|
||||||
|
|
||||||
|
def show_chat_menu(self):
|
||||||
|
pr = Profile.get_instance()
|
||||||
|
if not pr.is_active_a_friend():
|
||||||
|
pass # TODO: show list of users in chat
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Messages, calls and file transfers
|
# Messages, calls and file transfers
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -533,29 +543,32 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8)
|
auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8)
|
||||||
if item is not None:
|
if item is not None:
|
||||||
self.listMenu = QtGui.QMenu()
|
self.listMenu = QtGui.QMenu()
|
||||||
set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
|
if type(friend) is Friend: # TODO: add `invite to gc` submenu
|
||||||
clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
|
set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
copy_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
|
clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
copy_name_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Name', None, QtGui.QApplication.UnicodeUTF8))
|
copy_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
copy_status_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Status message', None, QtGui.QApplication.UnicodeUTF8))
|
copy_name_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Name', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
copy_key_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Public key', None, QtGui.QApplication.UnicodeUTF8))
|
copy_status_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Status message', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
copy_key_item = copy_menu.addAction(QtGui.QApplication.translate("MainWindow", 'Public key', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
auto_accept_item = self.listMenu.addAction(auto)
|
auto_accept_item = self.listMenu.addAction(auto)
|
||||||
remove_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Remove friend', None, QtGui.QApplication.UnicodeUTF8))
|
remove_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Remove friend', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
notes_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Notes', None, QtGui.QApplication.UnicodeUTF8))
|
notes_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Notes', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
submenu = plugin_support.PluginLoader.get_instance().get_menu(self.listMenu, num)
|
submenu = plugin_support.PluginLoader.get_instance().get_menu(self.listMenu, num)
|
||||||
if len(submenu):
|
if len(submenu):
|
||||||
plug = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
|
plug = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
plug.addActions(submenu)
|
plug.addActions(submenu)
|
||||||
self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
|
self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
|
||||||
self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
|
self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
|
||||||
self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
|
self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
|
||||||
self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
|
self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
|
||||||
self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
|
self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
|
||||||
self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
|
self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
|
||||||
self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
|
self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
|
||||||
self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
|
self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
|
||||||
|
else:
|
||||||
|
pass # TODO: add menu for gc
|
||||||
parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
|
parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
|
||||||
self.listMenu.move(parent_position + pos)
|
self.listMenu.move(parent_position + pos)
|
||||||
self.listMenu.show()
|
self.listMenu.show()
|
||||||
|
|
|
@ -60,7 +60,7 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
if not self._history.friend_exists_in_db(tox_id):
|
if not self._history.friend_exists_in_db(tox_id):
|
||||||
self._history.add_friend_to_db(tox_id)
|
self._history.add_friend_to_db(tox_id)
|
||||||
message_getter = self._history.messages_getter(tox_id)
|
message_getter = self._history.messages_getter(tox_id)
|
||||||
friend = Friend(message_getter, i, name, status_message, item, tox_id)
|
friend = Friend(i, message_getter, name, status_message, item, tox_id)
|
||||||
friend.set_alias(alias)
|
friend.set_alias(alias)
|
||||||
self._friends_and_gc.append(friend)
|
self._friends_and_gc.append(friend)
|
||||||
self.filtration(self._show_online)
|
self.filtration(self._show_online)
|
||||||
|
@ -138,7 +138,10 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
self.filtration(self._show_online, self._filter_string)
|
self.filtration(self._show_online, self._filter_string)
|
||||||
|
|
||||||
def get_friend_by_number(self, num):
|
def get_friend_by_number(self, num):
|
||||||
return list(filter(lambda x: x.number == num, self._friends_and_gc))[0]
|
return list(filter(lambda x: x.number == num and type(x) is Friend, self._friends_and_gc))[0]
|
||||||
|
|
||||||
|
def get_gc_by_number(self, num):
|
||||||
|
return list(filter(lambda x: x.number == num and type(x) is not Friend, self._friends_and_gc))[0]
|
||||||
|
|
||||||
def get_friend_or_gc(self, num):
|
def get_friend_or_gc(self, num):
|
||||||
return self._friends_and_gc[num]
|
return self._friends_and_gc[num]
|
||||||
|
@ -350,12 +353,13 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def split_and_send(self, number, message_type, message):
|
def split_and_send(self, number, message_type, message, is_group=False):
|
||||||
"""
|
"""
|
||||||
Message splitting
|
Message splitting
|
||||||
:param number: friend's number
|
:param number: friend or gc number
|
||||||
:param message_type: type of message
|
:param message_type: type of message
|
||||||
:param message: message text
|
:param message: message text
|
||||||
|
:param is_group: send to group
|
||||||
"""
|
"""
|
||||||
while len(message) > TOX_MAX_MESSAGE_LENGTH:
|
while len(message) > TOX_MAX_MESSAGE_LENGTH:
|
||||||
size = TOX_MAX_MESSAGE_LENGTH * 4 / 5
|
size = TOX_MAX_MESSAGE_LENGTH * 4 / 5
|
||||||
|
@ -369,9 +373,15 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
else:
|
else:
|
||||||
index = TOX_MAX_MESSAGE_LENGTH - size - 1
|
index = TOX_MAX_MESSAGE_LENGTH - size - 1
|
||||||
index += size + 1
|
index += size + 1
|
||||||
self._tox.friend_send_message(number, message_type, message[:index])
|
if not is_group:
|
||||||
|
self._tox.friend_send_message(number, message_type, message[:index])
|
||||||
|
else:
|
||||||
|
self._tox.group_send_message(number, message_type, message[:index])
|
||||||
message = message[index:]
|
message = message[index:]
|
||||||
self._tox.friend_send_message(number, message_type, message)
|
if not is_group:
|
||||||
|
self._tox.friend_send_message(number, message_type, message)
|
||||||
|
else:
|
||||||
|
self._tox.group_send_message(number, message_type, message)
|
||||||
|
|
||||||
def new_message(self, friend_num, message_type, message):
|
def new_message(self, friend_num, message_type, message):
|
||||||
"""
|
"""
|
||||||
|
@ -394,18 +404,20 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
if not friend.visibility:
|
if not friend.visibility:
|
||||||
self.update_filtration()
|
self.update_filtration()
|
||||||
|
|
||||||
def send_message(self, text, friend_num=None):
|
def send_message(self, text, number=None, is_gc=False):
|
||||||
"""
|
"""
|
||||||
Send message
|
Send message
|
||||||
:param text: message text
|
:param text: message text
|
||||||
:param friend_num: num of friend
|
:param number: num of friend or gc
|
||||||
|
:param is_gc: is group chat
|
||||||
"""
|
"""
|
||||||
if friend_num is None:
|
if number is None:
|
||||||
friend_num = self.get_active_number()
|
number = self.get_active_number()
|
||||||
|
is_gc = not self.is_active_a_friend()
|
||||||
if text.startswith('/plugin '):
|
if text.startswith('/plugin '):
|
||||||
plugin_support.PluginLoader.get_instance().command(text[8:])
|
plugin_support.PluginLoader.get_instance().command(text[8:])
|
||||||
self._screen.messageEdit.clear()
|
self._screen.messageEdit.clear()
|
||||||
elif text and friend_num + 1:
|
elif text and number + 1:
|
||||||
text = ''.join(c if c <= '\u10FFFF' else '\u25AF' for c in text)
|
text = ''.join(c if c <= '\u10FFFF' else '\u25AF' for c in text)
|
||||||
|
|
||||||
if text.startswith('/me '):
|
if text.startswith('/me '):
|
||||||
|
@ -414,22 +426,30 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
else:
|
else:
|
||||||
message_type = TOX_MESSAGE_TYPE['NORMAL']
|
message_type = TOX_MESSAGE_TYPE['NORMAL']
|
||||||
|
|
||||||
friend = self.get_friend_by_number(friend_num)
|
if not is_gc:
|
||||||
# TODO: send to gc
|
friend_or_gc = self.get_friend_by_number(number)
|
||||||
# friend = self._friends_and_gc[self._active_friend_or_gc]
|
else:
|
||||||
|
friend_or_gc = self.get_gc_by_number(number)
|
||||||
friend.inc_receipts()
|
|
||||||
if friend.status is not None:
|
|
||||||
self.split_and_send(friend.number, message_type, text.encode('utf-8'))
|
|
||||||
t = time.time()
|
t = time.time()
|
||||||
if friend.number == self.get_active_number():
|
|
||||||
self.create_message_item(text, t, MESSAGE_OWNER['NOT_SENT'], message_type)
|
if not is_gc:
|
||||||
self._screen.messageEdit.clear()
|
friend_or_gc.inc_receipts()
|
||||||
self._messages.scrollToBottom()
|
if friend_or_gc.status is not None:
|
||||||
friend.append_message(TextMessage(text, MESSAGE_OWNER['NOT_SENT'], t, message_type))
|
self.split_and_send(friend_or_gc.number, message_type, text.encode('utf-8'))
|
||||||
|
if friend_or_gc.number == self.get_active_number() and self.is_active_a_friend():
|
||||||
|
self.create_message_item(text, t, MESSAGE_OWNER['NOT_SENT'], message_type)
|
||||||
|
self._screen.messageEdit.clear()
|
||||||
|
self._messages.scrollToBottom()
|
||||||
|
else:
|
||||||
|
self.split_and_send(friend_or_gc.number, message_type, text.encode('utf-8'), True)
|
||||||
|
if friend_or_gc.number == self.get_active_number() and not self.is_active_a_friend():
|
||||||
|
self.create_message_item(text, t, MESSAGE_OWNER['ME'], message_type)
|
||||||
|
self._screen.messageEdit.clear()
|
||||||
|
self._messages.scrollToBottom()
|
||||||
|
friend_or_gc.append_message(TextMessage(text, MESSAGE_OWNER['NOT_SENT'], t, message_type))
|
||||||
|
|
||||||
def delete_message(self, time):
|
def delete_message(self, time):
|
||||||
friend = self._friends[self._active_friend]
|
friend = self._friends_and_gc[self._active_friend_or_gc]
|
||||||
friend.delete_message(time)
|
friend.delete_message(time)
|
||||||
self._history.delete_message(friend.tox_id, time)
|
self._history.delete_message(friend.tox_id, time)
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -1198,12 +1218,43 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
# Group chats support
|
# Group chats support
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def add_gc(self, num):
|
||||||
|
tox_id = self._tox.group_get_chat_id(num)
|
||||||
|
name = self._tox.group_get_name(num)
|
||||||
|
topic = self._tox.group_get_topic(num)
|
||||||
|
item = self.create_friend_item()
|
||||||
|
try:
|
||||||
|
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)
|
||||||
|
except Exception as ex: # something is wrong
|
||||||
|
log('Accept friend request failed! ' + str(ex))
|
||||||
|
message_getter = None
|
||||||
|
gc = GroupChat(self._tox, message_getter, num, name, topic, item, tox_id)
|
||||||
|
self._friends_and_gc.append(gc)
|
||||||
|
|
||||||
def create_gc(self, name, is_public, password):
|
def create_gc(self, name, is_public, password):
|
||||||
privacy_state = TOX_GROUP_PRIVACY_STATE['TOX_GROUP_PRIVACY_STATE_PUBLIC'] if is_public else TOX_GROUP_PRIVACY_STATE['TOX_GROUP_PRIVACY_STATE_PRIVATE']
|
privacy_state = TOX_GROUP_PRIVACY_STATE['TOX_GROUP_PRIVACY_STATE_PUBLIC'] if is_public else TOX_GROUP_PRIVACY_STATE['TOX_GROUP_PRIVACY_STATE_PRIVATE']
|
||||||
num = self._tox.group_new(privacy_state, bytes(name, 'utf-8'))
|
num = self._tox.group_new(privacy_state, bytes(name, 'utf-8'))
|
||||||
if password:
|
if password:
|
||||||
self._tox.group_founder_set_password(num, password)
|
self._tox.group_founder_set_password(num, bytes(password, 'utf-8'))
|
||||||
# self._friends_and_gc.append(Groupchat(num, self._tox, ))
|
self.add_gc(num)
|
||||||
|
|
||||||
|
def process_group_invite(self, friend_num, data):
|
||||||
|
# TODO: add info to list and support password
|
||||||
|
try:
|
||||||
|
text = QtGui.QApplication.translate('MainWindow', 'User {} invites you to group',
|
||||||
|
None, QtGui.QApplication.UnicodeUTF8)
|
||||||
|
info = text.format(self.get_friend_by_number(friend_num).name)
|
||||||
|
fr_req = QtGui.QApplication.translate('MainWindow', 'Group chat invite', None, QtGui.QApplication.UnicodeUTF8)
|
||||||
|
reply = QtGui.QMessageBox.question(None, fr_req, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||||
|
if reply == QtGui.QMessageBox.Yes: # accepted
|
||||||
|
num = self._tox.group_invite_accept(data)
|
||||||
|
data = self._tox.get_savedata()
|
||||||
|
ProfileHelper.get_instance().save_profile(data)
|
||||||
|
self.add_gc(num)
|
||||||
|
except Exception as ex: # something is wrong
|
||||||
|
log('Accept group chat invite failed! ' + str(ex))
|
||||||
|
|
||||||
|
|
||||||
def tox_factory(data=None, settings=None):
|
def tox_factory(data=None, settings=None):
|
||||||
|
|
|
@ -1893,13 +1893,14 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
Write the Chat ID designated by the given group number to a byte array.
|
Write the Chat ID designated by the given group number to a byte array.
|
||||||
`chat_id` should have room for at least TOX_GROUP_CHAT_ID_SIZE bytes.
|
`chat_id` should have room for at least TOX_GROUP_CHAT_ID_SIZE bytes.
|
||||||
:return true on success.
|
:return chat id.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
|
buff = create_string_buffer(TOX_GROUP_CHAT_ID_SIZE)
|
||||||
result = Tox.libtoxcore.tox_group_get_chat_id(self._tox_pointer, groupnumber,
|
result = Tox.libtoxcore.tox_group_get_chat_id(self._tox_pointer, groupnumber,
|
||||||
create_string_buffer(TOX_GROUP_CHAT_ID_SIZE), byref(error))
|
buff, byref(error))
|
||||||
return result
|
return bin_to_string(buff[:TOX_GROUP_CHAT_ID_SIZE], TOX_GROUP_CHAT_ID_SIZE)
|
||||||
|
|
||||||
def group_get_number_groups(self):
|
def group_get_number_groups(self):
|
||||||
"""
|
"""
|
||||||
|
@ -2093,6 +2094,15 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
Set the callback for the `group_message` event. Pass NULL to unset.
|
Set the callback for the `group_message` event. Pass NULL to unset.
|
||||||
This event is triggered when the client receives a group message.
|
This event is triggered when the client receives a group message.
|
||||||
|
|
||||||
|
Callback: python function with params:
|
||||||
|
tox Tox* instance
|
||||||
|
groupnumber The group number of the group the message is intended for.
|
||||||
|
peer_id The ID of the peer who sent the message.
|
||||||
|
type The type of message (normal, action, ...).
|
||||||
|
message The message data.
|
||||||
|
length The length of the message.
|
||||||
|
user_data - user data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_int, c_char_p, c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_int, c_char_p, c_size_t, c_void_p)
|
||||||
|
@ -2140,7 +2150,7 @@ class Tox:
|
||||||
result = Tox.libtoxcore.tox_group_invite_friend(self._tox_pointer, groupnumber, friend_number, byref(error))
|
result = Tox.libtoxcore.tox_group_invite_friend(self._tox_pointer, groupnumber, friend_number, byref(error))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def group_invite_accept(self, invite_data, password):
|
def group_invite_accept(self, invite_data, password=None):
|
||||||
"""
|
"""
|
||||||
Accept an invite to a group chat that the client previously received from a friend. The invite
|
Accept an invite to a group chat that the client previously received from a friend. The invite
|
||||||
is only valid while the inviter is present in the group.
|
is only valid while the inviter is present in the group.
|
||||||
|
@ -2151,8 +2161,10 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
result = Tox.libtoxcore.tox_group_invite_accept(self._tox_pointer, invite_data, len(invite_data), password,
|
result = Tox.libtoxcore.tox_group_invite_accept(self._tox_pointer, invite_data, len(invite_data),
|
||||||
len(password), byref(error))
|
password,
|
||||||
|
len(password) if password is not None else 0,
|
||||||
|
byref(error))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def callback_group_invite(self, callback, user_data):
|
def callback_group_invite(self, callback, user_data):
|
||||||
|
@ -2161,6 +2173,13 @@ class Tox:
|
||||||
|
|
||||||
This event is triggered when the client receives a group invite from a friend. The client must store
|
This event is triggered when the client receives a group invite from a friend. The client must store
|
||||||
invite_data which is used to join the group via tox_group_invite_accept.
|
invite_data which is used to join the group via tox_group_invite_accept.
|
||||||
|
|
||||||
|
Callback: python function with params:
|
||||||
|
tox - Tox*
|
||||||
|
friend_number The friend number of the contact who sent the invite.
|
||||||
|
invite_data The invite data.
|
||||||
|
length The length of invite_data.
|
||||||
|
user_data - user data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_char_p, c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_char_p, c_size_t, c_void_p)
|
||||||
|
|
Loading…
Reference in a new issue