def dropMimeData( # noqa: N802 self, mime: QMimeData, action: Qt.DropAction, row: int, column: int, parent: QModelIndex = QModelIndex) -> bool: """ This function unpacks QMimeData and insert them to the view where they are dropped. Inserting is a bit complicated since sometimes we need to create a parent when it is not in the view yet: - when child (marker gene) is dropped we insert it under the current parent (group) if it exist othervise we crate a new parent. - when group item is inserted it merge it with current same parent item if exist or insert it if it does not exists """ if action == Qt.IgnoreAction: return True if not mime.hasFormat(self.MIME_TYPE): return False items = mime.property("_items") if items is None: return False # when parent item in items remove its child since all group will be moved items = [it for it in items if it.parentItem not in items] self.insert_items(items) self.data_added.emit() return True
def test_activate_drop_node(self): class NodeFromMimeData(TestNodeFromMimeData): def shouldActivateNode(self) -> bool: self.shouldActivateNode_called += 1 return True shouldActivateNode_called = 0 def activateNode(self, document: 'SchemeEditWidget', node: 'Node', widget: 'QWidget') -> None: self.activateNode_called += 1 super().activateNode(document, node, widget) widget.didActivate = True activateNode_called = 0 w = self.w viewport = w.view().viewport() workflow = Scheme() wm = workflow.widget_manager = TestingWidgetManager() wm.set_creation_policy(TestingWidgetManager.Immediate) wm.set_workflow(workflow) w.setScheme(workflow) handler = NodeFromMimeData() w.setDropHandlers([handler]) mime = QMimeData() mime.setData(TestNodeFromMimeData.format_, b'abc') spy = QSignalSpy(wm.widget_for_node_added) dragDrop(viewport, mime, QPoint(10, 10)) self.assertEqual(len(spy), 1) self.assertGreaterEqual(handler.shouldActivateNode_called, 1) self.assertGreaterEqual(handler.activateNode_called, 1) _, widget = spy[0] self.assertTrue(widget.didActivate) workflow.clear()
def __onDragStarted(self, index): desc = index.data(QtWidgetRegistry.WIDGET_DESC_ROLE) icon = index.data(Qt.DecorationRole) drag_data = QMimeData() drag_data.setData( "application/vnv.orange-canvas.registry.qualified-name", desc.qualified_name.encode('utf-8') ) drag = QDrag(self) drag.setPixmap(icon.pixmap(38)) drag.setMimeData(drag_data) # TODO: Should animate (accept) hide. self.hide() # When a drag is started and the menu hidden the item's tool tip # can still show for a short time UNDER the cursor preventing a # drop. viewport = self.__menu.view().viewport() filter = ToolTipEventFilter() viewport.installEventFilter(filter) drag.exec_(Qt.CopyAction) viewport.removeEventFilter(filter)
def __onDragStarted(self, index): # type: (QModelIndex) -> None desc = index.data(QtWidgetRegistry.WIDGET_DESC_ROLE) icon = index.data(Qt.DecorationRole) drag_data = QMimeData() drag_data.setData( "application/vnv.orange-canvas.registry.qualified-name", desc.qualified_name.encode('utf-8') ) drag = QDrag(self) drag.setPixmap(icon.pixmap(38)) drag.setMimeData(drag_data) # TODO: Should animate (accept) hide. self.hide() # When a drag is started and the menu hidden the item's tool tip # can still show for a short time UNDER the cursor preventing a # drop. viewport = self.__menu.view().viewport() filter = ToolTipEventFilter() viewport.installEventFilter(filter) drag.exec_(Qt.CopyAction) viewport.removeEventFilter(filter)
def mimeData(self, indexlist): if len(indexlist) != 1: return None mime = QMimeData() mime.setData(self.MIME_TYPE, b'see properties: item_index') mime.setProperty('item_index', indexlist[0]) return mime
def mimeData(indexlist): assert len(indexlist) == 1 index = indexlist[0] qname = index.data(DescriptionRole).qualname m = QMimeData() m.setData("application/x-qwidget-ref", qname.encode("utf-8")) return m
def test_drop_sample(self): path = os.path.join(self._path, "lib.cell.count") data = QMimeData() data.setUrls([QUrl.fromLocalFile(path)]) event = QDropEvent(QPoint(10, 10), Qt.MoveAction, data, Qt.NoButton, Qt.NoModifier, QDropEvent.Drop) self.widget.view.dropEvent(event) self.assertEqual(self.widget.view.model().rowCount(), 3)
def insertFromMimeData(mime: QMimeData): fragment: Optional[QTextDocumentFragment] = None if mime.hasHtml() and acceptRichText: fragment = QTextDocumentFragment.fromHtml(mime.html()) elif mime.hasText(): fragment = QTextDocumentFragment.fromPlainText(mime.text()) if fragment is not None: item.textCursor().insertFragment(fragment)
def test_script_insert_mime_text(self): current = self.widget.text.toPlainText() insert = "test\n" cursor = self.widget.text.cursor() cursor.setPos(0, 0) mime = QMimeData() mime.setText(insert) self.widget.text.insertFromMimeData(mime) self.assertEqual(insert + current, self.widget.text.toPlainText())
def test_files_drop(self): w = self.w workflow = w.scheme() mime = QMimeData() mime.setUrls([QUrl("file:///foo/bar")] * 2) dragDrop(w.view().viewport(), mime, QPoint(10, 10)) self.assertEqual(len(workflow.nodes), 1) self.assertEqual(workflow.nodes[0].properties, {"param": ["/foo/bar"] * 2})
def test_script_insert_mime_file(self): with named_file("test", suffix=".42") as fn: previous = self.widget.text.toPlainText() mime = QMimeData() url = QUrl.fromLocalFile(fn) mime.setUrls([url]) self.widget.text.insertFromMimeData(mime) self.assertEqual("test", self.widget.text.toPlainText()) self.widget.text.undo() self.assertEqual(previous, self.widget.text.toPlainText())
def mimeData(self, indexlist): descriptors = [] vars = [] for index in indexlist: var = self[index.row()] descriptors.append((var.name, vartype(var))) vars.append(var) mime = QMimeData() mime.setData(self.MIME_TYPE, QByteArray(str(descriptors).encode("utf-8"))) mime._vars = vars return mime
def test_script_insert_mime_file(self): with named_file("test", suffix=".42") as fn: previous = self.widget.text.toPlainText() mime = QMimeData() url = QUrl.fromLocalFile(fn) mime.setUrls([url]) self.widget.text.insertFromMimeData(mime) text = self.widget.text.toPlainText().split( "print('Hello world')")[0] self.assertTrue("'" + fn + "'", text) self.widget.text.undo() self.assertEqual(previous, self.widget.text.toPlainText())
def mimeData(self, indexlist): """ Reimplemented. For efficiency reasons only the variable instances are set on the mime data (under `'_items'` property) """ items = [self[index.row()] for index in indexlist] mime = QMimeData() # the encoded 'data' is empty, variables are passed by properties mime.setData(self.MIME_TYPE, b'') mime.setProperty("_items", items) return mime
def test_drag_drop(self): w = self.w w.setRegistry(self.reg) handler = TestDropHandler() w.setDropHandlers([handler]) viewport = w.view().viewport() mime = QMimeData() mime.setData(handler.format_, b'abc') dragDrop(viewport, mime, QPoint(10, 10)) self.assertEqual(handler.doDrop_calls, 1) self.assertGreaterEqual(handler.accepts_calls, 1) self.assertIsNone(w._userInteractionHandler()) handler.accepts_calls = 0 handler.doDrop_calls = 0 mime = QMimeData() mime.setData("application/prs.do-not-accept-this", b'abc') dragDrop(viewport, mime, QPoint(10, 10)) self.assertGreaterEqual(handler.accepts_calls, 1) self.assertEqual(handler.doDrop_calls, 0) self.assertIsNone(w._userInteractionHandler()) dragEnterLeave(viewport, mime, QPoint(10, 10)) self.assertIsNone(w._userInteractionHandler())
def __startDrag(self, button): """ Start a drag from button """ action = button.defaultAction() desc = action.data() # Widget Description icon = action.icon() drag_data = QMimeData() drag_data.setData( "application/vnv.orange-canvas.registry.qualified-name", desc.qualified_name.encode("utf-8")) drag = QDrag(button) drag.setPixmap(icon.pixmap(self.iconSize())) drag.setMimeData(drag_data) drag.exec_(Qt.CopyAction)
def __startDrag(self, button): """ Start a drag from button """ action = button.defaultAction() desc = action.data() # Widget Description icon = action.icon() drag_data = QMimeData() drag_data.setData( "application/vnv.orange-canvas.registry.qualified-name", desc.qualified_name.encode("utf-8") ) drag = QDrag(button) drag.setPixmap(icon.pixmap(self.iconSize())) drag.setMimeData(drag_data) drag.exec_(Qt.CopyAction)
def _drop_event(self, url): # make sure data does not get garbage collected before it used self.event_data = data = QMimeData() data.setUrls([QUrl(url)]) return QDropEvent(QPoint(0, 0), Qt.MoveAction, data, Qt.NoButton, Qt.NoModifier, QDropEvent.Drop)
def _drag_enter_event(self, url): # make sure data does not get garbage collected before it used # pylint: disable=attribute-defined-outside-init self.event_data = data = QMimeData() data.setUrls([QUrl(url)]) return QDragEnterEvent(QPoint(0, 0), Qt.MoveAction, data, Qt.NoButton, Qt.NoModifier)
def mimeData(self, index_list: List[QModelIndex]) -> QMimeData: # noqa: N802 """ This function packs data in QMimeData in order to move them to other view with drag and drop functionality. """ items = [self.node_from_index(index) for index in index_list] mime = QMimeData() # the encoded 'data' is empty, variables are passed by properties mime.setData(self.MIME_TYPE, b'') mime.setProperty("_items", items) mime.setProperty("_source_id", id(self)) return mime
def __startInternalDrag(self, frame, hotSpot=None): drag = QDrag(self) pixmap = QPixmap(frame.size()) frame.render(pixmap) transparent = QPixmap(pixmap.size()) transparent.fill(Qt.transparent) painter = QPainter(transparent) painter.setOpacity(0.35) painter.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap) painter.end() drag.setPixmap(transparent) if hotSpot is not None: drag.setHotSpot(hotSpot) mime = QMimeData() mime.setData("application/x-internal-move", b"") drag.setMimeData(mime) return drag.exec(Qt.MoveAction)
def __startInternalDrag(self, frame, hotSpot=None): drag = QDrag(self) pixmap = QPixmap(frame.size()) frame.render(pixmap) transparent = QPixmap(pixmap.size()) transparent.fill(Qt.transparent) painter = QPainter(transparent) painter.setOpacity(0.35) painter.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap) painter.end() drag.setPixmap(transparent) if hotSpot is not None: drag.setHotSpot(hotSpot) mime = QMimeData() mime.setData("application/x-internal-move", b"") drag.setMimeData(mime) return drag.exec_(Qt.MoveAction)
def test_drop_event(self): w = self.w w.setRegistry(self.reg) workflow = w.scheme() desc = self.reg.widget("one") viewport = w.view().viewport() mime = QMimeData() mime.setData( "application/vnd.orange-canvas.registry.qualified-name", desc.qualified_name.encode("utf-8") ) self.assertTrue(dragDrop(viewport, mime, QPoint(10, 10))) self.assertEqual(len(workflow.nodes), 1) self.assertEqual(workflow.nodes[0].description, desc) dragEnterLeave(viewport, mime) self.assertEqual(len(workflow.nodes), 1)
def table_selection_to_mime_data(table): """Copy the current selection in a QTableView to the clipboard. """ lines = table_selection_to_list(table) as_csv = lines_to_csv_string(lines, dialect="excel").encode("utf-8") as_tsv = lines_to_csv_string(lines, dialect="excel-tab").encode("utf-8") mime = QMimeData() mime.setData("text/csv", QByteArray(as_csv)) mime.setData("text/tab-separated-values", QByteArray(as_tsv)) mime.setData("text/plain", QByteArray(as_tsv)) return mime
def canDropMimeData( # noqa: N802 self, data: QMimeData, action: Qt.DropAction, row: int, column: int, parent: QModelIndex ) -> bool: """ This function enable or disable drop action to the view. With current implementation we disable drop action to the same view. """ if data.property("_source_id") == id(self): return False else: return True
def test_drop(self): widget = self.widget with tempfile.TemporaryDirectory() as tmpdir: urlpath = QUrl.fromLocalFile(tmpdir) data = QMimeData() data.setUrls([urlpath]) pos = widget.recent_cb.rect().center() actions = Qt.LinkAction | Qt.CopyAction ev = QDragEnterEvent(pos, actions, data, Qt.LeftButton, Qt.NoModifier) assert QApplication.sendEvent(widget.recent_cb, ev) self.assertTrue(ev.isAccepted()) del ev ev = QDropEvent(pos, actions, data, Qt.LeftButton, Qt.NoModifier, QDropEvent.Drop) assert QApplication.sendEvent(widget.recent_cb, ev) self.assertTrue(ev.isAccepted()) del ev self.assertEqual(widget.currentPath, urlpath.toLocalFile()) self._startandwait(widget) self.widget.commit()
def createMimeDataFromSelection( fragment: QTextDocumentFragment) -> QMimeData: mime = QMimeData() mime.setText(fragment.toPlainText()) mime.setHtml(fragment.toHtml(b"utf-8")) # missing here is odf return mime
def test_drop(self): widget = self.widget with tempfile.TemporaryDirectory() as tmpdir: urlpath = QUrl.fromLocalFile(tmpdir) data = QMimeData() data.setUrls([urlpath]) pos = widget.recent_cb.rect().center() actions = Qt.LinkAction | Qt.CopyAction ev = QDragEnterEvent(pos, actions, data, Qt.LeftButton, Qt.NoModifier) assert QApplication.sendEvent(widget.recent_cb, ev) self.assertTrue(ev.isAccepted()) del ev ev = QDropEvent(pos, actions, data, Qt.LeftButton, Qt.NoModifier, QDropEvent.Drop) assert QApplication.sendEvent(widget.recent_cb, ev) self.assertTrue(ev.isAccepted()) del ev self.assertEqual(widget.recent_paths[0].abspath, urlpath.toLocalFile()) self._startandwait(widget) self.widget.commit()
def copy(self): """Copy to the clipboard""" data = QMimeData() text = '\n'.join([cursor.selectedText() \ for cursor in self.cursors()]) data.setText(text) data.setData(self.MIME_TYPE, text.encode('utf8')) QApplication.clipboard().setMimeData(data)
def table_selection_to_mime_data(table): """Copy the current selection in a QTableView to the clipboard. """ lines = table_selection_to_list(table) csv = lines_to_csv_string(lines, dialect="excel") tsv = lines_to_csv_string(lines, dialect="excel-tab") mime = QMimeData() mime.setData("text/csv", QByteArray(csv)) mime.setData("text/tab-separated-values", QByteArray(tsv)) mime.setData("text/plain", QByteArray(tsv)) return mime
def mimeData(self, indexlist): if len(indexlist) <= 0: return None def itemData(row): # type: (int) -> Dict[int, Any] if row < len(self._other_data): return {key: val for key, val in self._other_data[row].items() if isinstance(key, int)} else: return {} # pragma: no cover items = [self[i.row()] for i in indexlist] itemdata = [itemData(i.row()) for i in indexlist] mime = QMimeData() mime.setData(self.MIME_TYPE, b'see properties: _items, _itemdata') mime.setProperty('_items', items) mime.setProperty('_itemdata', itemdata) return mime
def _export(exporter, _): buffer = exporter.export(toBytes=True) mimedata = QMimeData() mimedata.setData("image/png", buffer) QApplication.clipboard().setMimeData(mimedata)
def _drag_enter_event(self, variables): # pylint: disable=attribute-defined-outside-init self.event_data = mime = QMimeData() mime.setProperty("_items", variables) return QDragEnterEvent(QPoint(0, 0), Qt.MoveAction, mime, Qt.NoButton, Qt.NoModifier)
def _drag_enter_event(self, variables): self.event_data = mime = QMimeData() mime.setProperty("_items", variables) return QDragEnterEvent(QPoint(0, 0), Qt.MoveAction, mime, Qt.NoButton, Qt.NoModifier)
def test_plugin_drag_drop(self): handler = PluginDropHandler() w = self.w w.setRegistry(self.reg) w.setDropHandlers([handler]) workflow = w.scheme() viewport = w.view().viewport() # Test empty handler mime = QMimeData() mime.setData(TestDropHandler.format_, b'abc') dragDrop(viewport, mime, QPoint(10, 10)) self.assertIsNone(w._userInteractionHandler()) # test create node handler mime = QMimeData() mime.setData(TestNodeFromMimeData.format_, b'abc') dragDrop(viewport, mime, QPoint(10, 10)) self.assertIsNone(w._userInteractionHandler()) self.assertEqual(len(workflow.nodes), 1) self.assertEqual(workflow.nodes[0].description.name, "one") self.assertEqual(workflow.nodes[0].properties, {"a": "from drop"}) workflow.clear() # Test both simultaneously (menu for selection) mime = QMimeData() mime.setData(TestDropHandler.format_, b'abc') mime.setData(TestNodeFromMimeData.format_, b'abc') def exec(self, *args): return action_by_name(self.actions(), "-pick-me") # intercept QMenu.exec, force select the TestNodeFromMimeData handler with mock.patch.object(QMenu, "exec", exec): dragDrop(viewport, mime, QPoint(10, 10)) self.assertEqual(len(workflow.nodes), 1) self.assertEqual(workflow.nodes[0].description.name, "one") self.assertEqual(workflow.nodes[0].properties, {"a": "from drop"})