LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - print3.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 1009 0.0 %
Date: 2012-12-27 Functions: 0 82 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "vcl/print.hxx"
      21             : #include "vcl/svapp.hxx"
      22             : #include "vcl/metaact.hxx"
      23             : #include "vcl/msgbox.hxx"
      24             : #include "vcl/configsettings.hxx"
      25             : #include "vcl/unohelp.hxx"
      26             : 
      27             : #include "printdlg.hxx"
      28             : #include "svdata.hxx"
      29             : #include "salinst.hxx"
      30             : #include "salprn.hxx"
      31             : #include "svids.hrc"
      32             : 
      33             : #include "tools/urlobj.hxx"
      34             : 
      35             : #include "com/sun/star/container/XNameAccess.hpp"
      36             : #include "com/sun/star/ui/dialogs/XFilePicker.hpp"
      37             : #include "com/sun/star/ui/dialogs/XFilterManager.hpp"
      38             : #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
      39             : #include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
      40             : #include "com/sun/star/view/DuplexMode.hpp"
      41             : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
      42             : #include "com/sun/star/awt/Size.hpp"
      43             : #include "comphelper/processfactory.hxx"
      44             : 
      45             : #include <boost/unordered_map.hpp>
      46             : #include <boost/unordered_set.hpp>
      47             : 
      48             : using namespace com::sun::star;
      49             : using namespace com::sun::star::uno;
      50             : using namespace com::sun::star::beans;
      51             : using namespace vcl;
      52             : 
      53           0 : class ImplPageCache
      54             : {
      55           0 :     struct CacheEntry
      56             :     {
      57             :         GDIMetaFile                 aPage;
      58             :         PrinterController::PageSize aSize;
      59             :     };
      60             : 
      61             :     std::vector< CacheEntry >  maPages;
      62             :     std::vector< sal_Int32 >    maPageNumbers;
      63             :     std::vector< sal_Int32 >    maCacheRanking;
      64             : 
      65             :     static const sal_Int32 nCacheSize = 6;
      66             : 
      67           0 :     void updateRanking( sal_Int32 nLastHit )
      68             :     {
      69           0 :         if( maCacheRanking[0] != nLastHit )
      70             :         {
      71           0 :             for( sal_Int32 i = nCacheSize-1; i > 0; i-- )
      72           0 :                 maCacheRanking[i] = maCacheRanking[i-1];
      73           0 :             maCacheRanking[0] = nLastHit;
      74             :         }
      75           0 :     }
      76             : 
      77             : public:
      78           0 :     ImplPageCache()
      79             :     : maPages( nCacheSize )
      80             :     , maPageNumbers( nCacheSize, -1 )
      81           0 :     , maCacheRanking( nCacheSize )
      82             :     {
      83           0 :         for( sal_Int32 i = 0; i < nCacheSize; i++ )
      84           0 :             maCacheRanking[i] = nCacheSize - i - 1;
      85           0 :     }
      86             : 
      87             :     // caution: does not ensure uniqueness
      88           0 :     void insert( sal_Int32 i_nPageNo, const GDIMetaFile& i_rPage, const PrinterController::PageSize& i_rSize )
      89             :     {
      90           0 :         sal_Int32 nReplacePage = maCacheRanking.back();
      91           0 :         maPages[ nReplacePage ].aPage = i_rPage;
      92           0 :         maPages[ nReplacePage ].aSize = i_rSize;
      93           0 :         maPageNumbers[ nReplacePage ] = i_nPageNo;
      94             :         // cache insertion means in our case, the page was just queried
      95             :         // so update the ranking
      96           0 :         updateRanking( nReplacePage );
      97           0 :     }
      98             : 
      99             :     // caution: bad algorithm; should there ever be reason to increase the cache size beyond 6
     100             :     // this needs to be urgently rewritten. However do NOT increase the cache size lightly,
     101             :     // whole pages can be rather memory intensive
     102           0 :     bool get( sal_Int32 i_nPageNo, GDIMetaFile& o_rPageFile, PrinterController::PageSize& o_rSize )
     103             :     {
     104           0 :         for( sal_Int32 i = 0; i < nCacheSize; ++i )
     105             :         {
     106           0 :             if( maPageNumbers[i] == i_nPageNo )
     107             :             {
     108           0 :                 updateRanking( i );
     109           0 :                 o_rPageFile = maPages[i].aPage;
     110           0 :                 o_rSize = maPages[i].aSize;
     111           0 :                 return true;
     112             :             }
     113             :         }
     114           0 :         return false;
     115             :     }
     116             : 
     117           0 :     void invalidate()
     118             :     {
     119           0 :         for( sal_Int32 i = 0; i < nCacheSize; ++i )
     120             :         {
     121           0 :             maPageNumbers[i] = -1;
     122           0 :             maPages[i].aPage.Clear();
     123           0 :             maCacheRanking[i] = nCacheSize - i - 1;
     124             :         }
     125           0 :     }
     126             : };
     127             : 
     128             : class vcl::ImplPrinterControllerData
     129             : {
     130             : public:
     131           0 :     struct ControlDependency
     132             :     {
     133             :         rtl::OUString       maDependsOnName;
     134             :         sal_Int32           mnDependsOnEntry;
     135             : 
     136           0 :         ControlDependency() : mnDependsOnEntry( -1 ) {}
     137             :     };
     138             : 
     139             :     typedef boost::unordered_map< rtl::OUString, size_t, rtl::OUStringHash > PropertyToIndexMap;
     140             :     typedef boost::unordered_map< rtl::OUString, ControlDependency, rtl::OUStringHash > ControlDependencyMap;
     141             :     typedef boost::unordered_map< rtl::OUString, Sequence< sal_Bool >, rtl::OUStringHash > ChoiceDisableMap;
     142             : 
     143             :     boost::shared_ptr<Printer>                                  mpPrinter;
     144             :     Sequence< PropertyValue >                                   maUIOptions;
     145             :     std::vector< PropertyValue >                                maUIProperties;
     146             :     std::vector< bool >                                         maUIPropertyEnabled;
     147             :     PropertyToIndexMap                                          maPropertyToIndex;
     148             :     Link                                                        maOptionChangeHdl;
     149             :     ControlDependencyMap                                        maControlDependencies;
     150             :     ChoiceDisableMap                                            maChoiceDisableMap;
     151             :     sal_Bool                                                    mbFirstPage;
     152             :     sal_Bool                                                    mbLastPage;
     153             :     sal_Bool                                                    mbReversePageOrder;
     154             :     view::PrintableState                                        meJobState;
     155             : 
     156             :     vcl::PrinterController::MultiPageSetup                      maMultiPage;
     157             : 
     158             :     vcl::PrintProgressDialog*                                   mpProgress;
     159             : 
     160             :     ImplPageCache                                               maPageCache;
     161             : 
     162             :     // set by user through printer config dialog
     163             :     // if set, pages are centered and trimmed onto the fixed page
     164             :     Size                                                        maFixedPageSize;
     165             :     // set by user through printer config dialog
     166             :     sal_Int32                                                   mnDefaultPaperBin;
     167             :     // Set by user through printer preferences in print dialog.
     168             :     // Overrides application-set tray for a page.
     169             :     sal_Int32                                                   mnFixedPaperBin;
     170             : 
     171             :     // N.B. Apparently we have three levels of paper tray settings
     172             :     // (latter overrides former):
     173             :     // 1. default tray
     174             :     // 2. tray set for a concrete page by an application, e.g., writer
     175             :     //    allows setting a printer tray (for the default printer) for a
     176             :     //    page style. This setting can be overriden by user by selecting
     177             :     //    "Use only paper tray from printer preferences" on the Options
     178             :     //    page in the print dialog, in which case the default tray is
     179             :     //    used for all pages.
     180             :     // 3. tray set in printer properties the printer dialog
     181             :     // I'm not quite sure why 1. and 3. are distinct, but the commit
     182             :     // history suggests this is intentional...
     183             : 
     184           0 :     ImplPrinterControllerData() :
     185             :         mbFirstPage( sal_True ),
     186             :         mbLastPage( sal_False ),
     187             :         mbReversePageOrder( sal_False ),
     188             :         meJobState( view::PrintableState_JOB_STARTED ),
     189             :         mpProgress( NULL ),
     190             :         mnDefaultPaperBin( -1 ),
     191           0 :         mnFixedPaperBin( -1 )
     192           0 :     {}
     193           0 :     ~ImplPrinterControllerData() { delete mpProgress; }
     194             : 
     195           0 :     Size getRealPaperSize( const Size& i_rPageSize, bool bNoNUP ) const
     196             :     {
     197           0 :         if( maFixedPageSize.Width() > 0 && maFixedPageSize.Height() > 0 )
     198           0 :             return maFixedPageSize;
     199           0 :         if( maMultiPage.nRows * maMultiPage.nColumns > 1 && ! bNoNUP )
     200           0 :             return maMultiPage.aPaperSize;
     201           0 :         return i_rPageSize;
     202             :     }
     203           0 :     bool isFixedPageSize() const
     204           0 :     { return maFixedPageSize.Width() != 0 && maFixedPageSize.Height() != 0; }
     205             :     PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP );
     206             : };
     207             : 
     208           0 : PrinterController::PrinterController( const boost::shared_ptr<Printer>& i_pPrinter )
     209           0 :     : mpImplData( new ImplPrinterControllerData )
     210             : {
     211           0 :     mpImplData->mpPrinter = i_pPrinter;
     212           0 : }
     213             : 
     214           0 : static rtl::OUString queryFile( Printer* pPrinter )
     215             : {
     216           0 :     rtl::OUString aResult;
     217             : 
     218           0 :     uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
     219           0 :     if( xFactory.is() )
     220             :     {
     221           0 :         uno::Sequence< uno::Any > aTempl( 1 );
     222           0 :         aTempl.getArray()[0] <<= ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION;
     223             :         uno::Reference< ui::dialogs::XFilePicker > xFilePicker(
     224           0 :             xFactory->createInstanceWithArguments(
     225             :                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ),
     226           0 :                 aTempl ), uno::UNO_QUERY );
     227             :         DBG_ASSERT( xFilePicker.is(), "could not get FilePicker service" );
     228             : 
     229           0 :         uno::Reference< ui::dialogs::XFilterManager > xFilterMgr( xFilePicker, uno::UNO_QUERY );
     230           0 :         if( xFilePicker.is() && xFilterMgr.is() )
     231             :         {
     232             :             try
     233             :             {
     234             : #ifdef UNX
     235             :                 // add PostScript and PDF
     236           0 :                 bool bPS = true, bPDF = true;
     237           0 :                 if( pPrinter )
     238             :                 {
     239           0 :                     if( pPrinter->GetCapabilities( PRINTER_CAPABILITIES_PDF ) )
     240           0 :                         bPS = false;
     241             :                     else
     242           0 :                         bPDF = false;
     243             :                 }
     244           0 :                 if( bPS )
     245           0 :                     xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PostScript" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.ps" ) ) );
     246           0 :                 if( bPDF )
     247           0 :                     xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Portable Document Format" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.pdf" ) ) );
     248             : #elif defined WNT
     249             :         (void)pPrinter;
     250             :                 xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.PRN" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ) );
     251             : #endif
     252             :                 // add arbitrary files
     253           0 :                 xFilterMgr->appendFilter(VclResId(SV_STDTEXT_ALLFILETYPES), "*.*");
     254             :             }
     255           0 :             catch (const lang::IllegalArgumentException&)
     256             :             {
     257             :                 SAL_WARN( "vcl.gdi", "caught IllegalArgumentException when registering filter" );
     258             :             }
     259             : 
     260           0 :             if( xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK )
     261             :             {
     262           0 :                 uno::Sequence< ::rtl::OUString > aPathSeq( xFilePicker->getFiles() );
     263           0 :                 INetURLObject aObj( aPathSeq[0] );
     264           0 :                 aResult = aObj.PathToFileName();
     265             :             }
     266           0 :         }
     267             :     }
     268           0 :     return aResult;
     269             : }
     270             : 
     271           0 : struct PrintJobAsync
     272             : {
     273             :     boost::shared_ptr<PrinterController>  mpController;
     274             :     JobSetup                            maInitSetup;
     275             : 
     276           0 :     PrintJobAsync( const boost::shared_ptr<PrinterController>& i_pController,
     277             :                    const JobSetup& i_rInitSetup
     278             :                    )
     279           0 :     : mpController( i_pController ), maInitSetup( i_rInitSetup )
     280           0 :     {}
     281             : 
     282             :     DECL_LINK( ExecJob, void* );
     283             : };
     284             : 
     285           0 : IMPL_LINK_NOARG(PrintJobAsync, ExecJob)
     286             : {
     287           0 :     Printer::ImplPrintJob( mpController, maInitSetup );
     288             : 
     289             :     // clean up, do not access members after this
     290           0 :     delete this;
     291             : 
     292           0 :     return 0;
     293             : }
     294             : 
     295           0 : void Printer::PrintJob( const boost::shared_ptr<PrinterController>& i_pController,
     296             :                         const JobSetup& i_rInitSetup
     297             :                         )
     298             : {
     299           0 :     sal_Bool bSynchronous = sal_False;
     300           0 :     beans::PropertyValue* pVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wait" ) ) );
     301           0 :     if( pVal )
     302           0 :         pVal->Value >>= bSynchronous;
     303             : 
     304           0 :     if( bSynchronous )
     305           0 :         ImplPrintJob( i_pController, i_rInitSetup );
     306             :     else
     307             :     {
     308           0 :         PrintJobAsync* pAsync = new PrintJobAsync( i_pController, i_rInitSetup );
     309           0 :         Application::PostUserEvent( LINK( pAsync, PrintJobAsync, ExecJob ) );
     310             :     }
     311           0 : }
     312             : 
     313           0 : void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pController,
     314             :                             const JobSetup& i_rInitSetup
     315             :                             )
     316             : {
     317           0 :     boost::shared_ptr<PrinterController> pController( i_pController );
     318             : 
     319             :     // check if there is a default printer; if not, show an error box (if appropriate)
     320           0 :     if( GetDefaultPrinterName().isEmpty() )
     321             :     {
     322           0 :         if(  pController->isShowDialogs()
     323             :              // && ! pController->isDirectPrint()
     324             :            )
     325             :         {
     326           0 :             ErrorBox aBox( NULL, VclResId( SV_PRINT_NOPRINTERWARNING ) );
     327           0 :             aBox.Execute();
     328             :         }
     329             :         pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ),
     330           0 :                                makeAny( sal_False ) );
     331             :     }
     332             : 
     333             :     // setup printer
     334             : 
     335             :     // #i114306# changed behavior back from persistence
     336             :     // if no specific printer is already set, create the default printer
     337           0 :     if( ! pController->getPrinter() )
     338             :     {
     339           0 :         rtl::OUString aPrinterName( i_rInitSetup.GetPrinterName() );
     340           0 :         boost::shared_ptr<Printer> pPrinter( new Printer( aPrinterName ) );
     341           0 :         pPrinter->SetJobSetup( i_rInitSetup );
     342           0 :         pController->setPrinter( pPrinter );
     343             :     }
     344             : 
     345             :     // reset last page property
     346           0 :     i_pController->setLastPage( sal_False );
     347             : 
     348             :     // update "PageRange" property inferring from other properties:
     349             :     // case 1: "Pages" set from UNO API ->
     350             :     //         setup "Print Selection" and insert "PageRange" attribute
     351             :     // case 2: "All pages" is selected
     352             :     //         update "Page range" attribute to have a sensible default,
     353             :     //         but leave "All" as selected
     354             : 
     355             :     // "Pages" attribute from API is now equivalent to "PageRange"
     356             :     // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
     357             :     // Argh ! That sure needs cleaning up
     358           0 :     beans::PropertyValue* pContentVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) ) );
     359           0 :     if( ! pContentVal )
     360           0 :         pContentVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ) );
     361             : 
     362             :     // case 1: UNO API has set "Pages"
     363           0 :     beans::PropertyValue* pPagesVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) ) );
     364           0 :     if( pPagesVal )
     365             :     {
     366           0 :         rtl::OUString aPagesVal;
     367           0 :         pPagesVal->Value >>= aPagesVal;
     368           0 :         if( !aPagesVal.isEmpty() )
     369             :         {
     370             :             // "Pages" attribute from API is now equivalent to "PageRange"
     371             :             // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
     372             :             // Argh ! That sure needs cleaning up
     373           0 :             if( pContentVal )
     374             :             {
     375           0 :                 pContentVal->Value = makeAny( sal_Int32( 1 ) );
     376           0 :                 i_pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ), pPagesVal->Value );
     377             :             }
     378           0 :         }
     379             :     }
     380             :     // case 2: is "All" selected ?
     381           0 :     else if( pContentVal )
     382             :     {
     383           0 :         sal_Int32 nContent = -1;
     384           0 :         if( pContentVal->Value >>= nContent )
     385             :         {
     386           0 :             if( nContent == 0 )
     387             :             {
     388             :                 // do not overwrite PageRange if it is already set
     389           0 :                 beans::PropertyValue* pRangeVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) );
     390           0 :                 rtl::OUString aRange;
     391           0 :                 if( pRangeVal )
     392           0 :                     pRangeVal->Value >>= aRange;
     393           0 :                 if( aRange.isEmpty() )
     394             :                 {
     395           0 :                     sal_Int32 nPages = i_pController->getPageCount();
     396           0 :                     if( nPages > 0 )
     397             :                     {
     398           0 :                         rtl::OUStringBuffer aBuf( 32 );
     399           0 :                         aBuf.appendAscii( "1" );
     400           0 :                         if( nPages > 1 )
     401             :                         {
     402           0 :                             aBuf.appendAscii( "-" );
     403           0 :                             aBuf.append( nPages );
     404             :                         }
     405           0 :                         i_pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ), makeAny( aBuf.makeStringAndClear() ) );
     406             :                     }
     407           0 :                 }
     408             :             }
     409             :         }
     410             :     }
     411             : 
     412           0 :     beans::PropertyValue* pReverseVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ) );
     413           0 :     if( pReverseVal )
     414             :     {
     415           0 :         sal_Bool bReverse = sal_False;
     416           0 :         pReverseVal->Value >>= bReverse;
     417           0 :         pController->setReversePrint( bReverse );
     418             :     }
     419             : 
     420             :     // setup NUp printing from properties
     421           0 :     sal_Int32 nRows = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpRows" ) ), 1 );
     422           0 :     sal_Int32 nCols = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpColumns" ) ), 1 );
     423           0 :     if( nRows > 1 || nCols > 1 )
     424             :     {
     425           0 :         PrinterController::MultiPageSetup aMPS;
     426           0 :         aMPS.nRows         = nRows > 1 ? nRows : 1;
     427           0 :         aMPS.nColumns      = nCols > 1 ? nCols : 1;
     428           0 :         sal_Int32 nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpPageMarginLeft" ) ), aMPS.nLeftMargin );
     429           0 :         if( nValue >= 0 )
     430           0 :             aMPS.nLeftMargin = nValue;
     431           0 :         nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpPageMarginRight" ) ), aMPS.nRightMargin );
     432           0 :         if( nValue >= 0 )
     433           0 :             aMPS.nRightMargin = nValue;
     434           0 :         nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpPageMarginTop" ) ), aMPS.nTopMargin );
     435           0 :         if( nValue >= 0 )
     436           0 :             aMPS.nTopMargin = nValue;
     437           0 :         nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpPageMarginBottom" ) ), aMPS.nBottomMargin );
     438           0 :         if( nValue >= 0 )
     439           0 :             aMPS.nBottomMargin = nValue;
     440           0 :         nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpHorizontalSpacing" ) ), aMPS.nHorizontalSpacing );
     441           0 :         if( nValue >= 0 )
     442           0 :             aMPS.nHorizontalSpacing = nValue;
     443           0 :         nValue = i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpVerticalSpacing" ) ), aMPS.nVerticalSpacing );
     444           0 :         if( nValue >= 0 )
     445           0 :             aMPS.nVerticalSpacing = nValue;
     446           0 :         aMPS.bDrawBorder = i_pController->getBoolProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpDrawBorder" ) ), aMPS.bDrawBorder );
     447           0 :         aMPS.nOrder = static_cast<PrinterController::NupOrderType>(i_pController->getIntProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpSubPageOrder" ) ), aMPS.nOrder ));
     448           0 :         aMPS.aPaperSize = i_pController->getPrinter()->PixelToLogic( i_pController->getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) );
     449           0 :         beans::PropertyValue* pPgSizeVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NUpPaperSize" ) ) );
     450           0 :         awt::Size aSizeVal;
     451           0 :         if( pPgSizeVal && (pPgSizeVal->Value >>= aSizeVal) )
     452             :         {
     453           0 :             aMPS.aPaperSize.Width() = aSizeVal.Width;
     454           0 :             aMPS.aPaperSize.Height() = aSizeVal.Height;
     455             :         }
     456             : 
     457           0 :         i_pController->setMultipage( aMPS );
     458             :     }
     459             : 
     460             :     // in direct print case check whether there is anything to print.
     461             :     // if not, show an errorbox (if appropriate)
     462           0 :     if( pController->isShowDialogs() && pController->isDirectPrint() )
     463             :     {
     464           0 :         if( pController->getFilteredPageCount() == 0 )
     465             :         {
     466           0 :             ErrorBox aBox( NULL, VclResId( SV_PRINT_NOCONTENT ) );
     467           0 :             aBox.Execute();
     468           0 :             return;
     469             :         }
     470             :     }
     471             : 
     472             :     // check if the printer brings up its own dialog
     473             :     // in that case leave the work to that dialog
     474           0 :     if( ! pController->getPrinter()->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) &&
     475           0 :         ! pController->isDirectPrint() &&
     476           0 :         pController->isShowDialogs()
     477             :         )
     478             :     {
     479             :         try
     480             :         {
     481           0 :             PrintDialog aDlg( NULL, i_pController );
     482           0 :             if( ! aDlg.Execute() )
     483             :             {
     484           0 :                 i_pController->abortJob();
     485             :                 return;
     486             :             }
     487           0 :             if( aDlg.isPrintToFile() )
     488             :             {
     489           0 :                 rtl::OUString aFile = queryFile( pController->getPrinter().get() );
     490           0 :                 if( aFile.isEmpty() )
     491             :                 {
     492           0 :                     i_pController->abortJob();
     493             :                     return;
     494             :                 }
     495             :                 pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ),
     496           0 :                                        makeAny( aFile ) );
     497             :             }
     498           0 :             else if( aDlg.isSingleJobs() )
     499             :             {
     500             :                 pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ),
     501           0 :                                        makeAny( sal_True ) );
     502           0 :             }
     503             :         }
     504           0 :         catch (const std::bad_alloc&)
     505             :         {
     506             :         }
     507             :     }
     508             : 
     509           0 :     pController->pushPropertiesToPrinter();
     510             : 
     511           0 :     rtl::OUString aJobName;
     512           0 :     beans::PropertyValue* pJobNameVal = pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "JobName" ) ) );
     513           0 :     if( pJobNameVal )
     514           0 :         pJobNameVal->Value >>= aJobName;
     515             : 
     516           0 :     pController->getPrinter()->StartJob( String( aJobName ), pController );
     517             : 
     518           0 :     pController->jobFinished( pController->getJobState() );
     519             : }
     520             : 
     521           0 : bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl::PrinterController>& i_pController )
     522             : {
     523           0 :     mnError = PRINTER_OK;
     524             : 
     525           0 :     if ( IsDisplayPrinter() )
     526           0 :         return sal_False;
     527             : 
     528           0 :     if ( IsJobActive() || IsPrinting() )
     529           0 :         return sal_False;
     530             : 
     531           0 :     sal_uLong   nCopies = mnCopyCount;
     532           0 :     bool    bCollateCopy = mbCollateCopy;
     533           0 :     bool    bUserCopy = sal_False;
     534             : 
     535           0 :     if ( nCopies > 1 )
     536             :     {
     537             :         sal_uLong nDevCopy;
     538             : 
     539           0 :         if ( bCollateCopy )
     540           0 :             nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
     541             :         else
     542           0 :             nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );
     543             : 
     544             :         // need to do copies by hand ?
     545           0 :         if ( nCopies > nDevCopy )
     546             :         {
     547           0 :             bUserCopy = sal_True;
     548           0 :             nCopies = 1;
     549           0 :             bCollateCopy = sal_False;
     550             :         }
     551             :     }
     552             :     else
     553           0 :         bCollateCopy = sal_False;
     554             : 
     555             : 
     556           0 :     ImplSVData* pSVData = ImplGetSVData();
     557           0 :     mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
     558             : 
     559           0 :     if ( !mpPrinter )
     560           0 :         return sal_False;
     561             : 
     562           0 :     sal_Bool bSinglePrintJobs = sal_False;
     563           0 :     beans::PropertyValue* pSingleValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) );
     564           0 :     if( pSingleValue )
     565             :     {
     566           0 :         pSingleValue->Value >>= bSinglePrintJobs;
     567             :     }
     568             : 
     569           0 :     beans::PropertyValue* pFileValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ) );
     570           0 :     if( pFileValue )
     571             :     {
     572           0 :         rtl::OUString aFile;
     573           0 :         pFileValue->Value >>= aFile;
     574           0 :         if( !aFile.isEmpty() )
     575             :         {
     576           0 :             mbPrintFile = sal_True;
     577           0 :             maPrintFile = aFile;
     578           0 :             bSinglePrintJobs = sal_False;
     579           0 :         }
     580             :     }
     581             : 
     582           0 :     rtl::OUString* pPrintFile = NULL;
     583           0 :     if ( mbPrintFile )
     584           0 :         pPrintFile = &maPrintFile;
     585           0 :     mpPrinterOptions->ReadFromConfig( mbPrintFile );
     586             : 
     587           0 :     maJobName               = i_rJobName;
     588           0 :     mnCurPage               = 1;
     589           0 :     mnCurPrintPage          = 1;
     590           0 :     mbPrinting              = sal_True;
     591           0 :     if( GetCapabilities( PRINTER_CAPABILITIES_USEPULLMODEL ) )
     592             :     {
     593           0 :         mbJobActive             = sal_True;
     594             :         // sallayer does all necessary page printing
     595             :         // and also handles showing a dialog
     596             :         // that also means it must call jobStarted when the dialog is finished
     597             :         // it also must set the JobState of the Controller
     598           0 :         if( mpPrinter->StartJob( pPrintFile,
     599             :                                  i_rJobName,
     600             :                                  Application::GetDisplayName(),
     601             :                                  maJobSetup.ImplGetConstData(),
     602           0 :                                  *i_pController ) )
     603             :         {
     604           0 :             EndJob();
     605             :         }
     606             :         else
     607             :         {
     608           0 :             mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
     609           0 :             if ( !mnError )
     610           0 :                 mnError = PRINTER_GENERALERROR;
     611           0 :             pSVData->mpDefInst->DestroyPrinter( mpPrinter );
     612           0 :             mnCurPage           = 0;
     613           0 :             mnCurPrintPage      = 0;
     614           0 :             mbPrinting          = sal_False;
     615           0 :             mpPrinter = NULL;
     616           0 :             mbJobActive = sal_False;
     617             : 
     618           0 :             GDIMetaFile aDummyFile;
     619           0 :             i_pController->setLastPage(sal_True);
     620           0 :             i_pController->getFilteredPageFile(0, aDummyFile);
     621             : 
     622           0 :             return false;
     623             :         }
     624             :     }
     625             :     else
     626             :     {
     627             :         // possibly a dialog has been shown
     628             :         // now the real job starts
     629           0 :         i_pController->setJobState( view::PrintableState_JOB_STARTED );
     630           0 :         i_pController->jobStarted();
     631             : 
     632           0 :         int nJobs = 1;
     633           0 :         int nOuterRepeatCount = 1;
     634           0 :         int nInnerRepeatCount = 1;
     635           0 :         if( bUserCopy )
     636             :         {
     637           0 :             if( mbCollateCopy )
     638           0 :                 nOuterRepeatCount = mnCopyCount;
     639             :             else
     640           0 :                 nInnerRepeatCount = mnCopyCount;
     641             :         }
     642           0 :         if( bSinglePrintJobs )
     643             :         {
     644           0 :             nJobs = mnCopyCount;
     645           0 :             nCopies = 1;
     646           0 :             nOuterRepeatCount = nInnerRepeatCount = 1;
     647             :         }
     648             : 
     649           0 :         for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ )
     650             :         {
     651           0 :             bool bError = false, bAborted = false;
     652           0 :             if( mpPrinter->StartJob( pPrintFile,
     653             :                                      i_rJobName,
     654             :                                      Application::GetDisplayName(),
     655             :                                      nCopies,
     656             :                                      bCollateCopy,
     657           0 :                                      i_pController->isDirectPrint(),
     658           0 :                                      maJobSetup.ImplGetConstData() ) )
     659             :             {
     660           0 :                 mbJobActive             = sal_True;
     661           0 :                 i_pController->createProgressDialog();
     662           0 :                 int nPages = i_pController->getFilteredPageCount();
     663           0 :                 for( int nOuterIteration = 0; nOuterIteration < nOuterRepeatCount && ! bAborted; nOuterIteration++ )
     664             :                 {
     665           0 :                     for( int nPage = 0; nPage < nPages && ! bAborted; nPage++ )
     666             :                     {
     667           0 :                         for( int nInnerIteration = 0; nInnerIteration < nInnerRepeatCount && ! bAborted; nInnerIteration++ )
     668             :                         {
     669           0 :                             if( nPage == nPages-1 &&
     670             :                                 nOuterIteration == nOuterRepeatCount-1 &&
     671             :                                 nInnerIteration == nInnerRepeatCount-1 &&
     672             :                                 nJobIteration == nJobs-1 )
     673             :                             {
     674           0 :                                 i_pController->setLastPage( sal_True );
     675             :                             }
     676           0 :                             i_pController->printFilteredPage( nPage );
     677           0 :                             if( i_pController->isProgressCanceled() )
     678             :                             {
     679           0 :                                 i_pController->abortJob();
     680             :                             }
     681           0 :                             if (i_pController->getJobState() ==
     682             :                                     view::PrintableState_JOB_ABORTED)
     683             :                             {
     684           0 :                                 bAborted = true;
     685             :                             }
     686             :                         }
     687             :                     }
     688             :                     // FIXME: duplex ?
     689             :                 }
     690           0 :                 EndJob();
     691             : 
     692           0 :                 if( nJobIteration < nJobs-1 )
     693             :                 {
     694           0 :                     mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
     695             : 
     696           0 :                     if ( mpPrinter )
     697             :                     {
     698           0 :                         maJobName               = i_rJobName;
     699           0 :                         mnCurPage               = 1;
     700           0 :                         mnCurPrintPage          = 1;
     701           0 :                         mbPrinting              = sal_True;
     702             :                     }
     703             :                     else
     704           0 :                         bError = true;
     705             :                 }
     706             :             }
     707             :             else
     708           0 :                 bError = true;
     709             : 
     710           0 :             if( bError )
     711             :             {
     712           0 :                 mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
     713           0 :                 if ( !mnError )
     714           0 :                     mnError = PRINTER_GENERALERROR;
     715             :                 i_pController->setJobState( mnError == PRINTER_ABORT
     716             :                                             ? view::PrintableState_JOB_ABORTED
     717           0 :                                             : view::PrintableState_JOB_FAILED );
     718           0 :                 if( mpPrinter )
     719           0 :                     pSVData->mpDefInst->DestroyPrinter( mpPrinter );
     720           0 :                 mnCurPage           = 0;
     721           0 :                 mnCurPrintPage      = 0;
     722           0 :                 mbPrinting          = sal_False;
     723           0 :                 mpPrinter = NULL;
     724             : 
     725           0 :                 return false;
     726             :             }
     727             :         }
     728             : 
     729           0 :         if( i_pController->getJobState() == view::PrintableState_JOB_STARTED )
     730           0 :             i_pController->setJobState( view::PrintableState_JOB_SPOOLED );
     731             :     }
     732             : 
     733             :     // make last used printer persistent for UI jobs
     734           0 :     if( i_pController->isShowDialogs() && ! i_pController->isDirectPrint() )
     735             :     {
     736           0 :         SettingsConfigItem* pItem = SettingsConfigItem::get();
     737             :         pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
     738             :                          rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinterUsed" ) ),
     739           0 :                          GetName()
     740           0 :                          );
     741             :     }
     742             : 
     743           0 :     return true;
     744             : }
     745             : 
     746           0 : PrinterController::~PrinterController()
     747             : {
     748           0 :     delete mpImplData;
     749           0 : }
     750             : 
     751           0 : view::PrintableState PrinterController::getJobState() const
     752             : {
     753           0 :     return mpImplData->meJobState;
     754             : }
     755             : 
     756           0 : void PrinterController::setJobState( view::PrintableState i_eState )
     757             : {
     758           0 :     mpImplData->meJobState = i_eState;
     759           0 : }
     760             : 
     761           0 : const boost::shared_ptr<Printer>& PrinterController::getPrinter() const
     762             : {
     763           0 :     return mpImplData->mpPrinter;
     764             : }
     765             : 
     766           0 : void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter )
     767             : {
     768           0 :     mpImplData->mpPrinter = i_rPrinter;
     769             :     setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ),
     770           0 :               makeAny( rtl::OUString( i_rPrinter->GetName() ) ) );
     771           0 :     mpImplData->mnDefaultPaperBin = mpImplData->mpPrinter->GetPaperBin();
     772           0 :     mpImplData->mnFixedPaperBin = -1;
     773           0 : }
     774             : 
     775           0 : void PrinterController:: resetPrinterOptions( bool i_bFileOutput )
     776             : {
     777           0 :     PrinterOptions aOpt;
     778           0 :     aOpt.ReadFromConfig( i_bFileOutput );
     779           0 :     mpImplData->mpPrinter->SetPrinterOptions( aOpt );
     780           0 : }
     781             : 
     782           0 : bool PrinterController::setupPrinter( Window* i_pParent )
     783             : {
     784           0 :     bool bRet = false;
     785           0 :     if( mpImplData->mpPrinter.get() )
     786             :     {
     787             :         // get old data
     788           0 :         Size aPaperSize( mpImplData->mpPrinter->PixelToLogic(
     789           0 :             mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
     790           0 :         sal_uInt16 nPaperBin = mpImplData->mpPrinter->GetPaperBin();
     791             : 
     792             :         // call driver setup
     793           0 :         bRet = mpImplData->mpPrinter->Setup( i_pParent );
     794           0 :         if( bRet )
     795             :         {
     796             :             // was papersize or bin  overridden ? if so we need to take action
     797           0 :             Size aNewPaperSize( mpImplData->mpPrinter->PixelToLogic(
     798           0 :                 mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
     799           0 :             sal_uInt16 nNewPaperBin = mpImplData->mpPrinter->GetPaperBin();
     800           0 :             if( aNewPaperSize != aPaperSize || nNewPaperBin != nPaperBin )
     801             :             {
     802           0 :                 mpImplData->maFixedPageSize = aNewPaperSize;
     803           0 :                 mpImplData->maPageCache.invalidate();
     804           0 :                 awt::Size aOverrideSize;
     805           0 :                 aOverrideSize.Width = aNewPaperSize.Width();
     806           0 :                 aOverrideSize.Height = aNewPaperSize.Height();
     807             :                 setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OverridePageSize" ) ),
     808           0 :                           makeAny( aOverrideSize ) );
     809           0 :                 mpImplData->mnFixedPaperBin = nNewPaperBin;
     810             :             }
     811             :         }
     812             :     }
     813           0 :     return bRet;
     814             : }
     815             : 
     816           0 : PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP )
     817             : {
     818           0 :     PrinterController::PageSize aPageSize;
     819           0 :     aPageSize.aSize = mpPrinter->GetPaperSize();
     820           0 :     awt::Size aSetSize, aIsSize;
     821           0 :     sal_Int32 nPaperBin = mnDefaultPaperBin;
     822           0 :     for( sal_Int32 nProperty = 0, nPropertyCount = i_rProps.getLength(); nProperty < nPropertyCount; ++nProperty )
     823             :     {
     824           0 :         if ( i_rProps[ nProperty ].Name == "PreferredPageSize" )
     825             :         {
     826           0 :             i_rProps[ nProperty ].Value >>= aSetSize;
     827             :         }
     828           0 :         else if ( i_rProps[ nProperty ].Name == "PageSize" )
     829             :         {
     830           0 :             i_rProps[ nProperty ].Value >>= aIsSize;
     831             :         }
     832           0 :         else if ( i_rProps[ nProperty ].Name == "PageIncludesNonprintableArea" )
     833             :         {
     834           0 :             sal_Bool bVal = sal_False;
     835           0 :             i_rProps[ nProperty ].Value >>= bVal;
     836           0 :             aPageSize.bFullPaper = static_cast<bool>(bVal);
     837             :         }
     838           0 :         else if ( i_rProps[ nProperty ].Name == "PrinterPaperTray" )
     839             :         {
     840           0 :             sal_Int32 nBin = -1;
     841           0 :             i_rProps[ nProperty ].Value >>= nBin;
     842           0 :             if( nBin >= 0 && nBin < mpPrinter->GetPaperBinCount() )
     843           0 :                 nPaperBin = nBin;
     844             :         }
     845             :     }
     846             : 
     847           0 :     Size aCurSize( mpPrinter->GetPaperSize() );
     848           0 :     if( aSetSize.Width && aSetSize.Height )
     849             :     {
     850           0 :         Size aSetPaperSize( aSetSize.Width, aSetSize.Height );
     851           0 :         Size aRealPaperSize( getRealPaperSize( aSetPaperSize, bNoNUP ) );
     852           0 :         if( aRealPaperSize != aCurSize )
     853           0 :             aIsSize = aSetSize;
     854             :     }
     855             : 
     856           0 :     if( aIsSize.Width && aIsSize.Height )
     857             :     {
     858           0 :         aPageSize.aSize.Width() = aIsSize.Width;
     859           0 :         aPageSize.aSize.Height() = aIsSize.Height;
     860             : 
     861           0 :         Size aRealPaperSize( getRealPaperSize( aPageSize.aSize, bNoNUP ) );
     862           0 :         if( aRealPaperSize != aCurSize )
     863           0 :             mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() );
     864             :     }
     865             : 
     866             :     // paper bin set from properties in print dialog overrides
     867             :     // application default for a page
     868           0 :     if ( mnFixedPaperBin != -1 )
     869           0 :         nPaperBin = mnFixedPaperBin;
     870             : 
     871           0 :     if( nPaperBin != -1 && nPaperBin != mpPrinter->GetPaperBin() )
     872           0 :         mpPrinter->SetPaperBin( nPaperBin );
     873             : 
     874           0 :     return aPageSize;
     875             : }
     876             : 
     877           0 : int PrinterController::getPageCountProtected() const
     878             : {
     879           0 :     const MapMode aMapMode( MAP_100TH_MM );
     880             : 
     881           0 :     mpImplData->mpPrinter->Push();
     882           0 :     mpImplData->mpPrinter->SetMapMode( aMapMode );
     883           0 :     int nPages = getPageCount();
     884           0 :     mpImplData->mpPrinter->Pop();
     885           0 :     return nPages;
     886             : }
     887             : 
     888           0 : Sequence< beans::PropertyValue > PrinterController::getPageParametersProtected( int i_nPage ) const
     889             : {
     890           0 :     const MapMode aMapMode( MAP_100TH_MM );
     891             : 
     892           0 :     mpImplData->mpPrinter->Push();
     893           0 :     mpImplData->mpPrinter->SetMapMode( aMapMode );
     894           0 :     Sequence< beans::PropertyValue > aResult( getPageParameters( i_nPage ) );
     895           0 :     mpImplData->mpPrinter->Pop();
     896           0 :     return aResult;
     897             : }
     898             : 
     899           0 : PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
     900             : {
     901             :     // update progress if necessary
     902           0 :     if( mpImplData->mpProgress )
     903             :     {
     904             :         // do nothing if printing is canceled
     905           0 :         if( mpImplData->mpProgress->isCanceled() )
     906           0 :             return PrinterController::PageSize();
     907           0 :         mpImplData->mpProgress->tick();
     908           0 :         Application::Reschedule( true );
     909             :     }
     910             : 
     911           0 :     if( i_bMayUseCache )
     912             :     {
     913           0 :         PrinterController::PageSize aPageSize;
     914           0 :         if( mpImplData->maPageCache.get( i_nUnfilteredPage, o_rMtf, aPageSize ) )
     915             :         {
     916           0 :             return aPageSize;
     917             :         }
     918             :     }
     919             :     else
     920           0 :         mpImplData->maPageCache.invalidate();
     921             : 
     922           0 :     o_rMtf.Clear();
     923             : 
     924             :     // get page parameters
     925           0 :     Sequence< PropertyValue > aPageParm( getPageParametersProtected( i_nUnfilteredPage ) );
     926           0 :     const MapMode aMapMode( MAP_100TH_MM );
     927             : 
     928           0 :     mpImplData->mpPrinter->Push();
     929           0 :     mpImplData->mpPrinter->SetMapMode( aMapMode );
     930             : 
     931             :     // modify job setup if necessary
     932           0 :     PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm, true );
     933             : 
     934           0 :     o_rMtf.SetPrefSize( aPageSize.aSize );
     935           0 :     o_rMtf.SetPrefMapMode( aMapMode );
     936             : 
     937           0 :     mpImplData->mpPrinter->EnableOutput( sal_False );
     938             : 
     939           0 :     o_rMtf.Record( mpImplData->mpPrinter.get() );
     940             : 
     941           0 :     printPage( i_nUnfilteredPage );
     942             : 
     943           0 :     o_rMtf.Stop();
     944           0 :     o_rMtf.WindStart();
     945           0 :     mpImplData->mpPrinter->Pop();
     946             : 
     947           0 :     if( i_bMayUseCache )
     948           0 :         mpImplData->maPageCache.insert( i_nUnfilteredPage, o_rMtf, aPageSize );
     949             : 
     950             :     // reset "FirstPage" property to false now we've gotten at least our first one
     951           0 :     mpImplData->mbFirstPage = sal_False;
     952             : 
     953           0 :     return aPageSize;
     954             : }
     955             : 
     956           0 : static void appendSubPage( GDIMetaFile& o_rMtf, const Rectangle& i_rClipRect, GDIMetaFile& io_rSubPage, bool i_bDrawBorder )
     957             : {
     958             :     // intersect all clipregion actions with our clip rect
     959           0 :     io_rSubPage.WindStart();
     960           0 :     io_rSubPage.Clip( i_rClipRect );
     961             : 
     962             :     // save gstate
     963           0 :     o_rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
     964             : 
     965             :     // clip to page rect
     966           0 :     o_rMtf.AddAction( new MetaClipRegionAction( Region( i_rClipRect ), sal_True ) );
     967             : 
     968             :     // append the subpage
     969           0 :     io_rSubPage.WindStart();
     970           0 :     io_rSubPage.Play( o_rMtf );
     971             : 
     972             :     // restore gstate
     973           0 :     o_rMtf.AddAction( new MetaPopAction() );
     974             : 
     975             :     // draw a border
     976           0 :     if( i_bDrawBorder )
     977             :     {
     978             :         // save gstate
     979           0 :         o_rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_CLIPREGION | PUSH_MAPMODE ) );
     980           0 :         o_rMtf.AddAction( new MetaMapModeAction( MapMode( MAP_100TH_MM ) ) );
     981             : 
     982           0 :         Rectangle aBorderRect( i_rClipRect );
     983           0 :         o_rMtf.AddAction( new MetaLineColorAction( Color( COL_BLACK ), sal_True ) );
     984           0 :         o_rMtf.AddAction( new MetaFillColorAction( Color( COL_TRANSPARENT ), sal_False ) );
     985           0 :         o_rMtf.AddAction( new MetaRectAction( aBorderRect ) );
     986             : 
     987             :         // restore gstate
     988           0 :         o_rMtf.AddAction( new MetaPopAction() );
     989             :     }
     990           0 : }
     991             : 
     992           0 : PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
     993             : {
     994           0 :     const MultiPageSetup& rMPS( mpImplData->maMultiPage );
     995           0 :     int nSubPages = rMPS.nRows * rMPS.nColumns;
     996           0 :     if( nSubPages < 1 )
     997           0 :         nSubPages = 1;
     998             : 
     999             :     // reverse sheet order
    1000           0 :     if( mpImplData->mbReversePageOrder )
    1001             :     {
    1002           0 :         int nDocPages = getFilteredPageCount();
    1003           0 :         i_nFilteredPage = nDocPages - 1 - i_nFilteredPage;
    1004             :     }
    1005             : 
    1006             :     // there is no filtering to be done (and possibly the page size of the
    1007             :     // original page is to be set), when N-Up is "neutral" that is there is
    1008             :     // only one subpage and the margins are 0
    1009           0 :     if( nSubPages == 1 &&
    1010             :         rMPS.nLeftMargin == 0 && rMPS.nRightMargin == 0 &&
    1011             :         rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 )
    1012             :     {
    1013           0 :         PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache );
    1014           0 :         if (mpImplData->meJobState != view::PrintableState_JOB_STARTED)
    1015             :         {   // rhbz#657394: check that we are still printing...
    1016           0 :             return PrinterController::PageSize();
    1017             :         }
    1018           0 :         Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true );
    1019           0 :         mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
    1020           0 :         mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
    1021           0 :         if( aPaperSize != aPageSize.aSize )
    1022             :         {
    1023             :             // user overridden page size, center Metafile
    1024           0 :             o_rMtf.WindStart();
    1025           0 :             long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2;
    1026           0 :             long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2;
    1027           0 :             o_rMtf.Move( nDX, nDY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() );
    1028           0 :             o_rMtf.WindStart();
    1029           0 :             o_rMtf.SetPrefSize( aPaperSize );
    1030           0 :             aPageSize.aSize = aPaperSize;
    1031             :         }
    1032           0 :         return aPageSize;
    1033             :     }
    1034             : 
    1035             :     // set last page property really only on the very last page to be rendered
    1036             :     // that is on the last subpage of a NUp run
    1037           0 :     sal_Bool bIsLastPage = mpImplData->mbLastPage;
    1038           0 :     mpImplData->mbLastPage = sal_False;
    1039             : 
    1040           0 :     Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize, false ) );
    1041             : 
    1042             :     // multi page area: page size minus margins + one time spacing right and down
    1043             :     // the added spacing is so each subpage can be calculated including its spacing
    1044           0 :     Size aMPArea( aPaperSize );
    1045           0 :     aMPArea.Width()  -= rMPS.nLeftMargin + rMPS.nRightMargin;
    1046           0 :     aMPArea.Width()  += rMPS.nHorizontalSpacing;
    1047           0 :     aMPArea.Height() -= rMPS.nTopMargin + rMPS.nBottomMargin;
    1048           0 :     aMPArea.Height() += rMPS.nVerticalSpacing;
    1049             : 
    1050             :     // determine offsets
    1051           0 :     long nAdvX = aMPArea.Width() / rMPS.nColumns;
    1052           0 :     long nAdvY = aMPArea.Height() / rMPS.nRows;
    1053             : 
    1054             :     // determine size of a "cell" subpage, leave a little space around pages
    1055           0 :     Size aSubPageSize( nAdvX - rMPS.nHorizontalSpacing, nAdvY - rMPS.nVerticalSpacing );
    1056             : 
    1057           0 :     o_rMtf.Clear();
    1058           0 :     o_rMtf.SetPrefSize( aPaperSize );
    1059           0 :     o_rMtf.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
    1060           0 :     o_rMtf.AddAction( new MetaMapModeAction( MapMode( MAP_100TH_MM ) ) );
    1061             : 
    1062           0 :     int nDocPages = getPageCountProtected();
    1063           0 :     if (mpImplData->meJobState != view::PrintableState_JOB_STARTED)
    1064             :     {   // rhbz#657394: check that we are still printing...
    1065           0 :         return PrinterController::PageSize();
    1066             :     }
    1067           0 :     for( int nSubPage = 0; nSubPage < nSubPages; nSubPage++ )
    1068             :     {
    1069             :         // map current sub page to real page
    1070           0 :         int nPage = (i_nFilteredPage * nSubPages + nSubPage) / rMPS.nRepeat;
    1071           0 :         if( nSubPage == nSubPages-1 ||
    1072             :             nPage == nDocPages-1 )
    1073             :         {
    1074           0 :             mpImplData->mbLastPage = bIsLastPage;
    1075             :         }
    1076           0 :         if( nPage >= 0 && nPage < nDocPages )
    1077             :         {
    1078           0 :             GDIMetaFile aPageFile;
    1079           0 :             PrinterController::PageSize aPageSize = getPageFile( nPage, aPageFile, i_bMayUseCache );
    1080           0 :             if( aPageSize.aSize.Width() && aPageSize.aSize.Height() )
    1081             :             {
    1082           0 :                 long nCellX = 0, nCellY = 0;
    1083           0 :                 switch( rMPS.nOrder )
    1084             :                 {
    1085             :                 case PrinterController::LRTB:
    1086           0 :                     nCellX = (nSubPage % rMPS.nColumns);
    1087           0 :                     nCellY = (nSubPage / rMPS.nColumns);
    1088           0 :                     break;
    1089             :                 case PrinterController::TBLR:
    1090           0 :                     nCellX = (nSubPage / rMPS.nRows);
    1091           0 :                     nCellY = (nSubPage % rMPS.nRows);
    1092           0 :                     break;
    1093             :                 case PrinterController::RLTB:
    1094           0 :                     nCellX = rMPS.nColumns - 1 - (nSubPage % rMPS.nColumns);
    1095           0 :                     nCellY = (nSubPage / rMPS.nColumns);
    1096           0 :                     break;
    1097             :                 case PrinterController::TBRL:
    1098           0 :                     nCellX = rMPS.nColumns - 1 - (nSubPage / rMPS.nRows);
    1099           0 :                     nCellY = (nSubPage % rMPS.nRows);
    1100           0 :                     break;
    1101             :                 }
    1102             :                 // scale the metafile down to a sub page size
    1103           0 :                 double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width());
    1104           0 :                 double fScaleY = double(aSubPageSize.Height())/double(aPageSize.aSize.Height());
    1105           0 :                 double fScale  = std::min( fScaleX, fScaleY );
    1106           0 :                 aPageFile.Scale( fScale, fScale );
    1107           0 :                 aPageFile.WindStart();
    1108             : 
    1109             :                 // move the subpage so it is centered in its "cell"
    1110           0 :                 long nOffX = (aSubPageSize.Width() - long(double(aPageSize.aSize.Width()) * fScale)) / 2;
    1111           0 :                 long nOffY = (aSubPageSize.Height() - long(double(aPageSize.aSize.Height()) * fScale)) / 2;
    1112           0 :                 long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX;
    1113           0 :                 long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY;
    1114           0 :                 aPageFile.Move( nX, nY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() );
    1115           0 :                 aPageFile.WindStart();
    1116             :                 // calculate border rectangle
    1117             :                 Rectangle aSubPageRect( Point( nX, nY ),
    1118           0 :                                         Size( long(double(aPageSize.aSize.Width())*fScale),
    1119           0 :                                               long(double(aPageSize.aSize.Height())*fScale) ) );
    1120             : 
    1121             :                 // append subpage to page
    1122           0 :                 appendSubPage( o_rMtf, aSubPageRect, aPageFile, rMPS.bDrawBorder );
    1123           0 :             }
    1124             :         }
    1125             :     }
    1126           0 :     o_rMtf.WindStart();
    1127             : 
    1128             :     // subsequent getPageFile calls have changed the paper, reset it to current value
    1129           0 :     mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
    1130           0 :     mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
    1131             : 
    1132           0 :     return PrinterController::PageSize( aPaperSize, true );
    1133             : }
    1134             : 
    1135           0 : int PrinterController::getFilteredPageCount()
    1136             : {
    1137           0 :     int nDiv = mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns;
    1138           0 :     if( nDiv < 1 )
    1139           0 :         nDiv = 1;
    1140           0 :     return (getPageCountProtected() * mpImplData->maMultiPage.nRepeat + (nDiv-1)) / nDiv;
    1141             : }
    1142             : 
    1143           0 : sal_uLong PrinterController::removeTransparencies( GDIMetaFile& i_rIn, GDIMetaFile& o_rOut )
    1144             : {
    1145           0 :     sal_uLong nRestoreDrawMode = mpImplData->mpPrinter->GetDrawMode();
    1146           0 :     sal_Int32 nMaxBmpDPIX = mpImplData->mpPrinter->ImplGetDPIX();
    1147           0 :     sal_Int32 nMaxBmpDPIY = mpImplData->mpPrinter->ImplGetDPIY();
    1148             : 
    1149           0 :     const PrinterOptions&   rPrinterOptions = mpImplData->mpPrinter->GetPrinterOptions();
    1150             : 
    1151             :     static const sal_Int32 OPTIMAL_BMP_RESOLUTION = 300;
    1152             :     static const sal_Int32 NORMAL_BMP_RESOLUTION  = 200;
    1153             : 
    1154             : 
    1155           0 :     if( rPrinterOptions.IsReduceBitmaps() )
    1156             :     {
    1157             :         // calculate maximum resolution for bitmap graphics
    1158           0 :         if( PRINTER_BITMAP_OPTIMAL == rPrinterOptions.GetReducedBitmapMode() )
    1159             :         {
    1160           0 :             nMaxBmpDPIX = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIX );
    1161           0 :             nMaxBmpDPIY = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIY );
    1162             :         }
    1163           0 :         else if( PRINTER_BITMAP_NORMAL == rPrinterOptions.GetReducedBitmapMode() )
    1164             :         {
    1165           0 :             nMaxBmpDPIX = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIX );
    1166           0 :             nMaxBmpDPIY = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIY );
    1167             :         }
    1168             :         else
    1169             :         {
    1170           0 :             nMaxBmpDPIX = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIX );
    1171           0 :             nMaxBmpDPIY = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIY );
    1172             :         }
    1173             :     }
    1174             : 
    1175             :     // convert to greysacles
    1176           0 :     if( rPrinterOptions.IsConvertToGreyscales() )
    1177             :     {
    1178           0 :         mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() |
    1179             :                                             ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT |
    1180           0 :                                               DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) );
    1181             :     }
    1182             : 
    1183             :     // disable transparency output
    1184           0 :     if( rPrinterOptions.IsReduceTransparency() && ( PRINTER_TRANSPARENCY_NONE == rPrinterOptions.GetReducedTransparencyMode() ) )
    1185             :     {
    1186           0 :         mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() | DRAWMODE_NOTRANSPARENCY );
    1187             :     }
    1188             : 
    1189           0 :     Color aBg( COL_TRANSPARENT ); // default: let RemoveTransparenciesFromMetaFile do its own background logic
    1190           0 :     if( mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns > 1 )
    1191             :     {
    1192             :         // in N-Up printing we have no "page" background operation
    1193             :         // we also have no way to determine the paper color
    1194             :         // so let's go for white, which will kill 99.9% of the real cases
    1195           0 :         aBg = Color( COL_WHITE );
    1196             :     }
    1197           0 :     mpImplData->mpPrinter->RemoveTransparenciesFromMetaFile( i_rIn, o_rOut, nMaxBmpDPIX, nMaxBmpDPIY,
    1198           0 :                                                              rPrinterOptions.IsReduceTransparency(),
    1199           0 :                                                              rPrinterOptions.GetReducedTransparencyMode() == PRINTER_TRANSPARENCY_AUTO,
    1200           0 :                                                              rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency(),
    1201             :                                                              aBg
    1202           0 :                                                              );
    1203           0 :     return nRestoreDrawMode;
    1204             : }
    1205             : 
    1206           0 : void PrinterController::printFilteredPage( int i_nPage )
    1207             : {
    1208           0 :     if( mpImplData->meJobState != view::PrintableState_JOB_STARTED )
    1209             :         return;
    1210             : 
    1211           0 :     GDIMetaFile aPageFile;
    1212           0 :     PrinterController::PageSize aPageSize = getFilteredPageFile( i_nPage, aPageFile );
    1213             : 
    1214           0 :     if (mpImplData->meJobState != view::PrintableState_JOB_STARTED)
    1215             :     {   // rhbz#657394: check that we are still printing...
    1216             :         return;
    1217             :     }
    1218             : 
    1219           0 :     if( mpImplData->mpProgress )
    1220             :     {
    1221             :         // do nothing if printing is canceled
    1222           0 :         if( mpImplData->mpProgress->isCanceled() )
    1223             :         {
    1224           0 :             setJobState( view::PrintableState_JOB_ABORTED );
    1225             :             return;
    1226             :         }
    1227             :     }
    1228             : 
    1229             :     // in N-Up printing set the correct page size
    1230           0 :     mpImplData->mpPrinter->SetMapMode( MAP_100TH_MM );
    1231             :     // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile()
    1232           0 :     mpImplData->mpPrinter->SetPaperSizeUser( aPageSize.aSize, ! mpImplData->isFixedPageSize() );
    1233           0 :     if( mpImplData->mnFixedPaperBin != -1 &&
    1234           0 :         mpImplData->mpPrinter->GetPaperBin() != mpImplData->mnFixedPaperBin )
    1235             :     {
    1236           0 :         mpImplData->mpPrinter->SetPaperBin( mpImplData->mnFixedPaperBin );
    1237             :     }
    1238             : 
    1239             :     // if full paper is meant to be used, move the output to accomodate for pageoffset
    1240           0 :     if( aPageSize.bFullPaper )
    1241             :     {
    1242           0 :         Point aPageOffset( mpImplData->mpPrinter->GetPageOffset() );
    1243           0 :         aPageFile.WindStart();
    1244           0 :         aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y(), mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() );
    1245             :     }
    1246             : 
    1247           0 :     GDIMetaFile aCleanedFile;
    1248           0 :     sal_uLong nRestoreDrawMode = removeTransparencies( aPageFile, aCleanedFile );
    1249             : 
    1250           0 :     mpImplData->mpPrinter->EnableOutput( sal_True );
    1251             : 
    1252             :     // actually print the page
    1253           0 :     mpImplData->mpPrinter->ImplStartPage();
    1254             : 
    1255           0 :     mpImplData->mpPrinter->Push();
    1256           0 :     aCleanedFile.WindStart();
    1257           0 :     aCleanedFile.Play( mpImplData->mpPrinter.get() );
    1258           0 :     mpImplData->mpPrinter->Pop();
    1259             : 
    1260           0 :     mpImplData->mpPrinter->ImplEndPage();
    1261             : 
    1262           0 :     mpImplData->mpPrinter->SetDrawMode( nRestoreDrawMode );
    1263             : }
    1264             : 
    1265           0 : void PrinterController::jobStarted()
    1266             : {
    1267           0 : }
    1268             : 
    1269           0 : void PrinterController::jobFinished( view::PrintableState )
    1270             : {
    1271           0 : }
    1272             : 
    1273           0 : void PrinterController::abortJob()
    1274             : {
    1275           0 :     setJobState( view::PrintableState_JOB_ABORTED );
    1276             :     // applications (well, sw) depend on a page request with "IsLastPage" = true
    1277             :     // to free resources, else they (well, sw) will crash eventually
    1278           0 :     setLastPage( sal_True );
    1279           0 :     delete mpImplData->mpProgress;
    1280           0 :     mpImplData->mpProgress = NULL;
    1281           0 :     GDIMetaFile aMtf;
    1282           0 :     getPageFile( 0, aMtf, false );
    1283           0 : }
    1284             : 
    1285           0 : void PrinterController::setLastPage( sal_Bool i_bLastPage )
    1286             : {
    1287           0 :     mpImplData->mbLastPage = i_bLastPage;
    1288           0 : }
    1289             : 
    1290           0 : void PrinterController::setReversePrint( sal_Bool i_bReverse )
    1291             : {
    1292           0 :     mpImplData->mbReversePageOrder = i_bReverse;
    1293           0 : }
    1294             : 
    1295           0 : bool PrinterController::getReversePrint() const
    1296             : {
    1297           0 :     return mpImplData->mbReversePageOrder;
    1298             : }
    1299             : 
    1300           0 : Sequence< PropertyValue > PrinterController::getJobProperties( const Sequence< PropertyValue >& i_rMergeList ) const
    1301             : {
    1302           0 :     boost::unordered_set< rtl::OUString, rtl::OUStringHash > aMergeSet;
    1303           0 :     size_t nResultLen = size_t(i_rMergeList.getLength()) + mpImplData->maUIProperties.size() + 3;
    1304           0 :     for( int i = 0; i < i_rMergeList.getLength(); i++ )
    1305           0 :         aMergeSet.insert( i_rMergeList[i].Name );
    1306             : 
    1307           0 :     Sequence< PropertyValue > aResult( nResultLen );
    1308           0 :     for( int i = 0; i < i_rMergeList.getLength(); i++ )
    1309           0 :         aResult[i] = i_rMergeList[i];
    1310           0 :     int nCur = i_rMergeList.getLength();
    1311           0 :     for( size_t i = 0; i < mpImplData->maUIProperties.size(); i++ )
    1312             :     {
    1313           0 :         if( aMergeSet.find( mpImplData->maUIProperties[i].Name ) == aMergeSet.end() )
    1314           0 :             aResult[nCur++] = mpImplData->maUIProperties[i];
    1315             :     }
    1316             :     // append IsFirstPage
    1317           0 :     if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) ) == aMergeSet.end() )
    1318             :     {
    1319           0 :         PropertyValue aVal;
    1320           0 :         aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
    1321           0 :         aVal.Value <<= mpImplData->mbFirstPage;
    1322           0 :         aResult[nCur++] = aVal;
    1323             :     }
    1324             :     // append IsLastPage
    1325           0 :     if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) ) == aMergeSet.end() )
    1326             :     {
    1327           0 :         PropertyValue aVal;
    1328           0 :         aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
    1329           0 :         aVal.Value <<= mpImplData->mbLastPage;
    1330           0 :         aResult[nCur++] = aVal;
    1331             :     }
    1332             :     // append IsPrinter
    1333           0 :     if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) ) ) == aMergeSet.end() )
    1334             :     {
    1335           0 :         PropertyValue aVal;
    1336           0 :         aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) );
    1337           0 :         aVal.Value <<= sal_True;
    1338           0 :         aResult[nCur++] = aVal;
    1339             :     }
    1340           0 :     aResult.realloc( nCur );
    1341           0 :     return aResult;
    1342             : }
    1343             : 
    1344           0 : const Sequence< beans::PropertyValue >& PrinterController::getUIOptions() const
    1345             : {
    1346           0 :     return mpImplData->maUIOptions;
    1347             : }
    1348             : 
    1349           0 : beans::PropertyValue* PrinterController::getValue( const rtl::OUString& i_rProperty )
    1350             : {
    1351             :     boost::unordered_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
    1352           0 :         mpImplData->maPropertyToIndex.find( i_rProperty );
    1353           0 :     return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL;
    1354             : }
    1355             : 
    1356           0 : const beans::PropertyValue* PrinterController::getValue( const rtl::OUString& i_rProperty ) const
    1357             : {
    1358             :     boost::unordered_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
    1359           0 :         mpImplData->maPropertyToIndex.find( i_rProperty );
    1360           0 :     return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL;
    1361             : }
    1362             : 
    1363           0 : void PrinterController::setValue( const rtl::OUString& i_rName, const Any& i_rValue )
    1364             : {
    1365           0 :     beans::PropertyValue aVal;
    1366           0 :     aVal.Name = i_rName;
    1367           0 :     aVal.Value = i_rValue;
    1368             : 
    1369           0 :     setValue( aVal );
    1370           0 : }
    1371             : 
    1372           0 : void PrinterController::setValue( const beans::PropertyValue& i_rValue )
    1373             : {
    1374             :     boost::unordered_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
    1375           0 :         mpImplData->maPropertyToIndex.find( i_rValue.Name );
    1376           0 :     if( it != mpImplData->maPropertyToIndex.end() )
    1377           0 :         mpImplData->maUIProperties[ it->second ] = i_rValue;
    1378             :     else
    1379             :     {
    1380             :         // insert correct index into property map
    1381           0 :         mpImplData->maPropertyToIndex[ i_rValue.Name ] = mpImplData->maUIProperties.size();
    1382           0 :         mpImplData->maUIProperties.push_back( i_rValue );
    1383           0 :         mpImplData->maUIPropertyEnabled.push_back( true );
    1384             :     }
    1385           0 : }
    1386             : 
    1387           0 : void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_rOptions )
    1388             : {
    1389             :     DBG_ASSERT( mpImplData->maUIOptions.getLength() == 0, "setUIOptions called twice !" );
    1390             : 
    1391           0 :     mpImplData->maUIOptions = i_rOptions;
    1392             : 
    1393           0 :     for( int i = 0; i < i_rOptions.getLength(); i++ )
    1394             :     {
    1395           0 :         Sequence< beans::PropertyValue > aOptProp;
    1396           0 :         i_rOptions[i].Value >>= aOptProp;
    1397           0 :         bool bIsEnabled = true;
    1398           0 :         bool bHaveProperty = false;
    1399           0 :         rtl::OUString aPropName;
    1400           0 :         vcl::ImplPrinterControllerData::ControlDependency aDep;
    1401           0 :         Sequence< sal_Bool > aChoicesDisabled;
    1402           0 :         for( int n = 0; n < aOptProp.getLength(); n++ )
    1403             :         {
    1404           0 :             const beans::PropertyValue& rEntry( aOptProp[ n ] );
    1405           0 :             if ( rEntry.Name == "Property" )
    1406             :             {
    1407           0 :                 PropertyValue aVal;
    1408           0 :                 rEntry.Value >>= aVal;
    1409             :                 DBG_ASSERT( mpImplData->maPropertyToIndex.find( aVal.Name )
    1410             :                             == mpImplData->maPropertyToIndex.end(), "duplicate property entry" );
    1411           0 :                 setValue( aVal );
    1412           0 :                 aPropName = aVal.Name;
    1413           0 :                 bHaveProperty = true;
    1414             :             }
    1415           0 :             else if ( rEntry.Name == "Enabled" )
    1416             :             {
    1417           0 :                 sal_Bool bValue = sal_True;
    1418           0 :                 rEntry.Value >>= bValue;
    1419           0 :                 bIsEnabled = bValue;
    1420             :             }
    1421           0 :             else if ( rEntry.Name == "DependsOnName" )
    1422             :             {
    1423           0 :                 rEntry.Value >>= aDep.maDependsOnName;
    1424             :             }
    1425           0 :             else if ( rEntry.Name == "DependsOnEntry" )
    1426             :             {
    1427           0 :                 rEntry.Value >>= aDep.mnDependsOnEntry;
    1428             :             }
    1429           0 :             else if ( rEntry.Name == "ChoicesDisabled" )
    1430             :             {
    1431           0 :                 rEntry.Value >>= aChoicesDisabled;
    1432             :             }
    1433             :         }
    1434           0 :         if( bHaveProperty )
    1435             :         {
    1436             :             vcl::ImplPrinterControllerData::PropertyToIndexMap::const_iterator it =
    1437           0 :                 mpImplData->maPropertyToIndex.find( aPropName );
    1438             :             // sanity check
    1439           0 :             if( it != mpImplData->maPropertyToIndex.end() )
    1440             :             {
    1441           0 :                 mpImplData->maUIPropertyEnabled[ it->second ] = bIsEnabled;
    1442             :             }
    1443           0 :             if( !aDep.maDependsOnName.isEmpty() )
    1444           0 :                 mpImplData->maControlDependencies[ aPropName ] = aDep;
    1445           0 :             if( aChoicesDisabled.getLength() > 0 )
    1446           0 :                 mpImplData->maChoiceDisableMap[ aPropName ] = aChoicesDisabled;
    1447             :         }
    1448           0 :     }
    1449           0 : }
    1450             : 
    1451           0 : bool PrinterController::isUIOptionEnabled( const rtl::OUString& i_rProperty ) const
    1452             : {
    1453           0 :     bool bEnabled = false;
    1454             :     boost::unordered_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator prop_it =
    1455           0 :         mpImplData->maPropertyToIndex.find( i_rProperty );
    1456           0 :     if( prop_it != mpImplData->maPropertyToIndex.end() )
    1457             :     {
    1458           0 :         bEnabled = mpImplData->maUIPropertyEnabled[prop_it->second];
    1459             : 
    1460           0 :         if( bEnabled )
    1461             :         {
    1462             :             // check control dependencies
    1463             :             vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
    1464           0 :                 mpImplData->maControlDependencies.find( i_rProperty );
    1465           0 :             if( it != mpImplData->maControlDependencies.end() )
    1466             :             {
    1467             :                 // check if the dependency is enabled
    1468             :                 // if the dependency is disabled, we are too
    1469           0 :                 bEnabled = isUIOptionEnabled( it->second.maDependsOnName );
    1470             : 
    1471           0 :                 if( bEnabled )
    1472             :                 {
    1473             :                     // does the dependency have the correct value ?
    1474           0 :                     const com::sun::star::beans::PropertyValue* pVal = getValue( it->second.maDependsOnName );
    1475             :                     OSL_ENSURE( pVal, "unknown property in dependency" );
    1476           0 :                     if( pVal )
    1477             :                     {
    1478           0 :                         sal_Int32 nDepVal = 0;
    1479           0 :                         sal_Bool bDepVal = sal_False;
    1480           0 :                         if( pVal->Value >>= nDepVal )
    1481             :                         {
    1482           0 :                             bEnabled = (nDepVal == it->second.mnDependsOnEntry) || (it->second.mnDependsOnEntry == -1);
    1483             :                         }
    1484           0 :                         else if( pVal->Value >>= bDepVal )
    1485             :                         {
    1486             :                             // could be a dependency on a checked boolean
    1487             :                             // in this case the dependency is on a non zero for checked value
    1488           0 :                             bEnabled = (   bDepVal && it->second.mnDependsOnEntry != 0) ||
    1489           0 :                                        ( ! bDepVal && it->second.mnDependsOnEntry == 0);
    1490             :                         }
    1491             :                         else
    1492             :                         {
    1493             :                             // if the type does not match something is awry
    1494             :                             OSL_FAIL( "strange type in control dependency" );
    1495           0 :                             bEnabled = false;
    1496             :                         }
    1497             :                     }
    1498             :                 }
    1499             :             }
    1500             :         }
    1501             :     }
    1502           0 :     return bEnabled;
    1503             : }
    1504             : 
    1505           0 : bool PrinterController::isUIChoiceEnabled( const rtl::OUString& i_rProperty, sal_Int32 i_nValue ) const
    1506             : {
    1507           0 :     bool bEnabled = true;
    1508             :     ImplPrinterControllerData::ChoiceDisableMap::const_iterator it =
    1509           0 :         mpImplData->maChoiceDisableMap.find( i_rProperty );
    1510           0 :     if(it != mpImplData->maChoiceDisableMap.end() )
    1511             :     {
    1512           0 :         const Sequence< sal_Bool >& rDisabled( it->second );
    1513           0 :         if( i_nValue >= 0 && i_nValue < rDisabled.getLength() )
    1514           0 :             bEnabled = ! rDisabled[i_nValue];
    1515             :     }
    1516           0 :     return bEnabled;
    1517             : }
    1518             : 
    1519           0 : rtl::OUString PrinterController::getDependency( const rtl::OUString& i_rProperty ) const
    1520             : {
    1521           0 :     rtl::OUString aDependency;
    1522             : 
    1523             :     vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
    1524           0 :         mpImplData->maControlDependencies.find( i_rProperty );
    1525           0 :     if( it != mpImplData->maControlDependencies.end() )
    1526           0 :         aDependency = it->second.maDependsOnName;
    1527             : 
    1528           0 :     return aDependency;
    1529             : }
    1530             : 
    1531           0 : rtl::OUString PrinterController::makeEnabled( const rtl::OUString& i_rProperty )
    1532             : {
    1533           0 :     rtl::OUString aDependency;
    1534             : 
    1535             :     vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
    1536           0 :         mpImplData->maControlDependencies.find( i_rProperty );
    1537           0 :     if( it != mpImplData->maControlDependencies.end() )
    1538             :     {
    1539           0 :         if( isUIOptionEnabled( it->second.maDependsOnName ) )
    1540             :         {
    1541           0 :            aDependency = it->second.maDependsOnName;
    1542           0 :            const com::sun::star::beans::PropertyValue* pVal = getValue( aDependency );
    1543             :            OSL_ENSURE( pVal, "unknown property in dependency" );
    1544           0 :            if( pVal )
    1545             :            {
    1546           0 :                sal_Int32 nDepVal = 0;
    1547           0 :                sal_Bool bDepVal = sal_False;
    1548           0 :                if( pVal->Value >>= nDepVal )
    1549             :                {
    1550           0 :                    if( it->second.mnDependsOnEntry != -1 )
    1551             :                    {
    1552           0 :                        setValue( aDependency, makeAny( sal_Int32( it->second.mnDependsOnEntry ) ) );
    1553             :                    }
    1554             :                }
    1555           0 :                else if( pVal->Value >>= bDepVal )
    1556             :                {
    1557           0 :                    setValue( aDependency, makeAny( sal_Bool( it->second.mnDependsOnEntry != 0 ) ) );
    1558             :                }
    1559             :                else
    1560             :                {
    1561             :                    // if the type does not match something is awry
    1562             :                    OSL_FAIL( "strange type in control dependency" );
    1563             :                }
    1564             :            }
    1565             :         }
    1566             :     }
    1567             : 
    1568           0 :     return aDependency;
    1569             : }
    1570             : 
    1571           0 : void PrinterController::setOptionChangeHdl( const Link& i_rHdl )
    1572             : {
    1573           0 :     mpImplData->maOptionChangeHdl = i_rHdl;
    1574           0 : }
    1575             : 
    1576           0 : void PrinterController::createProgressDialog()
    1577             : {
    1578           0 :     if( ! mpImplData->mpProgress )
    1579             :     {
    1580           0 :         sal_Bool bShow = sal_True;
    1581           0 :         beans::PropertyValue* pMonitor = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MonitorVisible" ) ) );
    1582           0 :         if( pMonitor )
    1583           0 :             pMonitor->Value >>= bShow;
    1584             :         else
    1585             :         {
    1586           0 :             const com::sun::star::beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ) );
    1587           0 :             if( pVal )
    1588             :             {
    1589           0 :                 sal_Bool bApi = sal_False;
    1590           0 :                 pVal->Value >>= bApi;
    1591           0 :                 bShow = ! bApi;
    1592             :             }
    1593             :         }
    1594             : 
    1595           0 :         if( bShow && ! Application::IsHeadlessModeEnabled() )
    1596             :         {
    1597           0 :             mpImplData->mpProgress = new PrintProgressDialog( NULL, getPageCountProtected() );
    1598           0 :             mpImplData->mpProgress->Show();
    1599             :         }
    1600             :     }
    1601             :     else
    1602           0 :         mpImplData->mpProgress->reset();
    1603           0 : }
    1604             : 
    1605           0 : bool PrinterController::isProgressCanceled() const
    1606             : {
    1607           0 :     return mpImplData->mpProgress && mpImplData->mpProgress->isCanceled();
    1608             : }
    1609             : 
    1610           0 : void PrinterController::setMultipage( const MultiPageSetup& i_rMPS )
    1611             : {
    1612           0 :     mpImplData->maMultiPage = i_rMPS;
    1613           0 : }
    1614             : 
    1615           0 : const PrinterController::MultiPageSetup& PrinterController::getMultipage() const
    1616             : {
    1617           0 :     return mpImplData->maMultiPage;
    1618             : }
    1619             : 
    1620           0 : void PrinterController::pushPropertiesToPrinter()
    1621             : {
    1622           0 :     sal_Int32 nCopyCount = 1;
    1623             :     // set copycount and collate
    1624           0 :     const beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) );
    1625           0 :     if( pVal )
    1626           0 :         pVal->Value >>= nCopyCount;
    1627           0 :     sal_Bool bCollate = sal_False;
    1628           0 :     pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) );
    1629           0 :     if( pVal )
    1630           0 :         pVal->Value >>= bCollate;
    1631           0 :     mpImplData->mpPrinter->SetCopyCount( static_cast<sal_uInt16>(nCopyCount), bCollate );
    1632             : 
    1633             :     // duplex mode
    1634           0 :     pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DuplexMode" ) ) );
    1635           0 :     if( pVal )
    1636             :     {
    1637           0 :         sal_Int16 nDuplex = view::DuplexMode::UNKNOWN;
    1638           0 :         pVal->Value >>= nDuplex;
    1639           0 :         switch( nDuplex )
    1640             :         {
    1641           0 :         case view::DuplexMode::OFF: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_OFF ); break;
    1642           0 :         case view::DuplexMode::LONGEDGE: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_LONGEDGE ); break;
    1643           0 :         case view::DuplexMode::SHORTEDGE: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_SHORTEDGE ); break;
    1644             :         }
    1645             :     }
    1646           0 : }
    1647             : 
    1648           0 : bool PrinterController::isShowDialogs() const
    1649             : {
    1650           0 :     sal_Bool bApi = getBoolProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ), sal_False );
    1651           0 :     return ! bApi && ! Application::IsHeadlessModeEnabled();
    1652             : }
    1653             : 
    1654           0 : bool PrinterController::isDirectPrint() const
    1655             : {
    1656           0 :     sal_Bool bDirect = getBoolProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ), sal_False );
    1657           0 :     return bDirect == sal_True;
    1658             : }
    1659             : 
    1660           0 : sal_Bool PrinterController::getBoolProperty( const rtl::OUString& i_rProperty, sal_Bool i_bFallback ) const
    1661             : {
    1662           0 :     sal_Bool bRet = i_bFallback;
    1663           0 :     const com::sun::star::beans::PropertyValue* pVal = getValue( i_rProperty );
    1664           0 :     if( pVal )
    1665           0 :         pVal->Value >>= bRet;
    1666           0 :     return bRet;
    1667             : }
    1668             : 
    1669           0 : sal_Int32 PrinterController::getIntProperty( const rtl::OUString& i_rProperty, sal_Int32 i_nFallback ) const
    1670             : {
    1671           0 :     sal_Int32 nRet = i_nFallback;
    1672           0 :     const com::sun::star::beans::PropertyValue* pVal = getValue( i_rProperty );
    1673           0 :     if( pVal )
    1674           0 :         pVal->Value >>= nRet;
    1675           0 :     return nRet;
    1676             : }
    1677             : 
    1678             : /*
    1679             :  * PrinterOptionsHelper
    1680             : **/
    1681           0 : Any PrinterOptionsHelper::getValue( const rtl::OUString& i_rPropertyName ) const
    1682             : {
    1683           0 :     Any aRet;
    1684             :     boost::unordered_map< rtl::OUString, Any, rtl::OUStringHash >::const_iterator it =
    1685           0 :         m_aPropertyMap.find( i_rPropertyName );
    1686           0 :     if( it != m_aPropertyMap.end() )
    1687           0 :         aRet = it->second;
    1688           0 :     return aRet;
    1689             : }
    1690             : 
    1691           0 : sal_Bool PrinterOptionsHelper::getBoolValue( const rtl::OUString& i_rPropertyName, sal_Bool i_bDefault ) const
    1692             : {
    1693           0 :     sal_Bool bRet = sal_False;
    1694           0 :     Any aVal( getValue( i_rPropertyName ) );
    1695           0 :     return (aVal >>= bRet) ? bRet : i_bDefault;
    1696             : }
    1697             : 
    1698           0 : sal_Int64 PrinterOptionsHelper::getIntValue( const rtl::OUString& i_rPropertyName, sal_Int64 i_nDefault ) const
    1699             : {
    1700           0 :     sal_Int64 nRet = 0;
    1701           0 :     Any aVal( getValue( i_rPropertyName ) );
    1702           0 :     return (aVal >>= nRet) ? nRet : i_nDefault;
    1703             : }
    1704             : 
    1705           0 : rtl::OUString PrinterOptionsHelper::getStringValue( const rtl::OUString& i_rPropertyName, const rtl::OUString& i_rDefault ) const
    1706             : {
    1707           0 :     rtl::OUString aRet;
    1708           0 :     Any aVal( getValue( i_rPropertyName ) );
    1709           0 :     return (aVal >>= aRet) ? aRet : i_rDefault;
    1710             : }
    1711             : 
    1712           0 : bool PrinterOptionsHelper::processProperties( const Sequence< PropertyValue >& i_rNewProp,
    1713             :                                               std::set< rtl::OUString >* o_pChangeProp )
    1714             : {
    1715           0 :     bool bChanged = false;
    1716             : 
    1717             :     // clear the changed set
    1718           0 :     if( o_pChangeProp )
    1719           0 :         o_pChangeProp->clear();
    1720             : 
    1721           0 :     sal_Int32 nElements = i_rNewProp.getLength();
    1722           0 :     const PropertyValue* pVals = i_rNewProp.getConstArray();
    1723           0 :     for( sal_Int32 i = 0; i < nElements; i++ )
    1724             :     {
    1725           0 :         bool bElementChanged = false;
    1726             :         boost::unordered_map< rtl::OUString, Any, rtl::OUStringHash >::iterator it =
    1727           0 :             m_aPropertyMap.find( pVals[ i ].Name );
    1728           0 :         if( it != m_aPropertyMap.end() )
    1729             :         {
    1730           0 :             if( it->second != pVals[ i ].Value )
    1731           0 :                 bElementChanged = true;
    1732             :         }
    1733             :         else
    1734           0 :             bElementChanged = true;
    1735             : 
    1736           0 :         if( bElementChanged )
    1737             :         {
    1738           0 :             if( o_pChangeProp )
    1739           0 :                 o_pChangeProp->insert( pVals[ i ].Name );
    1740           0 :             m_aPropertyMap[ pVals[i].Name ] = pVals[i].Value;
    1741           0 :             bChanged = true;
    1742             :         }
    1743             :     }
    1744           0 :     return bChanged;
    1745             : }
    1746             : 
    1747           0 : void PrinterOptionsHelper::appendPrintUIOptions( uno::Sequence< beans::PropertyValue >& io_rProps ) const
    1748             : {
    1749           0 :     if( m_aUIProperties.getLength() > 0 )
    1750             :     {
    1751           0 :         sal_Int32 nIndex = io_rProps.getLength();
    1752           0 :         io_rProps.realloc( nIndex+1 );
    1753           0 :         PropertyValue aVal;
    1754           0 :         aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExtraPrintUIOptions" ) );
    1755           0 :         aVal.Value = makeAny( m_aUIProperties );
    1756           0 :         io_rProps[ nIndex ] = aVal;
    1757             :     }
    1758           0 : }
    1759             : 
    1760           0 : Any PrinterOptionsHelper::setUIControlOpt(const com::sun::star::uno::Sequence< rtl::OUString >& i_rIDs,
    1761             :                                           const rtl::OUString& i_rTitle,
    1762             :                                           const Sequence< rtl::OUString >& i_rHelpIds,
    1763             :                                           const rtl::OUString& i_rType,
    1764             :                                           const PropertyValue* i_pVal,
    1765             :                                           const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1766             : {
    1767             :     sal_Int32 nElements =
    1768             :         2                                                             // ControlType + ID
    1769           0 :         + (i_rTitle.isEmpty() ? 0 : 1)                                // Text
    1770           0 :         + (i_rHelpIds.getLength() ? 1 : 0)                            // HelpId
    1771             :         + (i_pVal ? 1 : 0)                                            // Property
    1772           0 :         + i_rControlOptions.maAddProps.getLength()                    // additional props
    1773           0 :         + (i_rControlOptions.maGroupHint.isEmpty() ? 0 : 1)           // grouping
    1774             :         + (i_rControlOptions.mbInternalOnly ? 1 : 0)                  // internal hint
    1775           0 :         + (i_rControlOptions.mbEnabled ? 0 : 1)                       // enabled
    1776             :         ;
    1777           0 :     if( !i_rControlOptions.maDependsOnName.isEmpty() )
    1778             :     {
    1779           0 :         nElements += 1;
    1780           0 :         if( i_rControlOptions.mnDependsOnEntry != -1 )
    1781           0 :             nElements += 1;
    1782           0 :         if( i_rControlOptions.mbAttachToDependency )
    1783           0 :             nElements += 1;
    1784             :     }
    1785             : 
    1786           0 :     Sequence< PropertyValue > aCtrl( nElements );
    1787           0 :     sal_Int32 nUsed = 0;
    1788           0 :     if( !i_rTitle.isEmpty() )
    1789             :     {
    1790           0 :         aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) );
    1791           0 :         aCtrl[nUsed++].Value = makeAny( i_rTitle );
    1792             :     }
    1793           0 :     if( i_rHelpIds.getLength() )
    1794             :     {
    1795           0 :         aCtrl[nUsed  ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpId" ) );
    1796           0 :         aCtrl[nUsed++].Value = makeAny( i_rHelpIds );
    1797             :     }
    1798           0 :     aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlType" ) );
    1799           0 :     aCtrl[nUsed++].Value = makeAny( i_rType );
    1800           0 :     aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ID" ) );
    1801           0 :     aCtrl[nUsed++].Value = makeAny( i_rIDs );
    1802           0 :     if( i_pVal )
    1803             :     {
    1804           0 :         aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Property" ) );
    1805           0 :         aCtrl[nUsed++].Value = makeAny( *i_pVal );
    1806             :     }
    1807           0 :     if( !i_rControlOptions.maDependsOnName.isEmpty() )
    1808             :     {
    1809           0 :         aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DependsOnName" ) );
    1810           0 :         aCtrl[nUsed++].Value = makeAny( i_rControlOptions.maDependsOnName );
    1811           0 :         if( i_rControlOptions.mnDependsOnEntry != -1 )
    1812             :         {
    1813           0 :             aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DependsOnEntry" ) );
    1814           0 :             aCtrl[nUsed++].Value = makeAny( i_rControlOptions.mnDependsOnEntry );
    1815             :         }
    1816           0 :         if( i_rControlOptions.mbAttachToDependency )
    1817             :         {
    1818           0 :             aCtrl[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AttachToDependency" ) );
    1819           0 :             aCtrl[nUsed++].Value = makeAny( i_rControlOptions.mbAttachToDependency );
    1820             :         }
    1821             :     }
    1822           0 :     if( !i_rControlOptions.maGroupHint.isEmpty() )
    1823             :     {
    1824           0 :         aCtrl[nUsed  ].Name    = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GroupingHint" ) );
    1825           0 :         aCtrl[nUsed++].Value <<= i_rControlOptions.maGroupHint;
    1826             :     }
    1827           0 :     if( i_rControlOptions.mbInternalOnly )
    1828             :     {
    1829           0 :         aCtrl[nUsed  ].Name    = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InternalUIOnly" ) );
    1830           0 :         aCtrl[nUsed++].Value <<= sal_True;
    1831             :     }
    1832           0 :     if( ! i_rControlOptions.mbEnabled )
    1833             :     {
    1834           0 :         aCtrl[nUsed  ].Name    = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enabled" ) );
    1835           0 :         aCtrl[nUsed++].Value <<= sal_False;
    1836             :     }
    1837             : 
    1838           0 :     sal_Int32 nAddProps = i_rControlOptions.maAddProps.getLength();
    1839           0 :     for( sal_Int32 i = 0; i < nAddProps; i++ )
    1840           0 :         aCtrl[ nUsed++ ] = i_rControlOptions.maAddProps[i];
    1841             : 
    1842             :     DBG_ASSERT( nUsed == nElements, "nUsed != nElements, probable heap corruption" );
    1843             : 
    1844           0 :     return makeAny( aCtrl );
    1845             : }
    1846             : 
    1847           0 : Any PrinterOptionsHelper::setGroupControlOpt(const rtl::OUString& i_rID,
    1848             :                                              const rtl::OUString& i_rTitle,
    1849             :                                              const rtl::OUString& i_rHelpId)
    1850             : {
    1851           0 :     Sequence< rtl::OUString > aHelpId;
    1852           0 :     if( !i_rHelpId.isEmpty() )
    1853             :     {
    1854           0 :         aHelpId.realloc( 1 );
    1855           0 :         *aHelpId.getArray() = i_rHelpId;
    1856             :     }
    1857           0 :     Sequence< rtl::OUString > aIds(1);
    1858           0 :     aIds[0] = i_rID;
    1859           0 :     return setUIControlOpt(aIds, i_rTitle, aHelpId, "Group");
    1860             : }
    1861             : 
    1862           0 : Any PrinterOptionsHelper::setSubgroupControlOpt(const rtl::OUString& i_rID,
    1863             :                                                 const rtl::OUString& i_rTitle,
    1864             :                                                 const rtl::OUString& i_rHelpId,
    1865             :                                                 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1866             : {
    1867           0 :     Sequence< rtl::OUString > aHelpId;
    1868           0 :     if( !i_rHelpId.isEmpty() )
    1869             :     {
    1870           0 :         aHelpId.realloc( 1 );
    1871           0 :         *aHelpId.getArray() = i_rHelpId;
    1872             :     }
    1873           0 :     Sequence< rtl::OUString > aIds(1);
    1874           0 :     aIds[0] = i_rID;
    1875           0 :     return setUIControlOpt(aIds, i_rTitle, aHelpId, "Subgroup", NULL, i_rControlOptions);
    1876             : }
    1877             : 
    1878           0 : Any PrinterOptionsHelper::setBoolControlOpt(const rtl::OUString& i_rID,
    1879             :                                             const rtl::OUString& i_rTitle,
    1880             :                                             const rtl::OUString& i_rHelpId,
    1881             :                                             const rtl::OUString& i_rProperty,
    1882             :                                             sal_Bool i_bValue,
    1883             :                                             const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1884             : {
    1885           0 :     Sequence< rtl::OUString > aHelpId;
    1886           0 :     if( !i_rHelpId.isEmpty() )
    1887             :     {
    1888           0 :         aHelpId.realloc( 1 );
    1889           0 :         *aHelpId.getArray() = i_rHelpId;
    1890             :     }
    1891           0 :     PropertyValue aVal;
    1892           0 :     aVal.Name = i_rProperty;
    1893           0 :     aVal.Value = makeAny( i_bValue );
    1894           0 :     Sequence< rtl::OUString > aIds(1);
    1895           0 :     aIds[0] = i_rID;
    1896           0 :     return setUIControlOpt(aIds, i_rTitle, aHelpId, "Bool", &aVal, i_rControlOptions);
    1897             : }
    1898             : 
    1899           0 : Any PrinterOptionsHelper::setChoiceRadiosControlOpt(const com::sun::star::uno::Sequence< rtl::OUString >& i_rIDs,
    1900             :                                               const rtl::OUString& i_rTitle,
    1901             :                                               const Sequence< rtl::OUString >& i_rHelpId,
    1902             :                                               const rtl::OUString& i_rProperty,
    1903             :                                               const Sequence< rtl::OUString >& i_rChoices,
    1904             :                                               sal_Int32 i_nValue,
    1905             :                                               const Sequence< sal_Bool >& i_rDisabledChoices,
    1906             :                                               const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1907             : {
    1908           0 :     UIControlOptions aOpt( i_rControlOptions );
    1909           0 :     sal_Int32 nUsed = aOpt.maAddProps.getLength();
    1910           0 :     aOpt.maAddProps.realloc( nUsed + 1 + (i_rDisabledChoices.getLength() ? 1 : 0) );
    1911           0 :     aOpt.maAddProps[nUsed].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Choices" ) );
    1912           0 :     aOpt.maAddProps[nUsed].Value = makeAny( i_rChoices );
    1913           0 :     if( i_rDisabledChoices.getLength() )
    1914             :     {
    1915           0 :         aOpt.maAddProps[nUsed+1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChoicesDisabled" ) );
    1916           0 :         aOpt.maAddProps[nUsed+1].Value = makeAny( i_rDisabledChoices );
    1917             :     }
    1918             : 
    1919           0 :     PropertyValue aVal;
    1920           0 :     aVal.Name = i_rProperty;
    1921           0 :     aVal.Value = makeAny( i_nValue );
    1922           0 :     return setUIControlOpt(i_rIDs, i_rTitle, i_rHelpId, "Radio", &aVal, aOpt);
    1923             : }
    1924             : 
    1925           0 : Any PrinterOptionsHelper::setChoiceListControlOpt(const rtl::OUString& i_rID,
    1926             :                                               const rtl::OUString& i_rTitle,
    1927             :                                               const Sequence< rtl::OUString >& i_rHelpId,
    1928             :                                               const rtl::OUString& i_rProperty,
    1929             :                                               const Sequence< rtl::OUString >& i_rChoices,
    1930             :                                               sal_Int32 i_nValue,
    1931             :                                               const Sequence< sal_Bool >& i_rDisabledChoices,
    1932             :                                               const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1933             : {
    1934           0 :     UIControlOptions aOpt( i_rControlOptions );
    1935           0 :     sal_Int32 nUsed = aOpt.maAddProps.getLength();
    1936           0 :     aOpt.maAddProps.realloc( nUsed + 1 + (i_rDisabledChoices.getLength() ? 1 : 0) );
    1937           0 :     aOpt.maAddProps[nUsed].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Choices" ) );
    1938           0 :     aOpt.maAddProps[nUsed].Value = makeAny( i_rChoices );
    1939           0 :     if( i_rDisabledChoices.getLength() )
    1940             :     {
    1941           0 :         aOpt.maAddProps[nUsed+1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChoicesDisabled" ) );
    1942           0 :         aOpt.maAddProps[nUsed+1].Value = makeAny( i_rDisabledChoices );
    1943             :     }
    1944             : 
    1945           0 :     PropertyValue aVal;
    1946           0 :     aVal.Name = i_rProperty;
    1947           0 :     aVal.Value = makeAny( i_nValue );
    1948           0 :     Sequence< rtl::OUString > aIds(1);
    1949           0 :     aIds[0] = i_rID;
    1950           0 :     return setUIControlOpt(aIds, i_rTitle, i_rHelpId, "List", &aVal, aOpt);
    1951             : }
    1952             : 
    1953           0 : Any PrinterOptionsHelper::setRangeControlOpt(const rtl::OUString& i_rID,
    1954             :                                              const rtl::OUString& i_rTitle,
    1955             :                                              const rtl::OUString& i_rHelpId,
    1956             :                                              const rtl::OUString& i_rProperty,
    1957             :                                              sal_Int32 i_nValue,
    1958             :                                              sal_Int32 i_nMinValue,
    1959             :                                              sal_Int32 i_nMaxValue,
    1960             :                                              const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1961             : {
    1962           0 :     UIControlOptions aOpt( i_rControlOptions );
    1963           0 :     if( i_nMaxValue >= i_nMinValue )
    1964             :     {
    1965           0 :         sal_Int32 nUsed = aOpt.maAddProps.getLength();
    1966           0 :         aOpt.maAddProps.realloc( nUsed + 2 );
    1967           0 :         aOpt.maAddProps[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MinValue" ) );
    1968           0 :         aOpt.maAddProps[nUsed++].Value = makeAny( i_nMinValue );
    1969           0 :         aOpt.maAddProps[nUsed  ].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxValue" ) );
    1970           0 :         aOpt.maAddProps[nUsed++].Value = makeAny( i_nMaxValue );
    1971             :     }
    1972             : 
    1973           0 :     Sequence< rtl::OUString > aHelpId;
    1974           0 :     if( !i_rHelpId.isEmpty() )
    1975             :     {
    1976           0 :         aHelpId.realloc( 1 );
    1977           0 :         *aHelpId.getArray() = i_rHelpId;
    1978             :     }
    1979           0 :     PropertyValue aVal;
    1980           0 :     aVal.Name = i_rProperty;
    1981           0 :     aVal.Value = makeAny( i_nValue );
    1982           0 :     Sequence< rtl::OUString > aIds(1);
    1983           0 :     aIds[0] = i_rID;
    1984           0 :     return setUIControlOpt(aIds, i_rTitle, aHelpId, "Range", &aVal, aOpt);
    1985             : }
    1986             : 
    1987           0 : Any PrinterOptionsHelper::setEditControlOpt(const rtl::OUString& i_rID,
    1988             :                                             const rtl::OUString& i_rTitle,
    1989             :                                             const rtl::OUString& i_rHelpId,
    1990             :                                             const rtl::OUString& i_rProperty,
    1991             :                                             const rtl::OUString& i_rValue,
    1992             :                                             const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
    1993             : {
    1994           0 :     Sequence< rtl::OUString > aHelpId;
    1995           0 :     if( !i_rHelpId.isEmpty() )
    1996             :     {
    1997           0 :         aHelpId.realloc( 1 );
    1998           0 :         *aHelpId.getArray() = i_rHelpId;
    1999             :     }
    2000           0 :     PropertyValue aVal;
    2001           0 :     aVal.Name = i_rProperty;
    2002           0 :     aVal.Value = makeAny( i_rValue );
    2003           0 :     Sequence< rtl::OUString > aIds(1);
    2004           0 :     aIds[0] = i_rID;
    2005           0 :     return setUIControlOpt(aIds, i_rTitle, aHelpId, "Edit", &aVal, i_rControlOptions);
    2006             : }
    2007             : 
    2008             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10