Page 1 of 1

[Solved] Setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 8:24 am
by olk
Hello,
when I set the property 'ScaleToPages' to 1, '0' will be returned ... seams that setting 'ScaleToPages' has no effect?!
The output of my code at the cmd-line is:

default ScaleToPages = 0
changed ScaleToPages = 0

I would expect:

default ScaleToPages = 0
changed ScaleToPages = 1


My code reads and outputs the default value of 'ScaleToPages' first, then it is set to 1 and
read again:

Reference< XSpreadsheetDocument > xSpreadsheetDoc ...
Reference< XStyleFamiliesSupplier > xFamiliesSupplier{ xSpreadsheetDoc, UNO_QUERY_THROW };
Reference< XStyleLoader2 > xTargetStyleLoader{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
Sequence< PropertyValue > aOptions = xTargetStyleLoader->getStyleLoaderOptions();
xTargetStyleLoader->loadStylesFromDocument( xComponent, aOptions);
Reference< XNameAccess > xFamilies{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
Reference< XNameContainer > xFamily{ xFamilies->getByName("PageStyles"), UNO_QUERY_THROW };
Reference< XStyle > xStyle{ xFamily->getByName("Default"), UNO_QUERY_THROW };
Reference< XPropertySet > xStyleProps{ xStyle, UNO_QUERY_THROW };

OUString propName = "ScaleToPages";
sal_Int32 x = -1;
assert( xStyleProps->getPropertyValue( propName) >>= x);
std::cout << "default ScaleToPages = " << x << std::endl;
x = 1;
Any X;
X <<= x;
xStyleProps->setPropertyValue( propName, X);
x = -1;
assert( xStyleProps->getPropertyValue( propName) >>= x);
std::cout << "changed ScaleToPages = " << x << std::endl; // 'x' should be 1

What I'm missing?

best regards,
Oliver

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 8:47 am
by Zizi64
What a graphical object do you want to scale with the style?
Plese upload a sample file here.

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 10:07 am
by olk
The test code creates a spreadsheet that will be exported as PDF. The spreadsheet table is too large - it spans over two instead of one page in the PDF.
I assumed that setting ScaleToPages=1 will scale the spreadsheet table to fit to one page in the PDF.

The complete test code will follow ...

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 1:54 pm
by Zizi64
From the API description of the AOO:
short ScaleToPages;

Description
contains the number of pages the sheet will printed.
This property seems related to the printing...
Are you using a virtual PdF Printer fof the conversion, or the built-in Export function?

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 2:22 pm
by olk
Zizi64 wrote:This property seems related to the printing...
Are you using a virtual PdF Printer fof the converion, or the built-in Export function?
No - the PDF is written to a file via XStorable::storeToURL().

Do you know a way to scale the spreadsheet so that is would fit to one page?

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 3:35 pm
by Zizi64
Do you know a way to scale the spreadsheet so that is would fit to one page?
How many cells you want to compress onto one A4 (or another size) paper??? Millions?

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 5:35 pm
by Zizi64
I see now, the ScaleToPages property is related to the page styles. Therefore you can modify all of the applied page styles in a document, and not only the default page style (The Page styles are not organized in a hierarchic structure).

You can modify the ScaleToPages property by usage the

Code: Select all

.setPropertyValue("ScaleToPages",0)
.setPropertyValue("ScaleToPages",1)
method.

My sample code is written in StarBasic:
Scale_pdfexport.ods
(14.23 KiB) Downloaded 274 times

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 7:41 pm
by olk
I'm using C++ - my code looks like :

Code: Select all

void
export_document_pdf( Reference< XMultiServiceFactory > const& xMainComponent,  std::string const& documentFile) {
    Reference< XStorable > xStore{ xMainComponent, UNO_QUERY_THROW };
    Sequence< PropertyValue > storeProps{ 2 };
    storeProps[0].Name = OUString::createFromAscii("Overwrite");
    storeProps[0].Value <<= (bool)(true);
    storeProps[1].Name = OUString::createFromAscii("FilterName");
    storeProps[1].Value <<= OUString::createFromAscii("calc_pdf_Export");
    xStore->storeToURL( OUString::createFromAscii( documentFile.c_str() ), storeProps);
}

SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv) {
    // start LibreOffice server with: soffice "-accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager"
   OUString sConnectionString{ "uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager" };
    sal_Int32 nCount = static_cast< sal_Int32 >( rtl_getAppCommandArgCount() );
    if ( 1 > nCount) {
        printf("using: DocumentLoader -env:URE_MORE_TYPES=<office_types_rdb_url> [<uno_connection_url>]\n\n"
                "example: generator -env:URE_MORE_TYPES=\"file:///.../program/offapi.rdb\" \"uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager\"\n");
        return -1;
    }
    if ( 2 == nCount) {
        rtl_getAppCommandArg( 1, & sConnectionString.pData);
    }
    Reference< XComponentContext > xComponentContext = cppu::defaultBootstrap_InitialComponentContext();
    Reference< XMultiComponentFactory > xMultiComponentFactoryClient = xComponentContext->getServiceManager();
    Reference< XInterface > xInterface = xMultiComponentFactoryClient->createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xComponentContext);
    Reference< XUnoUrlResolver > resolver{ xInterface, UNO_QUERY_THROW };
     xInterface = Reference< XInterface >{ resolver->resolve( sConnectionString ), UNO_QUERY_THROW };
    Reference< XPropertySet > xPropSet{ xInterface, UNO_QUERY_THROW };
    xPropSet->getPropertyValue("DefaultContext") >>= xComponentContext;
    Reference< XMultiComponentFactory > xMultiComponentFactoryServer = xComponentContext->getServiceManager();
    Reference < XDesktop2 > xComponentLoader = Desktop::create( xComponentContext);
    Reference< XComponent > xComponent = xComponentLoader->loadComponentFromURL(
            OUString::createFromAscii("private:factory/scalc"),
            OUString{ "_blank" },
            0,
            Sequence< com::sun::star::beans::PropertyValue >{});
    Reference< XMultiServiceFactory > xMainComponent = Reference< XMultiServiceFactory >{ xComponent, UNO_QUERY_THROW };
    Reference< XSpreadsheetDocument > xSpreadsheetDoc{ xMainComponent, UNO_QUERY_THROW };
    Reference< XSpreadsheet > xSheet = get_sheet( xSpreadsheetDoc, 0);
    create_header( xSheet); // generates header of table

    Reference< XStyleFamiliesSupplier > xFamiliesSupplier{ xSpreadsheetDoc, UNO_QUERY_THROW };
    Reference< XStyleLoader2 > xTargetStyleLoader{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
    Sequence< PropertyValue > aOptions = xTargetStyleLoader->getStyleLoaderOptions();
    xTargetStyleLoader->loadStylesFromDocument( xComponent, aOptions);
    Reference< XNameAccess > xFamilies{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
    Reference< XNameContainer > xFamily{ xFamilies->getByName("PageStyles"), UNO_QUERY_THROW };
    Reference< XStyle > xStyle{ xFamily->getByName("Default"), UNO_QUERY_THROW };
    Reference< XPropertySet > xStyleProps{ xStyle, UNO_QUERY_THROW };
    OUString propName = "ScaleToPages";
    sal_Int32 x = -1;
    assert( xStyleProps->getPropertyValue( propName) >>= x);
    std::cout << "default ScaleToPages = " << x << std::endl;
    x = 1;
    Any X;
    X <<= x;
    xStyleProps->setPropertyValue( propName, X);
    x = -1;
    assert( xStyleProps->getPropertyValue( propName) >>= x);
    std::cout << "changed ScaleToPages = " << x << std::endl;

    // export spreadsheet
    export_document_pdf( xMainComponent, "file:///tmp/test.pdf");

    return 0;
}
The spreadsheet has 15 columns.

As I understand your comment, my C++ code should work (but unfortunately doesn't).
I don't get why

Code: Select all

xStyleProps->setPropertyValue( propName, X);
does not set ScaleToPages to 1.

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 9:44 pm
by Zizi64
As I understand your comment, my C++ code should work (but unfortunately doesn't).
The main question is: Is the page style "Default" used (is applied) in your ducument, or the document was formatted by another existing page styles???

Can you upload your sample document here?

Re: setting property ScaleToPages with no effect?!

Posted: Tue Sep 18, 2018 9:48 pm
by Zizi64
Are you using the native ODF documents? The binary MS fileformats can not handle the page styles.

But - i suppose it - it ia a new, empty .ods document, created from the default template:

Code: Select all

Reference< XComponent > xComponent = xComponentLoader->loadComponentFromURL(
OUString::createFromAscii("private:factory/scalc"),
OUString{ "_blank" },
0,
Sequence< com::sun::star::beans::PropertyValue >{});
And the defaul ttemplate uses the default page style only. At least the original default template do it...

Re: Setting property ScaleToPages with no effect?!

Posted: Wed Sep 19, 2018 7:13 pm
by olk
Right it is a newly created odf document.
But if I try to get the page style from the spreadsheet instance itself I get the same behavior. The " default" page style is used:

Code: Select all

    Reference< XStyleFamiliesSupplier > xFamiliesSupplier{ xSpreadsheetDoc, UNO_QUERY_THROW };
    Reference< XNameAccess > xFamilies{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
    Reference< XNameContainer > xFamily{ xFamilies->getByName("PageStyles"), UNO_QUERY_THROW };
    Reference< XSpreadsheetDocument > spreadsheetDocument{ xSpreadsheetDoc, UNO_QUERY_THROW };
    Reference< XModel > model{ spreadsheetDocument, UNO_QUERY_THROW };
    Reference< XSpreadsheetView > view{ model->getCurrentController(), UNO_QUERY_THROW };
    Reference< XPropertySet > xps{ view->getActiveSheet(), UNO_QUERY_THROW };
    OUString pageStyleName;
    xps->getPropertyValue("PageStyle") >>= pageStyleName;
    std::cout << "PageStyle = " << pageStyleName << std::endl;
    Reference< XStyle > xStyle{ xFamily->getByName( pageStyleName), UNO_QUERY_THROW };
    Reference< XPropertySet > xStyleProps{ xStyle, UNO_QUERY_THROW };
out put is:
PageStyle = Default

But why is the page not scaled?

Re: Setting property ScaleToPages with no effect?!

Posted: Wed Sep 19, 2018 8:31 pm
by FJCC
I recorded a C++ macro with MRI. I hope it helps.

Code: Select all

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/XInterface.hpp>

using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::uno;
using namespace ::rtl;

void snippet(const Reference< XComponentContext > &xContext, const Reference< XInterface > &oInitialTarget)
{
    try
    {
        Reference< XStyleFamiliesSupplier > xStyleFamiliesSupplier(oInitialTarget, UNO_QUERY);
        Reference< XNameAccess > xNameAccess = xStyleFamiliesSupplier->getStyleFamilies();
        
        Reference< XNameContainer > xNameContainer(xNameAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("PageStyles"))), UNO_QUERY);
        Reference< XNameAccess > xNameAccess_2(xNameContainer, UNO_QUERY);
        Reference< XStyle > xStyle(xNameAccess_2->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("Default"))), UNO_QUERY);
        Reference< XPropertySet > xPropSet(xStyle, UNO_QUERY);
        xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScaleToPages")), makeAny((sal_Int16) 1));
        
    }
    catch (IllegalArgumentException &e)
    {
        // setPropertyValue
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
    catch (PropertyVetoException &e)
    {
        // setPropertyValue
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
    catch (WrappedTargetException &e)
    {
        // getByName, setPropertyValue
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
    catch (UnknownPropertyException &e)
    {
        // setPropertyValue
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
    catch (NoSuchElementException &e)
    {
        // getByName
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
    catch (RuntimeException &e)
    {
        // getByName
        //printf(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
    }
}

Re: Setting property ScaleToPages with no effect?!

Posted: Wed Sep 19, 2018 9:09 pm
by olk
Thank you - your code helped me to figure out the reason why it failed to scale the page.
The reason is that I used sal_Int32 instead of sal_Int16 as type for the value/flag.
The correct code:

Code: Select all

    Reference< XStyleFamiliesSupplier > xFamiliesSupplier{ xSpreadsheetDoc, UNO_QUERY_THROW };
    Reference< XStyleLoader2 > xTargetStyleLoader{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
    Sequence< PropertyValue > aOptions = xTargetStyleLoader->getStyleLoaderOptions();
    xTargetStyleLoader->loadStylesFromDocument( xComponent, aOptions);
    Reference< XNameAccess > xFamilies{ xFamiliesSupplier->getStyleFamilies(), UNO_QUERY_THROW };
    Reference< XNameContainer > xFamily{ xFamilies->getByName("PageStyles"), UNO_QUERY_THROW };
    Reference< XStyle > xStyle{ xFamily->getByName("Default"), UNO_QUERY_THROW };
    Reference< XPropertySet > xStyleProps{ xStyle, UNO_QUERY_THROW };

    OUString propName{ "ScaleToPages" };
    sal_Int16 x = -1, y = -1;
    assert( xStyleProps->getPropertyValue( propName) >>= x);
    std::cout << "default ScaleToPages = " << x << std::endl;
    xStyleProps->setPropertyValue( propName, makeAny( static_cast< sal_Int16 >( 1) ) );
    assert( xStyleProps->getPropertyValue( propName) >>= y);
    std::cout << "changed ScaleToPages = " << y << std::endl
;