summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorTibor Nagy <tibor.nagy.extern@allotropia.de>2024-03-08 00:51:06 +0100
committerNagy Tibor <tibor.nagy.extern@allotropia.de>2024-03-11 15:59:22 +0100
commitf3bfe66fb54190fee6ac579835c03c2b4a2735d0 (patch)
treed65af9dc3e1f32717e2b34809e63033550998490 /sc
parentccf988d206a47701c81126f23e2bef71fc3db333 (diff)
tdf#159094 sc: fix failure when exporting media files to PDF
Change-Id: I948190b31f45cf05ba24d1fbc4a84dfe91eb3876 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164557 Tested-by: Jenkins Reviewed-by: Nagy Tibor <tibor.nagy.extern@allotropia.de>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/extras/scpdfexport.cxx14
-rw-r--r--sc/qa/extras/testdocuments/tdf159094.odsbin0 -> 10716 bytes
-rw-r--r--sc/source/ui/unoobj/docuno.cxx190
3 files changed, 196 insertions, 8 deletions
diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx
index 6cf93f71ed51..b26c61bdfddd 100644
--- a/sc/qa/extras/scpdfexport.cxx
+++ b/sc/qa/extras/scpdfexport.cxx
@@ -61,6 +61,7 @@ private:
// unit tests
public:
+ void testMediaShapeScreen_Tdf159094();
void testExportRange_Tdf120161();
void testExportFitToPage_Tdf103516();
void testUnoCommands_Tdf120161();
@@ -77,6 +78,7 @@ public:
void testForcepoint97();
CPPUNIT_TEST_SUITE(ScPDFExportTest);
+ CPPUNIT_TEST(testMediaShapeScreen_Tdf159094);
CPPUNIT_TEST(testExportRange_Tdf120161);
CPPUNIT_TEST(testExportFitToPage_Tdf103516);
CPPUNIT_TEST(testUnoCommands_Tdf120161);
@@ -213,6 +215,18 @@ void ScPDFExportTest::setFont(ScFieldEditEngine& rEE, sal_Int32 nStart, sal_Int3
rEE.QuickSetAttribs(aItemSet, aSel);
}
+void ScPDFExportTest::testMediaShapeScreen_Tdf159094()
+{
+ loadFromFile(u"tdf159094.ods");
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+
+ // A1:B8
+ ScRange aRange(0, 0, 0, 1, 7, 0);
+
+ // Without the fix, this test would crash on export media file to pdf
+ exportToPDF(xModel, aRange);
+}
+
// Selection was not taken into account during export into PDF
void ScPDFExportTest::testExportRange_Tdf120161()
{
diff --git a/sc/qa/extras/testdocuments/tdf159094.ods b/sc/qa/extras/testdocuments/tdf159094.ods
new file mode 100644
index 000000000000..c267b2152192
--- /dev/null
+++ b/sc/qa/extras/testdocuments/tdf159094.ods
Binary files differ
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index e80a3bbed259..eef74952df9a 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -29,6 +29,9 @@
#include <editeng/editview.hxx>
#include <editeng/memberids.h>
#include <editeng/outliner.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
#include <o3tl/any.hxx>
#include <o3tl/safeint.hxx>
#include <svx/fmview.hxx>
@@ -134,6 +137,7 @@
#include <appoptio.hxx>
#include <formulaopt.hxx>
#include <output.hxx>
+#include <stlpool.hxx>
#include <strings.hrc>
@@ -2147,7 +2151,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32
bWasCellRange = pPrintFunc->GetLastSourceRange( aCellRange );
Size aTwips = pPrintFunc->GetPageSize();
- if (!m_pPrintState)
+ if (!m_pPrintState || nRenderer == nTabStart)
{
m_pPrintState.reset(new ScPrintState());
pPrintFunc->GetPrintState(*m_pPrintState, true);
@@ -2343,6 +2347,172 @@ static void lcl_PDFExportBookmarkHelper(OutputDevice* pDev, ScDocument& rDoc,
rBookmarks.clear();
}
+static void lcl_SetMediaScreen(const uno::Reference<drawing::XShape>& xMediaShape,
+ const OutputDevice* pDev, tools::Rectangle& aRect,
+ sal_Int32 nPageNumb)
+{
+ OUString sMediaURL;
+ uno::Reference<beans::XPropertySet> xPropSet(xMediaShape, uno::UNO_QUERY);
+ xPropSet->getPropertyValue("MediaURL") >>= sMediaURL;
+ if (!sMediaURL.isEmpty())
+ {
+ OUString sTitle;
+ xPropSet->getPropertyValue("Title") >>= sTitle;
+ OUString sDescription;
+ xPropSet->getPropertyValue("Description") >>= sDescription;
+ OUString const altText(sTitle.isEmpty() ? sDescription
+ : sDescription.isEmpty()
+ ? sTitle
+ : OUString::Concat(sTitle) + OUString::Concat("\n")
+ + OUString::Concat(sDescription));
+
+ OUString const mimeType(xPropSet->getPropertyValue("MediaMimeType").get<OUString>());
+ SdrObject* pSdrObj(SdrObject::getSdrObjectFromXShape(xMediaShape));
+ vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
+ sal_Int32 nScreenId = pPDF->CreateScreen(aRect, altText, mimeType, nPageNumb, pSdrObj);
+ if (sMediaURL.startsWith("vnd.sun.star.Package:"))
+ {
+ // Embedded media
+ OUString aTempFileURL;
+ xPropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
+ pPDF->SetScreenStream(nScreenId, aTempFileURL);
+ }
+ else // Linked media
+ pPDF->SetScreenURL(nScreenId, sMediaURL);
+ }
+}
+
+static void lcl_PDFExportMediaShapeScreen(const OutputDevice* pDev, const ScPrintState& rState,
+ ScDocument& rDoc, SCTAB nTab, tools::Long nStartPage,
+ bool bSinglePageSheets)
+{
+ ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+ vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
+ if (pPDF && pPDF->GetIsExportTaggedPDF() && pDrawLayer)
+ {
+
+ if (!bSinglePageSheets)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ OSL_ENSURE(pPage, "Page ?");
+ if (pPage)
+ {
+ ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(rDoc.GetPageStyle(nTab), SfxStyleFamily::Page);
+ SfxItemSet* pItemSet = &pStyleSheet->GetItemSet();
+
+ tools::Long nLeftMargin(pItemSet->Get(ATTR_LRSPACE).GetLeft());
+ nLeftMargin = o3tl::convert(nLeftMargin, o3tl::Length::twip, o3tl::Length::mm100);
+
+ tools::Long nTopMargin(pItemSet->Get(ATTR_ULSPACE).GetUpper());
+ nTopMargin = o3tl::convert(nTopMargin, o3tl::Length::twip, o3tl::Length::mm100);
+
+ tools::Long nHeader = 0;
+ const SvxSetItem* pHeaderSetItem = &pItemSet->Get(ATTR_PAGE_HEADERSET);
+ bool bHasHdr = pHeaderSetItem->GetItemSet().Get(ATTR_PAGE_ON).GetValue();
+ if (bHasHdr)
+ {
+ const SfxItemSet* pHeaderSet = &pHeaderSetItem->GetItemSet();
+ tools::Long nHdrHeight = pHeaderSet->Get(ATTR_PAGE_SIZE).GetSize().Height();
+ nHeader = o3tl::convert(nHdrHeight, o3tl::Length::twip, o3tl::Length::mm100);
+ }
+
+ bool bTopDown = pItemSet->Get(ATTR_PAGE_TOPDOWN).GetValue();
+
+ SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups);
+ SdrObject* pObj = aIter.Next();
+ while (pObj && pObj->IsVisible())
+ {
+ uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
+ {
+ SCCOL nX1, nX2;
+ SCROW nY1, nY2;
+ sal_Int32 nPageNumb = nStartPage;
+ if (bTopDown) // top-bottom page order
+ {
+ nX1 = 0;
+ for (size_t i = 0; i < rState.nPagesX; ++i)
+ {
+ nX2 = (*rState.xPageEndX)[i];
+ for (size_t j = 0; j < rState.nPagesY; ++j)
+ {
+ auto& rPageRow = (*rState.xPageRows)[j];
+ nY1 = rPageRow.GetStartRow();
+ nY2 = rPageRow.GetEndRow();
+
+ tools::Rectangle aPageRect(rDoc.GetMMRect(nX1, nY1, nX2, nY2, nTab));
+ tools::Rectangle aTmpRect(aPageRect.GetIntersection(pObj->GetCurrentBoundRect()));
+ if (!aTmpRect.IsEmpty())
+ {
+ tools::Long nPosX(aTmpRect.getX() - aPageRect.getX() + nLeftMargin);
+ tools::Long nPosY(aTmpRect.getY() - aPageRect.getY() + nHeader + nTopMargin);
+ tools::Rectangle aRect(Point(nPosX, nPosY), aTmpRect.GetSize());
+ lcl_SetMediaScreen(xShape, pDev, aRect, nPageNumb);
+ }
+ ++nPageNumb;
+ }
+ nX1 = nX2 + 1;
+ }
+ }
+ else // left to right page order
+ {
+ for (size_t i = 0; i < rState.nPagesY; ++i)
+ {
+ auto& rPageRow = (*rState.xPageRows)[i];
+ nY1 = rPageRow.GetStartRow();
+ nY2 = rPageRow.GetEndRow();
+ nX1 = 0;
+ for (size_t j = 0; j < rState.nPagesX; ++j)
+ {
+ nX2 = (*rState.xPageEndX)[j];
+
+ tools::Rectangle aPageRect(rDoc.GetMMRect(nX1, nY1, nX2, nY2, nTab));
+ tools::Rectangle aTmpRect(aPageRect.GetIntersection(pObj->GetCurrentBoundRect()));
+ if (!aTmpRect.IsEmpty())
+ {
+ tools::Long nPosX(aTmpRect.getX() - aPageRect.getX() + nLeftMargin);
+ tools::Long nPosY(aTmpRect.getY() - aPageRect.getY() + nHeader + nTopMargin);
+ tools::Rectangle aRect(Point(nPosX, nPosY), aTmpRect.GetSize());
+ lcl_SetMediaScreen(xShape, pDev, aRect, nPageNumb);
+ }
+ ++nPageNumb;
+ nX1 = nX2 + 1;
+ }
+ }
+ }
+ }
+ pObj = aIter.Next();
+ }
+ }
+ }
+ else // export whole sheet
+ {
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
+ OSL_ENSURE(pPage, "Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups);
+ SdrObject* pObj = aIter.Next();
+ while (pObj && pObj->IsVisible())
+ {
+ uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
+ if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
+ {
+ tools::Rectangle aRect(pObj->GetCurrentBoundRect());
+ lcl_SetMediaScreen(xShape, pDev, aRect, i);
+ }
+ pObj = aIter.Next();
+ }
+ }
+ }
+ }
+ }
+}
+
void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
const uno::Sequence<beans::PropertyValue>& rOptions )
{
@@ -2409,6 +2579,17 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec
ScDocument& rDoc = pDocShell->GetDocument();
+ SCTAB nTab;
+ if (!maValidPages.empty())
+ nTab = pPrintFuncCache->GetTabForPage(maValidPages.at(nRenderer) - 1);
+ else
+ nTab = pPrintFuncCache->GetTabForPage(nRenderer);
+
+ tools::Long nTabStart = pPrintFuncCache->GetTabStart(nTab);
+
+ if (nRenderer == nTabStart)
+ lcl_PDFExportMediaShapeScreen(pDev, *m_pPrintState, rDoc, nTab, nTabStart, bSinglePageSheets);
+
ScRange aRange;
const ScRange* pSelRange = nullptr;
if ( bSinglePageSheets )
@@ -2498,12 +2679,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec
}
} aDrawViewKeeper;
- SCTAB nTab;
- if ( !maValidPages.empty() )
- nTab = pPrintFuncCache->GetTabForPage( maValidPages.at( nRenderer )-1 );
- else
- nTab = pPrintFuncCache->GetTabForPage( nRenderer );
-
ScDrawLayer* pModel = rDoc.GetDrawLayer();
if( pModel )
@@ -2573,7 +2748,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec
aPage.Select( nRenderer+1 );
tools::Long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
- tools::Long nTabStart = pPrintFuncCache->GetTabStart( nTab );
if ( nRenderer == nTabStart || bIsFirstPage )
{