Пример #1
0
 def canInsertFromMimeData(self, source: QMimeData):
     if source.hasImage():
         return True
     elif source.hasUrls():
         return True
     elif source.hasHtml():
         return True
     else:
         return super().canInsertFromMimeData(source)
Пример #2
0
    def dropMimeData(self, mime: QMimeData, action, row: int, column: int,
                     parent: QModelIndex):
        LOG.debug('dropMimeData at row {}'.format(row))
        if action == Qt.IgnoreAction:
            return True

        if mime.hasFormat('text/uri-list'):
            if mime.hasUrls():
                LOG.debug('found urls in drop!')
                paths = [
                    qurl.path() for qurl in mime.urls() if qurl.isLocalFile()
                ]
                self.doc.import_files(paths)  # FIXME: replace with a signal
                return True
        elif mime.hasFormat(self._mimetype):
            # unpickle the presentation information and re-insert it
            # b = base64.decodebytes(mime.text())
            b = mime.data(self._mimetype)
            layer_set_len, insertion_info = pkl.loads(b)
            LOG.debug('dropped: {0!r:s}'.format(insertion_info))
            count = len(insertion_info)
            if row == -1:
                row = len(self.doc)  # append
                # FIXME: row=col=-1 implies drop-on-parent
                #  which may mean replace or may mean append for composite layers
            # self.insertRows(row, count)
            # for i, presentation in enumerate(l):
            #     self.setData(self.index(row+i, 0), presentation)
            order = list(range(layer_set_len))
            inserted_row_numbers = []
            # inserted_presentations = []
            # delete_these_rows = []
            insertion_point = row
            uuids = []
            for old_row, presentation in reversed(sorted(insertion_info)):
                del order[old_row]
                if old_row < insertion_point:
                    insertion_point -= 1
                inserted_row_numbers.insert(0, old_row)
                uuids.append(presentation.uuid)
                # delete_these_rows.append(old_row if old_row<row else old_row+count)
                # inserted_presentations.append(presentation)
            order = order[:insertion_point] + inserted_row_numbers + order[
                insertion_point:]
            LOG.debug('new order after drop {0!r:s}'.format(order))
            self.select([])
            self.doc.reorder_by_indices(order)
            # self.doc.insert_layer_prez(row, inserted_presentations)
            # LOG.debug('after insertion removing rows {0!r:s}'.format(delete_these_rows))
            # for exrow in delete_these_rows:
            #     self.doc.remove_layer_prez(exrow)
            # self.doc.didReorderLayers.emit(order)  # FUTURE: not our business to be emitting on behalf of the document
            assert (count == len(insertion_info))
            return True
        return False
Пример #3
0
    def insertFromMimeData(self,
                           source: QMimeData,
                           disable_richtext: bool = False):
        '''
        ..todo: Add support for embedded content when inserting html mime from clipboard
        '''
        if source.hasImage():
            temporary_file = os.path.join(
                Environment.get_base_path(),
                Configuration().get_setting(
                    'oxnote',
                    'application.directories.temporary',
                    default='.oxnote/tmp'), '{}.png'.format(
                        (str(uuid.uuid4()))))

            source.imageData().save(temporary_file)

            with open(temporary_file, 'rb') as f:
                encoded = base64.b64encode(f.read())

            self.textCursor().insertImage('data:image/png;base64,{}'.format(
                encoded.decode("utf-8")))

            if os.path.isfile(temporary_file):
                os.remove(temporary_file)
        elif source.hasUrls():
            for url in source.urls():
                if pathlib.Path(url.fileName()).suffix.lower(
                )[1:] not in self.supported_image_formats:
                    super().insertFromMimeData(source)
                    continue

                file_extension = pathlib.Path(
                    url.fileName()).suffix.lower()[1:]

                if url.isLocalFile():
                    if not os.path.isfile(url.toLocalFile()):
                        continue

                    with open(url.toLocalFile(), 'rb') as f:
                        self.textCursor().insertImage(
                            'data:image/png;base64,{}'.format(
                                base64.b64encode(f.read()).decode("utf-8")))
                else:
                    response = requests.get(url.toString(), stream=True)
                    if response.status_code == 200:
                        self.textCursor().insertImage(
                            'data:image/{};base64,{}'.format(
                                file_extension,
                                base64.b64encode(
                                    response.content).decode("utf-8")))
        elif source.hasHtml() and disable_richtext:
            self.textCursor().insertText(source.text())
        else:
            super().insertFromMimeData(source)
Пример #4
0
    def show_menu(self, clickPos):
        index = self.tree.indexAt(clickPos)
        selected_path = self.tree.model().filePath(index)
        enclosing_dir = self.find_enclosing_dir(selected_path)

        menu = QMenu(self)
        openAction = menu.addAction("Open")
        newFolderAction = menu.addAction("New Folder")
        newFileAction = menu.addAction("New File")
        copyAction = menu.addAction("Copy")
        pasteAction = menu.addAction("Paste")
        renameAction = menu.addAction("Rename")
        fileInfo = menu.addAction("Properties")

        menuPos = QPoint(clickPos.x() + 15, clickPos.y() + 15)
        action = menu.exec_(self.mapToGlobal(menuPos))

        if action == openAction:
            self.open_file(index)

        elif action == newFolderAction:
            path = self.get_dialog_str("New Folder",
                                       "Enter name for new folder:")
            if path:
                self.mkdir(os.path.join(enclosing_dir, path))

        elif action == newFileAction:
            path = self.get_dialog_str("New File", "Enter name for new file:")
            if path:
                self.touch(os.path.join(enclosing_dir, path))

        elif action == renameAction:
            path = self.get_dialog_str("Rename File", "Enter new name:")

            # Naive validation
            if "/" in path:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Critical)
                msg.setText("Filename cannot contain '/'")
                msg.setWindowTitle("Error")
                msg.exec_()
                return

            new_path = os.path.join(enclosing_dir, path)

            self.move(selected_path, new_path)

        elif action == copyAction:
            mime_data = QMimeData()

            # TODO: support multiple selections
            mime_data.setUrls([QUrl(Path(selected_path).as_uri())])
            self.clipboard.setMimeData(mime_data)

        elif action == pasteAction:
            mime_data = self.clipboard.mimeData()
            if not mime_data:
                return

            if mime_data.hasUrls():
                for src_url in mime_data.urls():
                    self.copy(src_url.path(), enclosing_dir)