def _mimeDataAlgorithm(items): item = items[0] mimeData = None if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.id()) return mimeData
def mimeData(self, indexes): mimeData = QMimeData() encodedData = QByteArray() stream = QDataStream(encodedData, QIODevice.WriteOnly) for index in indexes: if not index.isValid(): continue if not isinstance(index.internalPointer(), TableItem): continue table = self.getItem(index) stream.writeQString(table.mimeUri()) mimeData.setData(self.QGIS_URI_MIME, encodedData) return mimeData
def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) self.assertIn(sip.cast(pasted[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(pasted[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual(sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) # multiframes multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1a') multiframe1.addFrame(frame1) frame1b = QgsLayoutFrame(l, multiframe1) frame1b.setId('frame1b') multiframe1.addFrame(frame1b) # not selected frame1c = QgsLayoutFrame(l, multiframe1) frame1c.setId('frame1b') multiframe1.addFrame(frame1c) # not selected multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') multiframe2.addFrame(frame2) frame1.setSelected(True) frame2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 4) new_multiframes = [m for m in l.multiFrames() if m not in [multiframe1, multiframe2]] self.assertEqual(len(new_multiframes), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) labels = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutLabel] self.assertIn(sip.cast(labels[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(labels[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) frames = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutFrame] pasted_frame1 = sip.cast(frames[0], QgsLayoutFrame) pasted_frame2 = sip.cast(frames[1], QgsLayoutFrame) self.assertIn(pasted_frame1.multiFrame(), new_multiframes) self.assertIn(new_multiframes[0].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertIn(pasted_frame2.multiFrame(), new_multiframes) self.assertIn(new_multiframes[1].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertEqual(frame1.multiFrame(), multiframe1) self.assertCountEqual(multiframe1.frames(), [frame1, frame1b, frame1c]) self.assertEqual(frame1b.multiFrame(), multiframe1) self.assertEqual(frame1c.multiFrame(), multiframe1) self.assertEqual(frame2.multiFrame(), multiframe2) self.assertCountEqual(multiframe2.frames(), [frame2]) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual(sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
def _mimeDataAlgorithm(items): item = items[0] if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.commandLineName()) return mimeData
def _mimeDataInput(items): mimeData = QMimeData() text = items[0].text(0) mimeData.setText(text) return mimeData
def _mimeDataInput(items): mimeData = QMimeData() text = items[0].data(0, Qt.UserRole) mimeData.setText(text) return mimeData
def _mimeDataAlgorithm(items): item = items[0] if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.id()) return mimeData
def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) # multiframes multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1a') multiframe1.addFrame(frame1) frame1b = QgsLayoutFrame(l, multiframe1) frame1b.setId('frame1b') multiframe1.addFrame(frame1b) # not selected frame1c = QgsLayoutFrame(l, multiframe1) frame1c.setId('frame1b') multiframe1.addFrame(frame1c) # not selected multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') multiframe2.addFrame(frame2) frame1.setSelected(True) frame2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 4) new_multiframes = [ m for m in l.multiFrames() if m not in [multiframe1, multiframe2] ] self.assertEqual(len(new_multiframes), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) labels = [ p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutLabel ] self.assertIn( sip.cast(labels[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn( sip.cast(labels[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) frames = [ p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutFrame ] pasted_frame1 = sip.cast(frames[0], QgsLayoutFrame) pasted_frame2 = sip.cast(frames[1], QgsLayoutFrame) self.assertIn(pasted_frame1.multiFrame(), new_multiframes) self.assertIn(new_multiframes[0].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertIn(pasted_frame2.multiFrame(), new_multiframes) self.assertIn(new_multiframes[1].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertEqual(frame1.multiFrame(), multiframe1) self.assertCountEqual(multiframe1.frames(), [frame1, frame1b, frame1c]) self.assertEqual(frame1b.multiFrame(), multiframe1) self.assertEqual(frame1c.multiFrame(), multiframe1) self.assertEqual(frame2.multiFrame(), multiframe2) self.assertCountEqual(multiframe2.frames(), [frame2]) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual( sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
def testColorFromMimeData(self): data = QMimeData() color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertFalse(color.isValid()) # color data data.setColorData(QColor(255, 0, 255)) color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') # should be true regardless of the actual color's opacity -- a QColor object has innate knowledge of the alpha, # so our input color HAS an alpha of 255 self.assertTrue(has_alpha) self.assertEqual(color.alpha(), 255) data.setColorData(QColor(255, 0, 255, 100)) color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertEqual(color.alpha(), 100) self.assertTrue(has_alpha) # text data data = QMimeData() data.setText('#ff00ff') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') # should be False -- no alpha was specified self.assertFalse(has_alpha) self.assertEqual(color.alpha(), 255) data.setText('#ff00ff66') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertTrue(has_alpha) self.assertEqual(color.alpha(), 102) # "#" is optional data.setText('ff00ff66') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertTrue(has_alpha) self.assertEqual(color.alpha(), 102) data.setText('255,0,255') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertFalse(has_alpha) self.assertEqual(color.alpha(), 255) data.setText('255,0,255,0.5') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertTrue(has_alpha) self.assertEqual(color.alpha(), 128) data.setText('rgba(255,0,255,0.5)') color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertTrue(color.isValid()) self.assertEqual(color.name(), '#ff00ff') self.assertTrue(has_alpha) self.assertEqual(color.alpha(), 128) # wrong data type data = QMimeData() data.setImageData(QImage()) color, has_alpha = QgsSymbolLayerUtils.colorFromMimeData(data) self.assertFalse(color.isValid())
def dropMimeData( self, mimeData: QMimeData, action: Qt.DropAction, row: int, column: int, index: QModelIndex) -> bool: """ Drop MIME data. """ # pylint: disable=W0613 if mimeData.hasFormat(mime_types['list']): mime_type = mime_types['list'] elif mimeData.hasFormat(mime_types['colrow']): mime_type = mime_types['colrow'] elif mimeData.hasFormat(mime_types['value']): mime_type = mime_types['value'] else: return False data = mimeData.data(mime_type) stream = QDataStream(data, QIODevice.ReadOnly) data_set = [] while not stream.atEnd(): stream_type = stream.readBytes().decode('utf-8') name = stream.readBytes().decode('utf-8') id = stream.readInt16() # pylint: disable=W0622 field = (stream_type, name, id) modelRCV = self.modelRC + self.modelValue if stream_type == 'calculation' and \ stream_type in [x[0] for x in modelRCV] and \ mime_type == mime_types['list']: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'Function can be droped in only one area.' ), 15000) return False elif (field in self.modelRC or field in self.tab) and \ mime_type in [mime_types['list'], mime_types['value']]: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'This field has already been droped.' ), 15000) return False elif stream_type == 'calculation' and \ id not in self.calculation.listText and \ 'text' in [x[0] for x in self.modelValue]: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'For the text value, function can only be one of ' '{}.'.format(self.calculation.textName) ), 15000) return False data_set.append(field) self.insertRows(row, len(data_set), index, data_set) return True
def dropMimeData( self, mimeData: QMimeData, action: Qt.DropAction, row: int, column: int, index: QModelIndex) -> bool: """ Drop MIME data. """ # pylint: disable=W0613 if mimeData.hasFormat(mime_types['list']): mime_type = mime_types['list'] elif mimeData.hasFormat(mime_types['colrow']): mime_type = mime_types['colrow'] elif mimeData.hasFormat(mime_types['value']): mime_type = mime_types['value'] else: return False data = mimeData.data(mime_type) stream = QDataStream(data, QIODevice.ReadOnly) data_set = [] while not stream.atEnd(): stream_type = stream.readBytes().decode('utf-8') name = stream.readBytes().decode('utf-8') id = stream.readInt16() # pylint: disable=W0622 field = (stream_type, name, id) dataRC = self.modelRows + self.modelColumns all_data = dataRC + self.tab if len(self.tab) >= 2: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'Value field may contain a maximum of two entries.' ), 15000) return False elif stream_type == 'calculation' and \ stream_type in [x[0] for x in all_data] and \ mime_type == mime_types['list']: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'Function can be droped in only one area.' ), 15000) return False elif len(self.tab) == 1 and stream_type != 'calculation' and \ self.tab[0][0] != 'calculation': self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'One of the items in the Value field must be a ' 'function.' ), 15000) return False elif len(self.tab) == 1 and \ ((stream_type == 'text' and self.tab[0][2] not in self.calculation.listText) or (id not in self.calculation.listText and self.tab[0][0] == 'text')): self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'For the text value, function can only be one of ' '{}.'.format(self.calculation.textName) ), 15000) return False elif stream_type == 'text' and \ [x for x in dataRC if x[0] == 'calculation' and x[2] not in self.calculation.listText]: self.main_window.statusBar() \ .showMessage(QCoreApplication.translate( 'GroupStats', 'For the text value function can only be one of ' '{}.'.format(self.calculation.textName) ), 15000) return False data_set.append(field) self.insertRows(row, len(data_set), index, data_set) return True