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