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