def testTable(self): """Test we can render a html table in a single frame.""" layout_html = QgsLayoutItemHtml(self.layout) html_frame = QgsLayoutFrame(self.layout, layout_html) html_frame.attemptSetSceneRect(QRectF(0, 0, 100, 200)) html_frame.setFrameEnabled(True) layout_html.addFrame(html_frame) layout_html.setUrl(self.htmlUrl()) checker = QgsLayoutChecker('composerhtml_table', self.layout) checker.setControlPathPrefix("composer_html") myTestResult, myMessage = checker.testLayout() qDebug(myMessage) self.layout.removeMultiFrame(layout_html) assert myTestResult, myMessage
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 testTableMultiFrame(self): """Test we can render to multiframes.""" layout_html = QgsLayoutItemHtml(self.layout) html_frame = QgsLayoutFrame(self.layout, layout_html) html_frame.attemptSetSceneRect(QRectF(10, 10, 100, 50)) layout_html.addFrame(html_frame) layout_html.setResizeMode( QgsLayoutMultiFrame.RepeatUntilFinished) layout_html.setUseSmartBreaks(False) layout_html.setUrl(self.htmlUrl()) layout_html.frame(0).setFrameEnabled(True) print("Checking page 1") myPage = 0 checker1 = QgsLayoutChecker('composerhtml_multiframe1', self.layout) checker1.setControlPathPrefix("composer_html") myTestResult, myMessage = checker1.testLayout(myPage) assert myTestResult, myMessage print("Checking page 2") myPage = 1 checker2 = QgsLayoutChecker('composerhtml_multiframe2', self.layout) checker2.setControlPathPrefix("composer_html") myTestResult, myMessage = checker2.testLayout(myPage) assert myTestResult, myMessage self.layout.removeMultiFrame(layout_html) layout_html = None assert myTestResult, myMessage
def testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) # multiframe multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1') frame1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) frame1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) multiframe1.addFrame(frame1) multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') frame2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) frame2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) multiframe2.addFrame(frame2) uuids = {item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid(), multiframe1.uuid(), multiframe2.uuid()} original_uuids = {item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid()} self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 4) items = l2.items() multiframes = l2.multiFrames() self.assertEqual(len(multiframes), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes if i.html() == 'mf1']) self.assertTrue([i for i in multiframes if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes[0].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) self.assertNotIn(multiframes[1].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) new_multiframe1 = [i for i in multiframes if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1.layout(), l2) new_multiframe2 = [i for i in multiframes if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2.layout(), l2) new_frame1 = sip.cast([i for i in items if i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 4) items = l2.items() self.assertEqual(len(items), 8) multiframes2 = l2.multiFrames() self.assertEqual(len(multiframes2), 4) multiframes2 = [m for m in l2.multiFrames() if not m.uuid() in [new_multiframe1.uuid(), new_multiframe2.uuid()]] self.assertEqual(len(multiframes2), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf1']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertTrue(new_items2[2] in l2.items()) self.assertTrue(new_items2[3] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items2[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items2[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes2[0].uuid(), [multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid()]) self.assertNotIn(multiframes2[1].uuid(), [multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid()]) new_multiframe1b = [i for i in multiframes2 if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1b.layout(), l2) new_multiframe2b = [i for i in multiframes2 if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2b.layout(), l2) new_frame1b = sip.cast([i for i in items if i.id() == 'frame1' and i.uuid() != new_frame1.uuid()][0], QgsLayoutFrame) new_frame2b = sip.cast([i for i in items if i.id() == 'frame2' and i.uuid() != new_frame2.uuid()][0], QgsLayoutFrame) self.assertEqual(new_frame1b.multiFrame(), new_multiframe1b) self.assertEqual(new_multiframe1b.frames()[0].uuid(), new_frame1b.uuid()) self.assertEqual(new_frame2b.multiFrame(), new_multiframe2b) self.assertEqual(new_multiframe2b.frames()[0].uuid(), new_frame2b.uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) new_multiframes = l2.multiFrames() self.assertTrue(ok) self.assertEqual(len(new_items3), 5) # includes page self.assertEqual(len(new_multiframes), 2) items = l2.items() self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2']) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertTrue(new_items3[2] in l2.items()) self.assertTrue(new_items3[3] in l2.items()) new_multiframe1 = [i for i in new_multiframes if i.html() == 'mf1'][0] new_multiframe2 = [i for i in new_multiframes if i.html() == 'mf2'][0] new_frame1 = sip.cast([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())
def testTableMultiFrame(self): """Test we can render to multiframes.""" layout_html = QgsLayoutItemHtml(self.layout) html_frame = QgsLayoutFrame(self.layout, layout_html) html_frame.attemptSetSceneRect(QRectF(10, 10, 100, 50)) layout_html.addFrame(html_frame) layout_html.setResizeMode(QgsLayoutMultiFrame.RepeatUntilFinished) layout_html.setUseSmartBreaks(False) layout_html.setUrl(self.htmlUrl()) layout_html.frame(0).setFrameEnabled(True) print("Checking page 1") myPage = 0 checker1 = QgsLayoutChecker('composerhtml_multiframe1', self.layout) checker1.setControlPathPrefix("composer_html") myTestResult, myMessage = checker1.testLayout(myPage) assert myTestResult, myMessage print("Checking page 2") myPage = 1 checker2 = QgsLayoutChecker('composerhtml_multiframe2', self.layout) checker2.setControlPathPrefix("composer_html") myTestResult, myMessage = checker2.testLayout(myPage) assert myTestResult, myMessage self.layout.removeMultiFrame(layout_html) layout_html = None assert myTestResult, myMessage
def createItem(cls, layout): cls.mf = QgsLayoutItemHtml(layout) return QgsLayoutFrame(layout, cls.mf)
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 testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) # multiframe multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1') frame1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) frame1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) multiframe1.addFrame(frame1) multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') frame2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) frame2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) multiframe2.addFrame(frame2) uuids = { item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid(), multiframe1.uuid(), multiframe2.uuid() } original_uuids = { item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid() } self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 4) items = l2.items() multiframes = l2.multiFrames() self.assertEqual(len(multiframes), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes if i.html() == 'mf1']) self.assertTrue([i for i in multiframes if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn( multiframes[0].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) self.assertNotIn( multiframes[1].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) new_multiframe1 = [i for i in multiframes if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1.layout(), l2) new_multiframe2 = [i for i in multiframes if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2.layout(), l2) new_frame1 = sip.cast([i for i in items if i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 4) items = l2.items() self.assertEqual(len(items), 8) multiframes2 = l2.multiFrames() self.assertEqual(len(multiframes2), 4) multiframes2 = [ m for m in l2.multiFrames() if not m.uuid() in [new_multiframe1.uuid(), new_multiframe2.uuid()] ] self.assertEqual(len(multiframes2), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf1']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertTrue(new_items2[2] in l2.items()) self.assertTrue(new_items2[3] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items2[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items2[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes2[0].uuid(), [ multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid() ]) self.assertNotIn(multiframes2[1].uuid(), [ multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid() ]) new_multiframe1b = [i for i in multiframes2 if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1b.layout(), l2) new_multiframe2b = [i for i in multiframes2 if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2b.layout(), l2) new_frame1b = sip.cast([ i for i in items if i.id() == 'frame1' and i.uuid() != new_frame1.uuid() ][0], QgsLayoutFrame) new_frame2b = sip.cast([ i for i in items if i.id() == 'frame2' and i.uuid() != new_frame2.uuid() ][0], QgsLayoutFrame) self.assertEqual(new_frame1b.multiFrame(), new_multiframe1b) self.assertEqual(new_multiframe1b.frames()[0].uuid(), new_frame1b.uuid()) self.assertEqual(new_frame2b.multiFrame(), new_multiframe2b) self.assertEqual(new_multiframe2b.frames()[0].uuid(), new_frame2b.uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) new_multiframes = l2.multiFrames() self.assertTrue(ok) self.assertEqual(len(new_items3), 5) # includes page self.assertEqual(len(new_multiframes), 2) items = l2.items() self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2' ]) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertTrue(new_items3[2] in l2.items()) self.assertTrue(new_items3[3] in l2.items()) new_multiframe1 = [i for i in new_multiframes if i.html() == 'mf1'][0] new_multiframe2 = [i for i in new_multiframes if i.html() == 'mf2'][0] new_frame1 = sip.cast([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1' ][0], QgsLayoutFrame) new_frame2 = sip.cast([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2' ][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())
def qgis_composer_html_renderer(impact_report, component): """HTML to PDF renderer using QGIS Composer. Render using qgis composer for a given impact_report data and component context for html input. :param impact_report: ImpactReport contains data about the report that is going to be generated. :type impact_report: safe.report.impact_report.ImpactReport :param component: Contains the component metadata and context for rendering the output. :type component: safe.report.report_metadata.QgisComposerComponentsMetadata :return: Whatever type of output the component should be. .. versionadded:: 4.0 """ context = component.context # QGIS3: not used # qgis_composition_context = impact_report.qgis_composition_context # create new layout with A4 portrait page layout = QgsPrintLayout(QgsProject.instance()) page = QgsLayoutItemPage(layout) page.setPageSize('A4', orientation=QgsLayoutItemPage.Portrait) layout.pageCollection().addPage(page) if not context.html_frame_elements: # if no html frame elements at all, do not generate empty report. component.output = '' return component.output # Add HTML Frame for html_el in context.html_frame_elements: mode = html_el.get('mode') html_element = QgsLayoutItemHtml(layout) margin_left = html_el.get('margin_left', 10) margin_top = html_el.get('margin_top', 10) width = html_el.get('width', component.page_width - 2 * margin_left) height = html_el.get('height', component.page_height - 2 * margin_top) html_frame = QgsLayoutFrame(layout, html_element) html_frame.attemptSetSceneRect( QRectF(margin_left, margin_top, width, height)) html_element.addFrame(html_frame) if html_element: if mode == 'text': text = html_el.get('text') text = text if text else '' html_element.setContentMode(QgsLayoutItemHtml.ManualHtml) html_element.setResizeMode( QgsLayoutItemHtml.RepeatUntilFinished) html_element.setHtml(text) html_element.loadHtml() elif mode == 'url': url = html_el.get('url') html_element.setContentMode(QgsLayoutItemHtml.Url) html_element.setResizeMode( QgsLayoutItemHtml.RepeatUntilFinished) qurl = QUrl.fromLocalFile(url) html_element.setUrl(qurl) # Attempt on removing blank page. Notes: We assume that the blank page # will always appears in the last x page(s), not in the middle. pc = layout.pageCollection() index = pc.pageCount() while pc.pageIsEmpty(index): pc.deletePage(index) index -= 1 # process to output # in case output folder not specified if impact_report.output_folder is None: impact_report.output_folder = mkdtemp(dir=temp_dir()) component_output_path = impact_report.component_absolute_output_path( component.key) component_output = None output_format = component.output_format doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT template_format = QgisComposerComponentsMetadata.OutputFormat.QPT if isinstance(output_format, list): component_output = [] for i in range(len(output_format)): each_format = output_format[i] each_path = component_output_path[i] if each_format in doc_format: result_path = create_qgis_pdf_output( impact_report, each_path, layout, each_format, component) component_output.append(result_path) elif each_format == template_format: result_path = create_qgis_template_output( each_path, layout) component_output.append(result_path) elif isinstance(output_format, dict): component_output = {} for key, each_format in list(output_format.items()): each_path = component_output_path[key] if each_format in doc_format: result_path = create_qgis_pdf_output( impact_report, each_path, layout, each_format, component) component_output[key] = result_path elif each_format == template_format: result_path = create_qgis_template_output( each_path, layout) component_output[key] = result_path elif (output_format in QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT): component_output = None if output_format in doc_format: result_path = create_qgis_pdf_output( impact_report, component_output_path, layout, output_format, component) component_output = result_path elif output_format == template_format: result_path = create_qgis_template_output( component_output_path, layout) component_output = result_path component.output = component_output return component.output