initial fixes for file transfers - messages, widgets

This commit is contained in:
ingvar1995 2018-05-16 19:04:02 +03:00
parent 7209dfae72
commit bfd2a92dde
11 changed files with 245 additions and 230 deletions

View File

@ -126,7 +126,7 @@ class TestFriend:
assert arr[0][0] == 'Not sent'
tm = TransferMessage(MESSAGE_OWNER['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
FILE_TRANSFER_STATE['RUNNING'],
100, 'file_name', friend.number, 0)
friend.append_message(tm)
friend.clear_corr()

View File

@ -28,6 +28,7 @@ from ui.items_factories import MessagesItemsFactory, FriendItemsFactory
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
class App:
@ -312,7 +313,11 @@ class App:
history.set_contacts_manager(self._contacts_manager)
self._messenger = Messenger(self._tox, self._plugin_loader, self._ms, self._contacts_manager,
self._contacts_provider, messages_items_factory, profile)
self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider)
file_transfers_message_service = FileTransfersMessagesService(self._contacts_manager, messages_items_factory,
profile, self._ms)
self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider,
file_transfers_message_service)
messages_items_factory.set_file_transfers_handler(self._file_transfer_handler)
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)

View File

@ -83,18 +83,18 @@ class ContactsManager:
current_contact.curr_text = self._screen.messageEdit.toPlainText()
except:
pass
friend = self._contacts[value]
self._subscribe_to_events(friend)
friend.remove_invalid_unsent_files()
contact = self._contacts[value]
self._subscribe_to_events(contact)
contact.remove_invalid_unsent_files()
if self._active_contact != value:
self._screen.messageEdit.setPlainText(friend.curr_text)
self._screen.messageEdit.setPlainText(contact.curr_text)
self._active_contact = value
friend.reset_messages()
contact.reset_messages()
if not self._settings['save_history']:
friend.delete_old_messages()
contact.delete_old_messages()
self._messages.clear()
friend.load_corr()
corr = friend.get_corr()[-PAGE_SIZE:]
contact.load_corr()
corr = contact.get_corr()[-PAGE_SIZE:]
for message in corr:
self._messages_items_factory.create_message_item(message)
# if value in self._call:
@ -103,12 +103,8 @@ class ContactsManager:
# self._screen.incoming_call()
# else:
# self._screen.call_finished()
self._set_current_contact_data(contact)
self._screen.account_status.setToolTip(friend.get_full_status())
avatar_path = friend.get_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
util.log('Friend value: ' + str(value))
util.log('Error in set active: ' + str(ex))
@ -433,8 +429,15 @@ class ContactsManager:
self._screen.account_status.setText(status_message)
def _current_contact_avatar_changed(self, avatar_path):
self._set_current_contact_avatar(avatar_path)
def _set_current_contact_data(self, contact):
self._screen.account_name.setText(contact.name)
self._screen.account_status.setText(contact.status_message)
self._set_current_contact_avatar(contact.get_avatar_path())
def _set_current_contact_avatar(self, avatar_path):
width = self._screen.account_avatar.width()
pixmap = QtGui.QPixmap(avatar_path)
self._screen.avatar_label.setPixmap(pixmap.scaled(width, width,
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation))
self._screen.account_avatar.setPixmap(pixmap.scaled(width, width,
QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))

View File

@ -91,7 +91,7 @@ class Profile(basecontact.BaseContact):
ft = self._file_transfers[(friend_num, file_num)]
if type(ft) is SendTransfer:
self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, False, -1]
elif type(ft) is ReceiveTransfer and ft.state != TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
elif type(ft) is ReceiveTransfer and ft.state != FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, True, ft.total_size()]
self.cancel_transfer(friend_num, file_num, True)

View File

@ -3,10 +3,10 @@ from os.path import basename, getsize, exists, dirname
from os import remove, rename, chdir
from time import time, sleep
from wrapper.tox import Tox
from PyQt5 import QtCore
from common.event import Event
TOX_FILE_TRANSFER_STATE = {
FILE_TRANSFER_STATE = {
'RUNNING': 0,
'PAUSED_BY_USER': 1,
'CANCELLED': 2,
@ -31,69 +31,58 @@ def is_inline(file_name):
return file_name in allowed_inlines or file_name.startswith('qTox_Screenshot_')
# TODO: use events from common.event.py
class StateSignal(QtCore.QObject):
signal = QtCore.pyqtSignal(int, float, int) # state, progress, time in sec
class TransferFinishedSignal(QtCore.QObject):
signal = QtCore.pyqtSignal(int, int) # friend number, file number
class FileTransfer(QtCore.QObject):
class FileTransfer:
"""
Superclass for file transfers
"""
def __init__(self, path, tox, friend_number, size, file_number=None):
QtCore.QObject.__init__(self)
self._path = path
self._tox = tox
self._friend_number = friend_number
self.state = TOX_FILE_TRANSFER_STATE['RUNNING']
self.state = FILE_TRANSFER_STATE['RUNNING']
self._file_number = file_number
self._creation_time = None
self._size = float(size)
self._done = 0
self._state_changed = StateSignal()
self._finished = TransferFinishedSignal()
self._state_changed_event = Event()
self._finished_event = Event()
self._file_id = None
def set_tox(self, tox):
self._tox = tox
def set_state_changed_handler(self, handler):
self._state_changed.signal.connect(handler)
self._state_changed_event += handler
def set_transfer_finished_handler(self, handler):
self._finished.signal.connect(handler)
def signal(self):
percentage = self._done / self._size if self._size else 0
if self._creation_time is None or not percentage:
t = -1
else:
t = ((time() - self._creation_time) / percentage) * (1 - percentage)
self._state_changed.signal.emit(self.state, percentage, int(t))
def finished(self):
self._finished.signal.emit(self._friend_number, self._file_number)
self._finished_event += handler
def get_file_number(self):
return self._file_number
file_number = property(get_file_number)
def get_friend_number(self):
return self._friend_number
def get_id(self):
friend_number = property(get_friend_number)
def get_file_id(self):
return self._file_id
file_id = property(get_file_id)
def get_path(self):
return self._path
path = property(get_path)
def get_size(self):
return self._size
size = property(get_size)
def cancel(self):
self.send_control(TOX_FILE_CONTROL['CANCEL'])
if hasattr(self, '_file'):
@ -104,14 +93,14 @@ class FileTransfer(QtCore.QObject):
if hasattr(self, '_file'):
sleep(0.1)
self._file.close()
self.state = TOX_FILE_TRANSFER_STATE['CANCELLED']
self.state = FILE_TRANSFER_STATE['CANCELLED']
self.signal()
def pause(self, by_friend):
if not by_friend:
self.send_control(TOX_FILE_CONTROL['PAUSE'])
else:
self.state = TOX_FILE_TRANSFER_STATE['PAUSED_BY_FRIEND']
self.state = FILE_TRANSFER_STATE['PAUSED_BY_FRIEND']
self.signal()
def send_control(self, control):
@ -122,6 +111,17 @@ class FileTransfer(QtCore.QObject):
def get_file_id(self):
return self._tox.file_get_file_id(self._friend_number, self._file_number)
def signal(self):
percentage = self._done / self._size if self._size else 0
if self._creation_time is None or not percentage:
t = -1
else:
t = ((time() - self._creation_time) / percentage) * (1 - percentage)
self._state_changed_event(self.state, percentage, int(t))
def _finished(self):
self._finished_event(self._friend_number, self._file_number)
# -----------------------------------------------------------------------------------------------------------------
# Send file
# -----------------------------------------------------------------------------------------------------------------
@ -136,7 +136,7 @@ class SendTransfer(FileTransfer):
else:
size = 0
super().__init__(path, tox, friend_number, size)
self.state = TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
self.state = FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
self._file_number = tox.file_send(friend_number, kind, size, file_id,
bytes(basename(path), 'utf-8') if path else b'')
self._file_id = self.get_file_id()
@ -157,8 +157,8 @@ class SendTransfer(FileTransfer):
else:
if hasattr(self, '_file'):
self._file.close()
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
self.finished()
self.state = FILE_TRANSFER_STATE['FINISHED']
self._finished()
self.signal()
@ -183,7 +183,7 @@ class SendFromBuffer(FileTransfer):
def __init__(self, tox, friend_number, data, file_name):
super().__init__(None, tox, friend_number, len(data))
self.state = TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
self.state = FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
self._data = data
self._file_number = tox.file_send(friend_number, TOX_FILE_KIND['DATA'],
len(data), None, bytes(file_name, 'utf-8'))
@ -199,8 +199,8 @@ class SendFromBuffer(FileTransfer):
self._tox.file_send_chunk(self._friend_number, self._file_number, position, data)
self._done += size
else:
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
self.finished()
self.state = FILE_TRANSFER_STATE['FINISHED']
self._finished()
self.signal()
@ -250,8 +250,8 @@ class ReceiveTransfer(FileTransfer):
self._creation_time = time()
if data is None:
self._file.close()
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
self.finished()
self.state = FILE_TRANSFER_STATE['FINISHED']
self._finished()
else:
data = bytearray(data)
if self._file_size < position:
@ -286,8 +286,8 @@ class ReceiveToBuffer(FileTransfer):
if self._creation_time is None:
self._creation_time = time()
if data is None:
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
self.finished()
self.state = FILE_TRANSFER_STATE['FINISHED']
self._finished()
else:
data = bytes(data)
l = len(data)
@ -342,8 +342,8 @@ class ReceiveAvatar(ReceiveTransfer):
chdir(dirname(avatar_path))
remove(avatar_path)
rename(self._path, avatar_path)
self.finished(True)
self._finished(True)
def finished(self, emit=False):
def _finished(self, emit=False):
if emit:
super().finished()
super()._finished()

View File

@ -8,10 +8,11 @@ import utils.util as util
class FileTransfersHandler:
def __init__(self, tox, settings, contact_provider):
def __init__(self, tox, settings, contact_provider, file_transfers_message_service):
self._tox = tox
self._settings = settings
self._contact_provider = contact_provider
self._file_transfers_message_service = file_transfers_message_service
self._file_transfers = {}
# key = (friend number, file number), value - transfer instance
self._paused_file_transfers = dict(settings['paused_file_transfers'])
@ -46,51 +47,17 @@ class FileTransfersHandler:
return
self._tox.file_seek(friend_number, file_number, pos)
self.accept_transfer(None, data[0], friend_number, file_number, size, False, pos)
tm = TransferMessage(MESSAGE_AUTHOR['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
size,
file_name,
friend_number,
file_number)
elif inline and size < 1024 * 1024:
self.accept_transfer(None, '', friend_number, file_number, size, True)
tm = TransferMessage(MESSAGE_AUTHOR['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
size,
file_name,
friend_number,
file_number)
elif auto:
path = self._settings['auto_accept_path'] or util.curr_directory()
self.accept_transfer(None, path + '/' + file_name, friend_number, file_number, size)
tm = TransferMessage(MESSAGE_AUTHOR['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
size,
file_name,
friend_number,
file_number)
else:
tm = TransferMessage(MESSAGE_AUTHOR['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED'],
size,
file_name,
friend_number,
file_number)
accepted = False
if friend_number == self.get_active_number() and self.is_active_a_friend():
item = self.create_file_transfer_item(tm)
if accepted:
self._file_transfers[(friend_number, file_number)].set_state_changed_handler(item.update_transfer_state)
self._messages.scrollToBottom()
else:
friend.actions = True
friend.append_message(tm)
self._file_transfers_message_service.add_incoming_transfer_message(
friend, accepted, size, file_name,file_number)
def cancel_transfer(self, friend_number, file_number, already_cancelled=False):
"""
@ -100,7 +67,7 @@ class FileTransfersHandler:
:param already_cancelled: was cancelled by friend
"""
i = self._get_friend_by_number(friend_number).update_transfer_data(file_number,
TOX_FILE_TRANSFER_STATE['CANCELLED'])
FILE_TRANSFER_STATE['CANCELLED'])
if (friend_number, file_number) in self._file_transfers:
tr = self._file_transfers[(friend_number, file_number)]
if not already_cancelled:
@ -117,12 +84,11 @@ class FileTransfersHandler:
tmp = self._messages.count() + i
if tmp >= 0:
self._messages.itemWidget(
self._messages.item(tmp)).update_transfer_state(TOX_FILE_TRANSFER_STATE['CANCELLED'],
self._messages.item(tmp)).update_transfer_state(FILE_TRANSFER_STATE['CANCELLED'],
0, -1)
def cancel_not_started_transfer(self, cancel_time):
self.get_curr_friend().delete_one_unsent_file(cancel_time)
self.update()
def pause_transfer(self, friend_number, file_number, by_friend=False):
"""
@ -130,7 +96,7 @@ class FileTransfersHandler:
"""
tr = self._file_transfers[(friend_number, file_number)]
tr.pause(by_friend)
t = TOX_FILE_TRANSFER_STATE['PAUSED_BY_FRIEND'] if by_friend else TOX_FILE_TRANSFER_STATE['PAUSED_BY_USER']
t = FILE_TRANSFER_STATE['PAUSED_BY_FRIEND'] if by_friend else FILE_TRANSFER_STATE['PAUSED_BY_USER']
self._get_friend_by_number(friend_number).update_transfer_data(file_number, t)
def resume_transfer(self, friend_number, file_number, by_friend=False):
@ -141,7 +107,7 @@ class FileTransfersHandler:
# TOX_FILE_TRANSFER_STATE['RUNNING'])
tr = self._file_transfers[(friend_number, file_number)]
if by_friend:
tr.state = TOX_FILE_TRANSFER_STATE['RUNNING']
tr.state = FILE_TRANSFER_STATE['RUNNING']
tr.signal()
else:
tr.send_control(TOX_FILE_CONTROL['RESUME'])
@ -177,7 +143,7 @@ class FileTransfersHandler:
if item is not None:
rt.set_state_changed_handler(item.update_transfer_state)
self._get_friend_by_number(friend_number).update_transfer_data(file_number,
TOX_FILE_TRANSFER_STATE['RUNNING'])
FILE_TRANSFER_STATE['RUNNING'])
def send_screenshot(self, data, friend_number):
"""
@ -201,18 +167,9 @@ class FileTransfersHandler:
raise RuntimeError()
st = SendFromBuffer(self._tox, friend.number, data, file_name)
st.set_transfer_finished_handler(self.transfer_finished)
self._file_transfers[(friend.number, st.get_file_number())] = st
tm = TransferMessage(MESSAGE_AUTHOR['ME'],
time.time(),
TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED'],
len(data),
file_name,
friend.number,
st.get_file_number())
item = self.create_file_transfer_item(tm)
friend.append_message(tm)
st.set_state_changed_handler(item.update_transfer_state)
self._messages.scrollToBottom()
file_number = st.get_file_number()
self._file_transfers[(friend.number, file_number)] = st
self._file_transfers_message_service.add_outgoing_transfer_message(friend, st.size, file_name, file_number)
def send_file(self, path, friend_number, is_resend=False, file_id=None):
"""
@ -232,19 +189,10 @@ class FileTransfersHandler:
raise RuntimeError()
st = SendTransfer(path, self._tox, friend_number, TOX_FILE_KIND['DATA'], file_id)
st.set_transfer_finished_handler(self.transfer_finished)
self._file_transfers[(friend_number, st.get_file_number())] = st
# tm = TransferMessage(MESSAGE_AUTHOR['ME'],
# time.time(),
# TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED'],
# os.path.getsize(path),
# os.path.basename(path),
# friend_number,
# st.get_file_number())
# if friend_number == self.get_active_number():
# item = self.create_file_transfer_item(tm)
# st.set_state_changed_handler(item.update_transfer_state)
# self._messages.scrollToBottom()
# self._contacts[friend_number].append_message(tm)
file_number = st.get_file_number()
self._file_transfers[(friend_number, file_number)] = st
file_name = os.path.basename(path)
self._file_transfers_message_service.add_outgoing_transfer_message(friend, st.size, file_name, file_number)
def incoming_chunk(self, friend_number, file_number, position, data):
"""
@ -266,21 +214,13 @@ class FileTransfersHandler:
elif t is ReceiveToBuffer or (t is SendFromBuffer and self._settings['allow_inline']): # inline image
print('inline')
inline = InlineImage(transfer.get_data())
i = self._get_friend_by_number(friend_number).update_transfer_data(file_number,
TOX_FILE_TRANSFER_STATE['FINISHED'],
inline)
if friend_number == self.get_active_number() and self.is_active_a_friend():
count = self._messages.count()
if count + i + 1 >= 0:
elem = QtWidgets.QListWidgetItem()
item = InlineImageItem(transfer.get_data(), self._messages.width(), elem)
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
self._messages.insertItem(count + i + 1, elem)
self._messages.setItemWidget(elem, item)
self._messages.scrollToBottom()
index = self._get_friend_by_number(friend_number).update_transfer_data(file_number,
FILE_TRANSFER_STATE['FINISHED'],
inline)
self._file_transfers_message_service.add_inline_message(transfer, index)
elif t is not SendAvatar:
self._get_friend_by_number(friend_number).update_transfer_data(file_number,
TOX_FILE_TRANSFER_STATE['FINISHED'])
FILE_TRANSFER_STATE['FINISHED'])
del self._file_transfers[(friend_number, file_number)]
del transfer
@ -288,7 +228,7 @@ class FileTransfersHandler:
friend = self._get_friend_by_number(friend_number)
friend.remove_invalid_unsent_files()
files = friend.get_unsent_files()
try:
try: # TODO: fix
for fl in files:
data = fl.get_data()
if data[1] is not None:
@ -327,7 +267,7 @@ class FileTransfersHandler:
"""
friend = self._get_friend_by_number(friend_number)
ra = ReceiveAvatar(friend.get_contact_avatar_path(), self._tox, friend_number, size, file_number)
if ra.state != TOX_FILE_TRANSFER_STATE['CANCELLED']:
if ra.state != FILE_TRANSFER_STATE['CANCELLED']:
self._file_transfers[(friend_number, file_number)] = ra
ra.set_transfer_finished_handler(self.transfer_finished)
else:

View File

@ -0,0 +1,58 @@
from messenger.messenger import *
import utils.util as util
from file_transfers.file_transfers import *
class FileTransfersMessagesService:
def __init__(self, contacts_manager, messages_items_factory, profile, main_screen):
self._contacts_manager = contacts_manager
self._messages_items_factory = messages_items_factory
self._profile = profile
self._messages = main_screen.messages
def add_incoming_transfer_message(self, friend, accepted, size, file_name, file_number):
author = MessageAuthor(friend.name, MESSAGE_AUTHOR['FRIEND'])
status = FILE_TRANSFER_STATE['RUNNING'] if accepted else FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']
tm = TransferMessage(author, util.get_unix_time(), status, size, file_name, friend.number, file_number)
if self._is_active(friend.number):
self._create_file_transfer_item(tm)
self._messages.scrollToBottom()
else:
friend.actions = True
friend.append_message(tm)
def add_outgoing_transfer_message(self, friend, size, file_name, file_number):
author = MessageAuthor(self._profile.name, MESSAGE_AUTHOR['ME'])
status = FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
tm = TransferMessage(author, util.get_unix_time(), status, size, file_name, friend.number, file_number)
if self._is_active(friend.number):
self._create_file_transfer_item(tm)
self._messages.scrollToBottom()
friend.append_message(tm)
def add_inline_message(self, transfer, index):
if self._is_active(transfer.friend_number):
count = self._messages.count()
if count + index + 1 >= 0:
self._create_inline_item(transfer.data, count + index + 1)
# -----------------------------------------------------------------------------------------------------------------
# Private methods
# -----------------------------------------------------------------------------------------------------------------
def _is_active(self, friend_number):
if not self._contacts_manager.is_active_a_friend():
return False
return friend_number == self._contacts_manager.get_active_number()
def _create_file_transfer_item(self, tm):
return self._messages_items_factory.create_file_transfer_item(tm)
def _create_inline_item(self, data, position):
return self._messages_items_factory.create_inline_item(data, False, position)

View File

@ -126,27 +126,43 @@ class TransferMessage(Message):
Message with info about file transfer
"""
def __init__(self, owner, time, status, size, name, friend_number, file_number):
super().__init__(MESSAGE_TYPE['FILE_TRANSFER'], owner, time)
self._status = status
def __init__(self, author, time, state, size, file_name, friend_number, file_number):
super().__init__(MESSAGE_TYPE['FILE_TRANSFER'], author, time)
self._state = state
self._size = size
self._file_name = name
self._file_name = file_name
self._friend_number, self._file_number = friend_number, file_number
def is_active(self, file_number):
return self._file_number == file_number and self._status not in (2, 3)
return self._file_number == file_number and self._state not in (2, 3)
def get_friend_number(self):
return self._friend_number
friend_number = property(get_friend_number)
def get_file_number(self):
return self._file_number
def get_status(self):
return self._status
file_number = property(get_file_number)
def set_status(self, value):
self._status = value
def get_state(self):
return self._state
def set_state(self, value):
self._state = value
state = property(get_state, set_state)
def get_size(self):
return self._size
size = property(get_size)
def get_file_name(self):
return self._file_name
file_name = property(get_file_name)
class UnsentFile(Message):

View File

@ -1,7 +1,7 @@
from wrapper.toxcore_enums_and_consts import *
from PyQt5 import QtCore, QtGui, QtWidgets
from contacts import profile
from file_transfers.file_transfers import TOX_FILE_TRANSFER_STATE, PAUSED_FILE_TRANSFERS, DO_NOT_SHOW_ACCEPT_BUTTON, ACTIVE_FILE_TRANSFERS, SHOW_PROGRESS_BAR
from file_transfers.file_transfers import FILE_TRANSFER_STATE, PAUSED_FILE_TRANSFERS, DO_NOT_SHOW_ACCEPT_BUTTON, ACTIVE_FILE_TRANSFERS, SHOW_PROGRESS_BAR
from utils.util import *
from ui.widgets import DataLabel, create_menu
from user_data import settings

View File

@ -18,16 +18,18 @@ class FriendItemsFactory:
return item
# TODO: accept messages everywhere instead of params
class MessagesItemsFactory:
def __init__(self, settings, plugin_loader, smiley_loader, main_screen, delete_action):
self._file_transfers_handler = None
self._settings, self._plugin_loader = settings, plugin_loader
self._smiley_loader, self._delete_action = smiley_loader, delete_action
self._messages = main_screen.messages
self._message_edit = main_screen.messageEdit
def set_file_transfers_handler(self, file_transfers_handler):
self._file_transfers_handler = file_transfers_handler
def create_message_item(self, message, append=True, pixmap=None):
item = message.get_widget(self._settings, self._create_message_browser,
self._delete_action, self._messages)
@ -43,24 +45,20 @@ class MessagesItemsFactory:
return item
def create_inline_item(self, data, append):
def create_inline_item(self, data, append, position=0):
elem = QtWidgets.QListWidgetItem()
item = InlineImageItem(data, self._messages.width(), elem)
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
if append:
self._messages.addItem(elem)
else:
self._messages.insertItem(0, elem)
self._messages.insertItem(position, elem)
self._messages.setItemWidget(elem, item)
return item
def create_unsent_file_item(self, file_name, size, name, time, append):
item = UnsentFileItem(file_name,
size,
name,
time,
self._messages.width())
def create_unsent_file_item(self, tm, append):
item = UnsentFileItem(self._file_transfers_handler, self._settings, tm, self._messages.width())
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(self._messages.width() - 30, 34))
if append:
@ -71,9 +69,8 @@ class MessagesItemsFactory:
return item
def create_file_transfer_item(self, data, append=True):
data.append(self._messages.width())
item = FileTransferItem(*data)
def create_file_transfer_item(self, tm, append=True):
item = FileTransferItem(self._file_transfers_handler, self._settings, tm, self._messages.width())
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(self._messages.width() - 30, 34))
if append:

View File

@ -6,7 +6,9 @@ import utils.util as util
import ui.menu as menu
import html as h
import re
from ui.widgets import *
from messenger.messages import MESSAGE_AUTHOR
from file_transfers.file_transfers import *
class MessageBrowser(QtWidgets.QTextBrowser):
@ -216,60 +218,63 @@ class MessageItem(QtWidgets.QWidget):
class FileTransferItem(QtWidgets.QListWidget):
def __init__(self, file_name, size, time, user, friend_number, file_number, state, width, parent=None):
def __init__(self, file_transfers_handler, settings, transfer_message, width, parent=None):
QtWidgets.QListWidget.__init__(self, parent)
self._file_transfers_handler = file_transfers_handler
self.resize(QtCore.QSize(width, 34))
if state == TOX_FILE_TRANSFER_STATE['CANCELLED']:
if transfer_message.state == FILE_TRANSFER_STATE['CANCELLED']:
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
elif state in PAUSED_FILE_TRANSFERS:
elif transfer_message.state in PAUSED_FILE_TRANSFERS:
self.setStyleSheet('QListWidget { border: 1px solid #FF8000; }')
else:
self.setStyleSheet('QListWidget { border: 1px solid green; }')
self.state = state
self.state = transfer_message.state
self.name = DataLabel(self)
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.setFamily(settings['font'])
font.setPointSize(11)
font.setBold(True)
self.name.setFont(font)
self.name.setText(user)
self.name.setText(transfer_message.author.name)
self.time = QtWidgets.QLabel(self)
self.time.setGeometry(QtCore.QRect(width - 60, 7, 50, 25))
font.setPointSize(10)
font.setBold(False)
self.time.setFont(font)
self.time.setText(convert_time(time))
self.time.setText(util.convert_time(time))
self.cancel = QtWidgets.QPushButton(self)
self.cancel.setGeometry(QtCore.QRect(width - 125, 2, 30, 30))
pixmap = QtGui.QPixmap(curr_directory() + '/images/decline.png')
pixmap = QtGui.QPixmap(util.join_path(util.get_images_directory(), 'decline.png'))
icon = QtGui.QIcon(pixmap)
self.cancel.setIcon(icon)
self.cancel.setIconSize(QtCore.QSize(30, 30))
self.cancel.setVisible(state in ACTIVE_FILE_TRANSFERS)
self.cancel.clicked.connect(lambda: self.cancel_transfer(friend_number, file_number))
self.cancel.setVisible(transfer_message.state in ACTIVE_FILE_TRANSFERS)
self.cancel.clicked.connect(
lambda: self.cancel_transfer(transfer_message.friend_number, transfer_message.file_number))
self.cancel.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; background-color: none;}')
self.accept_or_pause = QtWidgets.QPushButton(self)
self.accept_or_pause.setGeometry(QtCore.QRect(width - 170, 2, 30, 30))
if state == TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
if transfer_message.state == FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
self.accept_or_pause.setVisible(True)
self.button_update('accept')
elif state in DO_NOT_SHOW_ACCEPT_BUTTON:
elif transfer_message.state in DO_NOT_SHOW_ACCEPT_BUTTON:
self.accept_or_pause.setVisible(False)
elif state == TOX_FILE_TRANSFER_STATE['PAUSED_BY_USER']: # setup for continue
elif transfer_message.state == FILE_TRANSFER_STATE['PAUSED_BY_USER']: # setup for continue
self.accept_or_pause.setVisible(True)
self.button_update('resume')
else: # pause
self.accept_or_pause.setVisible(True)
self.button_update('pause')
self.accept_or_pause.clicked.connect(lambda: self.accept_or_pause_transfer(friend_number, file_number, size))
self.accept_or_pause.clicked.connect(
lambda: self.accept_or_pause_transfer(transfer_message.friend_number, transfer_message.file_number,
transfer_message.size))
self.accept_or_pause.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; background-color: none}')
@ -277,64 +282,60 @@ class FileTransferItem(QtWidgets.QListWidget):
self.pb.setGeometry(QtCore.QRect(100, 7, 100, 20))
self.pb.setValue(0)
self.pb.setStyleSheet('QProgressBar { background-color: #302F2F; }')
self.pb.setVisible(state in SHOW_PROGRESS_BAR)
self.pb.setVisible(transfer_message.state in SHOW_PROGRESS_BAR)
self.file_name = DataLabel(self)
self.file_name.setGeometry(QtCore.QRect(210, 7, width - 420, 20))
font.setPointSize(12)
self.file_name.setFont(font)
file_size = size // 1024
file_size = transfer_message.size // 1024
if not file_size:
file_size = '{}B'.format(size)
file_size = '{}B'.format(transfer_message.size)
elif file_size >= 1024:
file_size = '{}MB'.format(file_size // 1024)
else:
file_size = '{}KB'.format(file_size)
file_data = '{} {}'.format(file_size, file_name)
file_data = '{} {}'.format(file_size, transfer_message.file_name)
self.file_name.setText(file_data)
self.file_name.setToolTip(file_name)
self.saved_name = file_name
self.file_name.setToolTip(transfer_message.file_name)
self.saved_name = transfer_message.file_name
self.time_left = QtWidgets.QLabel(self)
self.time_left.setGeometry(QtCore.QRect(width - 92, 7, 30, 20))
font.setPointSize(10)
self.time_left.setFont(font)
self.time_left.setVisible(state == TOX_FILE_TRANSFER_STATE['RUNNING'])
self.time_left.setVisible(transfer_message.state == FILE_TRANSFER_STATE['RUNNING'])
self.setFocusPolicy(QtCore.Qt.NoFocus)
self.paused = False
def cancel_transfer(self, friend_number, file_number):
pr = profile.Profile.get_instance()
pr.cancel_transfer(friend_number, file_number)
self._file_transfers_handler.cancel_transfer(friend_number, file_number)
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
self.cancel.setVisible(False)
self.accept_or_pause.setVisible(False)
self.pb.setVisible(False)
def accept_or_pause_transfer(self, friend_number, file_number, size):
if self.state == TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow", 'Choose folder'),
curr_directory(),
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if self.state == FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
directory = util_ui.directory_dialog(util_ui.tr('Choose folder'))
self.pb.setVisible(True)
if directory:
pr = profile.Profile.get_instance()
pr.accept_transfer(self, directory + '/' + self.saved_name, friend_number, file_number, size)
self._file_transfer_handler.accept_transfer(self, directory + '/' + self.saved_name,
friend_number, file_number, size)
self.button_update('pause')
elif self.state == TOX_FILE_TRANSFER_STATE['PAUSED_BY_USER']: # resume
elif self.state == FILE_TRANSFER_STATE['PAUSED_BY_USER']: # resume
self.paused = False
profile.Profile.get_instance().resume_transfer(friend_number, file_number)
self._file_transfer_handler.resume_transfer(friend_number, file_number)
self.button_update('pause')
self.state = TOX_FILE_TRANSFER_STATE['RUNNING']
self.state = FILE_TRANSFER_STATE['RUNNING']
else: # pause
self.paused = True
self.state = TOX_FILE_TRANSFER_STATE['PAUSED_BY_USER']
profile.Profile.get_instance().pause_transfer(friend_number, file_number)
self.state = FILE_TRANSFER_STATE['PAUSED_BY_USER']
self._file_transfer_handler.pause_transfer(friend_number, file_number)
self.button_update('resume')
self.accept_or_pause.clearFocus()
def button_update(self, path):
pixmap = QtGui.QPixmap(curr_directory() + '/images/{}.png'.format(path))
pixmap = QtGui.QPixmap(util.join_path(util.get_images_directory(), '{}.png'.format(path)))
icon = QtGui.QIcon(pixmap)
self.accept_or_pause.setIcon(icon)
self.accept_or_pause.setIconSize(QtCore.QSize(30, 30))
@ -345,31 +346,31 @@ class FileTransferItem(QtWidgets.QListWidget):
m, s = divmod(time, 60)
self.time_left.setText('{0:02d}:{1:02d}'.format(m, s))
if self.state != state and self.state in ACTIVE_FILE_TRANSFERS:
if state == TOX_FILE_TRANSFER_STATE['CANCELLED']:
if state == FILE_TRANSFER_STATE['CANCELLED']:
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
self.cancel.setVisible(False)
self.accept_or_pause.setVisible(False)
self.pb.setVisible(False)
self.state = state
self.time_left.setVisible(False)
elif state == TOX_FILE_TRANSFER_STATE['FINISHED']:
elif state == FILE_TRANSFER_STATE['FINISHED']:
self.accept_or_pause.setVisible(False)
self.pb.setVisible(False)
self.cancel.setVisible(False)
self.setStyleSheet('QListWidget { border: 1px solid green; }')
self.state = state
self.time_left.setVisible(False)
elif state == TOX_FILE_TRANSFER_STATE['PAUSED_BY_FRIEND']:
elif state == FILE_TRANSFER_STATE['PAUSED_BY_FRIEND']:
self.accept_or_pause.setVisible(False)
self.setStyleSheet('QListWidget { border: 1px solid #FF8000; }')
self.state = state
self.time_left.setVisible(False)
elif state == TOX_FILE_TRANSFER_STATE['PAUSED_BY_USER']:
elif state == FILE_TRANSFER_STATE['PAUSED_BY_USER']:
self.button_update('resume') # setup button continue
self.setStyleSheet('QListWidget { border: 1px solid green; }')
self.state = state
self.time_left.setVisible(False)
elif state == TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']:
elif state == FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']:
self.setStyleSheet('QListWidget { border: 1px solid #FF8000; }')
self.accept_or_pause.setVisible(False)
self.time_left.setVisible(False)
@ -382,24 +383,23 @@ class FileTransferItem(QtWidgets.QListWidget):
self.state = state
self.time_left.setVisible(True)
def mark_as_sent(self):
@staticmethod
def mark_as_sent():
return False
class UnsentFileItem(FileTransferItem):
def __init__(self, file_name, size, user, time, width, parent=None):
super(UnsentFileItem, self).__init__(file_name, size, time, user, -1, -1,
TOX_FILE_TRANSFER_STATE['PAUSED_BY_FRIEND'], width, parent)
def __init__(self, file_transfers_handler, settings, transfer_message, width, parent=None):
super().__init__(file_transfers_handler, settings, transfer_message, width, parent)
self._time = time
self.pb.setVisible(False)
movie = QtGui.QMovie(join_path(get_images_directory(), 'spinner.gif'))
movie = QtGui.QMovie(util.join_path(util.get_images_directory(), 'spinner.gif'))
self.time.setMovie(movie)
movie.start()
def cancel_transfer(self, *args):
pr = profile.Profile.get_instance()
pr.cancel_not_started_transfer(self._time)
self._file_transfers_handler.cancel_not_started_transfer(self._time)
class InlineImageItem(QtWidgets.QScrollArea):
@ -443,15 +443,11 @@ 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'),
curr_directory(),
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
directory = util_ui.directory_dialog(util_ui.tr('Choose folder'))
if directory:
fl = QtCore.QFile(directory + '/toxygen_inline_' + curr_time().replace(':', '_') + '.png')
fl = QtCore.QFile(directory + '/toxygen_inline_' + util.curr_time().replace(':', '_') + '.png')
self._pixmap.save(fl, 'PNG')
def mark_as_sent(self):
@staticmethod
def mark_as_sent():
return False