diff --git a/src/file_transfers.py b/src/file_transfers.py index 60a8c31..a088510 100644 --- a/src/file_transfers.py +++ b/src/file_transfers.py @@ -143,7 +143,7 @@ class ReceiveTransfer(FileTransfer): if data is None: self._file.close() self.state = TOX_FILE_TRANSFER_STATE['FINISHED'] - self._state_changed.signal.emit(self.state, self._done / self._size if self._size else 0) + self._state_changed.signal.emit(self.state, 1) else: data = ''.join(chr(x) for x in data) if self._file_size < position: @@ -159,6 +159,32 @@ class ReceiveTransfer(FileTransfer): self._state_changed.signal.emit(self.state, self._done / self._size) +class ReceiveToBuffer(FileTransfer): + + def __init__(self, tox, friend_number, size, file_number): + super(ReceiveToBuffer, self).__init__(None, tox, friend_number, size, file_number) + self._data = '' + self._data_size = 0 + + def get_data(self): + return self._data + + def write_chunk(self, position, data): + if data is None: + self.state = TOX_FILE_TRANSFER_STATE['FINISHED'] + self._state_changed.signal.emit(self.state, 1) + else: + data = ''.join(chr(x) for x in data) + l = len(data) + if self._data_size < position: + self._data += ('\0' * (position - self._data_size)) + self._data = self._data[:position] + data + self._data[position + l:] + if position + l > self._data_size: + self._data_size = position + l + self._done += l + self._state_changed.signal.emit(self.state, self._done / self._size) + + class ReceiveAvatar(ReceiveTransfer): MAX_AVATAR_SIZE = 512 * 1024 diff --git a/src/list_items.py b/src/list_items.py index 35cc6dd..48e971a 100644 --- a/src/list_items.py +++ b/src/list_items.py @@ -242,3 +242,40 @@ class FileTransferItem(QtGui.QListWidget): self.pb.setVisible(False) self.cancel.setVisible(False) + +class InlineImageItem(QtGui.QWidget): + + def __init__(self, time, user, data, parent=None): + + QtGui.QWidget.__init__(self, parent) + self.resize(QtCore.QSize(620, 500)) + # self.name = DataLabel(self) + # self.name.setGeometry(QtCore.QRect(1, 15, 95, 20)) + # self.name.setTextFormat(QtCore.Qt.PlainText) + # font = QtGui.QFont() + # font.setFamily("Times New Roman") + # font.setPointSize(11) + # font.setBold(True) + # self.name.setFont(font) + # self.name.setText(user) + # self.name.setStyleSheet('QLabel { color: black; }') + # + # self.time = QtGui.QLabel(self) + # self.time.setGeometry(QtCore.QRect(570, 2, 50, 46)) + # font.setPointSize(10) + # font.setBold(False) + # self.time.setFont(font) + # self.time.setText(convert_time(time)) + # self.time.setStyleSheet('QLabel { color: black; }') + # TODO: resize widget to picture size or resize picture + self._image_label = QtGui.QLabel(self) + self._image_label.raise_() + self._image_label.setGeometry(QtCore.QRect(0, 0, 600, 600)) + self._image_label.setScaledContents(False) + self.pixmap = QtGui.QPixmap() + print self.pixmap.loadFromData(QtCore.QByteArray(data), "PNG") + self._image_label.setPixmap(self.pixmap) + + + + diff --git a/src/main.py b/src/main.py index dd86ff5..2ce549a 100644 --- a/src/main.py +++ b/src/main.py @@ -75,7 +75,6 @@ class Toxygen(object): self.tox = tox_factory(data, settings) if ProfileHelper.is_active_profile(path, name): # profile is in use - deactivate = False reply = QtGui.QMessageBox.question(None, 'Profile {}'.format(name), QtGui.QApplication.translate("login", 'Looks like other instance of Toxygen uses this profile! Continue?', None, QtGui.QApplication.UnicodeUTF8), @@ -85,7 +84,6 @@ class Toxygen(object): return else: settings.set_active_profile() - deactivate = True lang = filter(lambda x: x[0] == settings['language'], Settings.supported_languages())[0] translator = QtCore.QTranslator() @@ -136,8 +134,7 @@ class Toxygen(object): self.init.wait() data = self.tox.get_savedata() ProfileHelper.save_profile(data) - if deactivate: - settings.close() + settings.close() del self.tox def reset(self): diff --git a/src/profile.py b/src/profile.py index 48eebab..732379b 100644 --- a/src/profile.py +++ b/src/profile.py @@ -1,4 +1,4 @@ -from list_items import MessageItem, ContactItem, FileTransferItem +from list_items import MessageItem, ContactItem, FileTransferItem, InlineImageItem from PySide import QtCore, QtGui from tox import Tox import os @@ -194,16 +194,19 @@ class Friend(Contact): """ if hasattr(self, '_message_getter'): del self._message_getter - self._corr = filter(lambda x: x.get_type() > 1, self._corr) + self._corr = filter(lambda x: x.get_type() == 2, self._corr) self._unsaved_messages = 0 - def update_transfer_data(self, file_number, status): + def update_transfer_data(self, file_number, status, inline=None): """ Update status of active transfer """ try: - tr = filter(lambda x: x.get_type() == 2 and x.is_active(file_number), self._corr)[0] + tr = filter(lambda x: x.get_type() >= 2 and x.is_active(file_number), self._corr)[0] tr.set_status(status) + if inline: # inline was loaded + i = self._corr.index(tr) + self._corr.insert(i, inline) except: pass @@ -397,6 +400,8 @@ class Profile(Contact, Singleton): if message.get_status() in (2, 4): # active file transfer ft = self._file_transfers[(message.get_friend_number(), message.get_file_number())] ft.set_state_changed_handler(item.update) + else: # inline + self.create_inline_item(message.get_data()) self._messages.scrollToBottom() else: friend = self._friends[self._active_friend] @@ -593,6 +598,17 @@ class Profile(Contact, Singleton): self._messages.repaint() return item + def create_inline_item(self, data, append=True): + item = InlineImageItem(0, '', data) + elem = QtGui.QListWidgetItem() + elem.setSizeHint(QtCore.QSize(600, 600)) + if append: + self._messages.addItem(elem) + else: + self._messages.insertItem(0, elem) + self._messages.setItemWidget(elem, item) + self._messages.repaint() + # ----------------------------------------------------------------------------------------------------------------- # Work with friends (remove, set alias, get public key) # ----------------------------------------------------------------------------------------------------------------- @@ -732,7 +748,18 @@ class Profile(Contact, Singleton): settings = Settings.get_instance() friend = self.get_friend_by_number(friend_number) file_name = file_name.decode('utf-8') - if settings['allow_auto_accept'] and friend.tox_id in settings['auto_accept_from_friends']: + auto = settings['allow_auto_accept'] and friend.tox_id in settings['auto_accept_from_friends'] + inline = (file_name == 'toxygen_inline.png' or file_name == 'utox-inline.png') and settings['allow_inline'] + if inline and size < 1024 * 1024: + self.accept_transfer(None, '', friend_number, file_number, size, True) + tm = TransferMessage(MESSAGE_OWNER['FRIEND'], + time.time(), + FILE_TRANSFER_MESSAGE_STATUS['INCOMING_STARTED'], + size, + file_name, + friend_number, + file_number) + elif auto: path = settings['auto_accept_path'] or curr_directory() new_file_name, i = file_name, 1 while os.path.isfile(path + '/' + new_file_name): # file with same name already exists @@ -784,20 +811,24 @@ class Profile(Contact, Singleton): self.get_friend_by_number(friend_number).update_transfer_data(file_number, FILE_TRANSFER_MESSAGE_STATUS['CANCELLED']) - def accept_transfer(self, item, path, friend_number, file_number, size): + def accept_transfer(self, item, path, friend_number, file_number, size, inline=False): """ - :param item: transfer item + :param item: transfer item. None if auto accept :param path: path for saving :param friend_number: friend number :param file_number: file number :param size: file size """ - rt = ReceiveTransfer(path, self._tox, friend_number, size, file_number) + if not inline: + rt = ReceiveTransfer(path, self._tox, friend_number, size, file_number) + else: + rt = ReceiveToBuffer(self._tox, friend_number, size, file_number) self._file_transfers[(friend_number, file_number)] = rt self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['RESUME']) if item is not None: rt.set_state_changed_handler(item.update) - self.get_friend_by_number(friend_number).update_transfer_data(file_number, FILE_TRANSFER_MESSAGE_STATUS['INCOMING_STARTED']) + self.get_friend_by_number(friend_number).update_transfer_data(file_number, + FILE_TRANSFER_MESSAGE_STATUS['INCOMING_STARTED']) def send_screenshot(self, data): """ @@ -847,6 +878,13 @@ class Profile(Contact, Singleton): if type(transfer) is ReceiveAvatar: self.get_friend_by_number(friend_number).load_avatar() self.set_active(None) + elif type(transfer) is ReceiveToBuffer: + inline = InlineImage(0, '', transfer.get_data()) + self.get_friend_by_number(friend_number).update_transfer_data(file_number, + FILE_TRANSFER_MESSAGE_STATUS['FINISHED'], + inline + ) + self.set_active(None) else: self.get_friend_by_number(friend_number).update_transfer_data(file_number, FILE_TRANSFER_MESSAGE_STATUS['FINISHED']) del self._file_transfers[(friend_number, file_number)]