From 81660a9ad4fa5d10eb6730f3c098a0215f9aa082 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Mon, 9 May 2016 18:32:29 +0300 Subject: [PATCH] file resuming support --- src/file_transfers.py | 3 ++ src/list_items.py | 86 +++++++++++++++++++++++++++++++------------ src/profile.py | 10 ++++- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/file_transfers.py b/src/file_transfers.py index ce8a99d..15eb554 100644 --- a/src/file_transfers.py +++ b/src/file_transfers.py @@ -12,6 +12,7 @@ TOX_FILE_TRANSFER_STATE = { 'PAUSED': 1, 'CANCELED': 2, 'FINISHED': 3, + 'PAUSED_BY_FRIEND': 4 } @@ -67,6 +68,8 @@ class FileTransfer(QtCore.QObject): 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.signal() def send_control(self, control): diff --git a/src/list_items.py b/src/list_items.py index f60f4ef..486709f 100644 --- a/src/list_items.py +++ b/src/list_items.py @@ -145,6 +145,8 @@ class FileTransferItem(QtGui.QListWidget): else: self.setStyleSheet('QWidget { background-color: #B40404; }') + self.state = state + self.name = DataLabel(self) self.name.setGeometry(QtCore.QRect(1, 15, 95, 20)) self.name.setTextFormat(QtCore.Qt.PlainText) @@ -174,15 +176,22 @@ class FileTransferItem(QtGui.QListWidget): self.cancel.clicked.connect(lambda: self.cancel_transfer(friend_number, file_number)) self.cancel.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; }') - self.accept = QtGui.QPushButton(self) - self.accept.setGeometry(QtCore.QRect(450, 2, 46, 46)) - pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png') - icon = QtGui.QIcon(pixmap) - self.accept.setIcon(icon) - self.accept.setIconSize(QtCore.QSize(30, 30)) - self.accept.clicked.connect(lambda: self.accept_transfer(friend_number, file_number, size)) - self.accept.setVisible(state == FILE_TRANSFER_MESSAGE_STATUS['INCOMING_NOT_STARTED']) - self.accept.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; }') + self.accept_or_pause = QtGui.QPushButton(self) + self.accept_or_pause.setGeometry(QtCore.QRect(450, 2, 46, 46)) + if state == FILE_TRANSFER_MESSAGE_STATUS['INCOMING_NOT_STARTED']: + self.accept_or_pause.setVisible(True) + self.button_update('accept') + elif state in (0, 1, 5): + self.accept_or_pause.setVisible(False) + elif state == FILE_TRANSFER_MESSAGE_STATUS['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.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; }') self.pb = QtGui.QProgressBar(self) self.pb.setGeometry(QtCore.QRect(100, 15, 100, 20)) @@ -212,27 +221,56 @@ class FileTransferItem(QtGui.QListWidget): pr.cancel_transfer(friend_number, file_number) self.setStyleSheet('QListWidget { background-color: #B40404; }') self.cancel.setVisible(False) - self.accept.setVisible(False) + self.accept_or_pause.setVisible(False) self.pb.setVisible(False) - def accept_transfer(self, friend_number, file_number, size): - directory = QtGui.QFileDialog.getExistingDirectory() - if directory: - pr = profile.Profile.get_instance() - pr.accept_transfer(self, directory + '/' + self.saved_name, friend_number, file_number, size) - self.accept.setVisible(False) + def accept_or_pause_transfer(self, friend_number, file_number, size): + if self.state == FILE_TRANSFER_MESSAGE_STATUS['INCOMING_NOT_STARTED']: + directory = QtGui.QFileDialog.getExistingDirectory() + if directory: + pr = profile.Profile.get_instance() + pr.accept_transfer(self, directory + '/' + self.saved_name, friend_number, file_number, size) + self.button_update('pause') + elif self.state == FILE_TRANSFER_MESSAGE_STATUS['PAUSED_BY_USER']: # resume + profile.Profile.get_instance().resume_transfer(friend_number, file_number) + else: # pause + profile.Profile.get_instance().pause_transfer(friend_number, file_number) + self.state = FILE_TRANSFER_MESSAGE_STATUS['PAUSED_BY_USER'] + self.accept_or_pause.clearFocus() + + def button_update(self, path): + pixmap = QtGui.QPixmap(curr_directory() + '/images/{}.png'.format(path)) + icon = QtGui.QIcon(pixmap) + self.accept_or_pause.setIcon(icon) + self.accept_or_pause.setIconSize(QtCore.QSize(30, 30)) + + def convert(self, state): + # convert TOX_FILE_TRANSFER_STATE to FILE_TRANSFER_MESSAGE_STATUS + d = {0: 2, 1: 6, 2: 1, 3: 0, 4: 5} + return d[state] @QtCore.Slot(int, float) def update(self, state, progress): self.pb.setValue(int(progress * 100)) - if state == TOX_FILE_TRANSFER_STATE['CANCELED']: - self.setStyleSheet('QListWidget { background-color: #B40404; }') - self.cancel.setVisible(False) - self.accept.setVisible(False) - self.pb.setVisible(False) - elif state == TOX_FILE_TRANSFER_STATE['FINISHED']: - self.pb.setVisible(False) - self.cancel.setVisible(False) + state = self.convert(state) + if self.state != state: + if state == FILE_TRANSFER_MESSAGE_STATUS['CANCELLED']: + self.setStyleSheet('QListWidget { background-color: #B40404; }') + self.cancel.setVisible(False) + self.accept_or_pause.setVisible(False) + self.pb.setVisible(False) + elif state == FILE_TRANSFER_MESSAGE_STATUS['FINISHED']: + self.accept_or_pause.setVisible(False) + self.pb.setVisible(False) + self.cancel.setVisible(False) + elif state == FILE_TRANSFER_MESSAGE_STATUS['PAUSED_BY_FRIEND']: + self.accept_or_pause.setVisible(False) + elif state == FILE_TRANSFER_MESSAGE_STATUS['PAUSED_BY_USER']: + self.button_update('resume') # setup button continue + else: # active + self.accept_or_pause.setVisible(True) # setup to pause + self.button_update('pause') + self.state = state class InlineImageItem(QtGui.QWidget): diff --git a/src/profile.py b/src/profile.py index 343ff81..7a3010c 100644 --- a/src/profile.py +++ b/src/profile.py @@ -953,6 +953,12 @@ class Profile(Contact, Singleton): def resume_transfer(self, friend_number, file_number, by_friend=False): self.get_friend_by_number(friend_number).update_transfer_data(file_number, FILE_TRANSFER_MESSAGE_STATUS['OUTGOING']) + tr = self._file_transfers[(friend_number, file_number)] + if by_friend: + tr.state = TOX_FILE_TRANSFER_STATE['RUNNING'] + tr.signal() + else: + tr.send_control(TOX_FILE_CONTROL['RESUME']) def accept_transfer(self, item, path, friend_number, file_number, size, inline=False): """ @@ -1018,7 +1024,7 @@ class Profile(Contact, Singleton): if (friend_number, file_number) in self._file_transfers: transfer = self._file_transfers[(friend_number, file_number)] transfer.write_chunk(position, data) - if transfer.state: + if transfer.state in (2, 3): # finished or cancelled if type(transfer) is ReceiveAvatar: self.get_friend_by_number(friend_number).load_avatar() self.set_active(None) @@ -1043,7 +1049,7 @@ class Profile(Contact, Singleton): if (friend_number, file_number) in self._file_transfers: transfer = self._file_transfers[(friend_number, file_number)] transfer.send_chunk(position, size) - if transfer.state: + if transfer.state in (2, 3): # finished or cancelled del self._file_transfers[(friend_number, file_number)] if type(transfer) is not SendAvatar: if type(transfer) is SendFromBuffer and Settings.get_instance()['allow_inline']: # inline