PDF export: allow setting filter data keys from the cmdline

Follow-up improvement to commit 3eb9eb9906c9 (lok: add pdf version
option for export, 2021-11-15), possibilities are endless.

For example, to skip the first page of a Draw document:

soffice --convert-to 'pdf:draw_pdf_Export:{"PageRange":{"type":"string","value":"2-"}}' test.odg

Add watermark:

soffice --convert-to 'pdf:draw_pdf_Export:{"TiledWatermark":{"type":"string","value":"draft"}}' test.odg

Encrypt:

soffice --convert-to 'pdf:draw_pdf_Export:{"EncryptFile":{"type":"boolean","value":"true"},"DocumentOpenPassword":{"type":"string","value":"secret"}}' test.odg

Version 1.5 (instead of the default 1.6):

soffice --convert-to 'pdf:draw_pdf_Export:{"SelectPdfVersion":{"type":"long","value":"15"}}' test.odg

The cost of the verbose syntax is probably smaller than the benefit of
having this 1:1 mapping from string to PropertyValues.

Change-Id: I2093a3a787a9578dd02a154593b7a020f4a0ba31
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128849
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/filter/source/pdf/pdffilter.cxx b/filter/source/pdf/pdffilter.cxx
index 6d1a793..d7fc558 100644
--- a/filter/source/pdf/pdffilter.cxx
+++ b/filter/source/pdf/pdffilter.cxx
@@ -30,6 +30,9 @@

#include <com/sun/star/io/XOutputStream.hpp>

#include <comphelper/propertysequence.hxx>
#include <comphelper/sequence.hxx>

using namespace ::com::sun::star::io;

PDFFilter::PDFFilter( const Reference< XComponentContext > &rxContext ) :
@@ -47,6 +50,7 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
{
    Reference< XOutputStream >  xOStm;
    Sequence< PropertyValue >   aFilterData;
    OUString aFilterOptions;
    sal_Int32                   nLength = rDescriptor.getLength();
    const PropertyValue*        pValue = rDescriptor.getConstArray();
    bool                        bIsRedactMode = false;
@@ -60,6 +64,8 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
            pValue[ i ].Value >>= xOStm;
        else if ( pValue[ i ].Name == "FilterData" )
            pValue[ i ].Value >>= aFilterData;
        else if ( pValue[ i ].Name == "FilterOptions" )
            pValue[ i ].Value >>= aFilterOptions;
        else if ( pValue[ i ].Name == "StatusIndicator" )
            pValue[ i ].Value >>= xStatusIndicator;
        else if ( pValue[i].Name == "InteractionHandler" )
@@ -72,6 +78,13 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
            pValue[i].Value >>= bIsRedactMode;
    }

    if (!aFilterData.hasElements() && !aFilterOptions.isEmpty())
    {
        // Allow setting filter data keys from the cmdline.
        std::vector<PropertyValue> aData = comphelper::JsonToPropertyValues(aFilterOptions.toUtf8());
        aFilterData = comphelper::containerToSequence(aData);
    }

    /* we don't get FilterData if we are exporting directly
       to pdf, but we have to use the last user settings (especially for the CompressMode) */
    if ( !aFilterData.hasElements() )
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 88b2a13..2906be6 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2006,6 +2006,25 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testLinkWrongPagePartial)
    CPPUNIT_ASSERT(!pPdfPage2->hasLinks());
}

CPPUNIT_TEST_FIXTURE(PdfExportTest, testPageRange)
{
    // Given a document with 3 pages:
    // When exporting that document to PDF, skipping the first page:
    aMediaDescriptor["FilterName"] <<= OUString("draw_pdf_Export");
    aMediaDescriptor["FilterOptions"]
        <<= OUString("{\"PageRange\":{\"type\":\"string\",\"value\":\"2-\"}}");
    saveAsPDF(u"link-wrong-page-partial.odg");

    // Then make sure the resulting PDF has 2 pages:
    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parseExport();
    CPPUNIT_ASSERT(pPdfDocument);
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2
    // - Actual  : 3
    // i.e. FilterOptions was ignored.
    CPPUNIT_ASSERT_EQUAL(2, pPdfDocument->getPageCount());
}

CPPUNIT_TEST_FIXTURE(PdfExportTest, testLargePage)
{
    // Import the bugdoc and export as PDF.