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