1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 
28 #include "DocumentRenderer.hxx"
29 #include "DocumentRenderer.hrc"
30 
31 #include "drawdoc.hxx"
32 #include "optsitem.hxx"
33 #include "sdresid.hxx"
34 #include "strings.hrc"
35 #include "sdattr.hxx"
36 #include "Window.hxx"
37 #include "drawview.hxx"
38 #include "DrawViewShell.hxx"
39 #include "FrameView.hxx"
40 #include "Outliner.hxx"
41 #include "OutlineViewShell.hxx"
42 
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/polygon/b2dpolypolygon.hxx>
45 #include <basegfx/matrix/b2dhommatrix.hxx>
46 #include <sfx2/printer.hxx>
47 #include <editeng/editstat.hxx>
48 #include <editeng/outlobj.hxx>
49 #include <svx/svdetc.hxx>
50 #include <svx/svditer.hxx>
51 #include <svx/svdopage.hxx>
52 #include <svx/svdopath.hxx>
53 #include <svx/xlnclit.hxx>
54 #include <toolkit/awt/vclxdevice.hxx>
55 #include <tools/resary.hxx>
56 #include <unotools/localedatawrapper.hxx>
57 #include <vcl/msgbox.hxx>
58 #include <unotools/moduleoptions.hxx>
59 
60 #include <vector>
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
64 using ::rtl::OUString;
65 
66 
67 namespace sd {
68 
69 namespace {
70     OUString A2S (const char* pString)
71     {
72         return OUString::createFromAscii(pString);
73     }
74 
75 
76 
77     /** Convenience class to extract values from the sequence of properties
78         given to one of the XRenderable methods.
79     */
80     class PrintOptions
81     {
82     public:
83         PrintOptions (
84             const vcl::PrinterOptionsHelper& rHelper,
85             const ::std::vector<sal_Int32>& rSlidesPerPage)
86             : mrProperties(rHelper),
87               maSlidesPerPage(rSlidesPerPage)
88         {
89         }
90 
91         bool IsWarningOrientation (void) const
92         {
93             return GetBoolValue(NULL, true);
94         }
95 
96         bool IsPrintPageName (void) const
97         {
98             return GetBoolValue("IsPrintName");
99         }
100 
101         bool IsDate (void) const
102         {
103             return GetBoolValue("IsPrintDateTime");
104         }
105 
106         bool IsTime (void) const
107         {
108             return GetBoolValue("IsPrintDateTime");
109         }
110 
111         bool IsHiddenPages (void) const
112         {
113             return GetBoolValue("IsPrintHidden");
114         }
115 
116         bool IsHandoutHorizontal (void) const
117         {
118             return GetBoolValue("SlidesPerPageOrder", sal_Int32(0), true);
119         }
120 
121         sal_Int32 GetHandoutPageCount (void) const
122         {
123             sal_uInt32 nIndex = static_cast<sal_Int32>(mrProperties.getIntValue("SlidesPerPage", sal_Int32(0)));
124             if (nIndex<maSlidesPerPage.size())
125                 return maSlidesPerPage[nIndex];
126             else if ( ! maSlidesPerPage.empty())
127                 return maSlidesPerPage[0];
128             else
129                 return 0;
130         }
131 
132         bool IsDraw (void) const
133         {
134             return GetBoolValue("PageContentType", sal_Int32(0));
135         }
136 
137         bool IsHandout (void) const
138         {
139             return GetBoolValue("PageContentType", sal_Int32(1));
140         }
141 
142         bool IsNotes (void) const
143         {
144             return GetBoolValue("PageContentType", sal_Int32(2));
145         }
146 
147         bool IsOutline (void) const
148         {
149             return GetBoolValue("PageContentType", sal_Int32(3));
150         }
151 
152         sal_uLong GetOutputQuality (void) const
153         {
154             sal_Int32 nQuality = static_cast<sal_Int32>(mrProperties.getIntValue( "Quality", sal_Int32(0) ));
155             return nQuality;
156         }
157 
158         bool IsPageSize (void) const
159         {
160             return GetBoolValue("PageOptions", sal_Int32(1));
161         }
162 
163         bool IsTilePage (void) const
164         {
165             return GetBoolValue("PageOptions", sal_Int32(2)) || GetBoolValue("PageOptions", sal_Int32(3));
166         }
167 
168         bool IsCutPage (void) const
169         {
170             return GetBoolValue("PageOptions", sal_Int32(0));
171         }
172 
173         bool IsBooklet (void) const
174         {
175             return GetBoolValue("PrintProspect", false);
176         }
177 
178         bool IsPrintExcluded (void) const
179         {
180             return (IsNotes() || IsDraw() || IsHandout()) &&  IsHiddenPages();
181         }
182 
183         bool IsPrintFrontPage (void) const
184         {
185             sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
186             return nInclude == 0 || nInclude == 1;
187         }
188 
189         bool IsPrintBackPage (void) const
190         {
191             sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
192             return nInclude == 0 || nInclude == 2;
193         }
194 
195         bool IsPaperBin (void) const
196         {
197             return GetBoolValue("PrintPaperFromSetup", false);
198         }
199 
200         OUString GetPrinterSelection (void) const
201         {
202             sal_Int32 nContent = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintContent", 0 ));
203             OUString sValue( A2S("all") );
204             if( nContent == 1 )
205                 sValue = mrProperties.getStringValue( "PageRange", A2S( "all" ) );
206             else if( nContent == 2 )
207                 sValue = A2S( "selection" );
208             return sValue;
209         }
210 
211     private:
212         const vcl::PrinterOptionsHelper& mrProperties;
213         const ::std::vector<sal_Int32> maSlidesPerPage;
214 
215         /** When the value of the property with name pName is a boolean then
216             return its value. When the property is unknown then
217             bDefaultValue is returned.  Otherwise <FALSE/> is returned.
218         */
219         bool GetBoolValue (
220             const sal_Char* pName,
221             const bool bDefaultValue = false) const
222         {
223             sal_Bool bValue = mrProperties.getBoolValue( pName, bDefaultValue );
224             return bValue;
225         }
226 
227         /** Return <TRUE/> when the value of the property with name pName is
228             a string and its value equals pValue. When the property is
229             unknown then bDefaultValue is returned.  Otherwise <FALSE/> is
230             returned.
231         */
232         bool GetBoolValue (
233             const sal_Char* pName,
234             const sal_Char* pValue,
235             const bool bDefaultValue = false) const
236         {
237             OUString sValue( mrProperties.getStringValue( pName ) );
238             if (sValue.getLength())
239                 return sValue.equalsAscii(pValue);
240             else
241                 return bDefaultValue;
242         }
243 
244         /** Return <TRUE/> when the value of the property with name pName is
245             an integer and its value is nTriggerValue. Otherwise <FALSE/> is
246             returned.
247         */
248         bool GetBoolValue (
249             const sal_Char* pName,
250             const sal_Int32 nTriggerValue) const
251         {
252             sal_Int32 nValue = static_cast<sal_Int32>(mrProperties.getIntValue( pName ));
253             return nValue == nTriggerValue;
254         }
255     };
256 
257 
258 
259     /** This class is like MultiSelection but understands two special values.
260         "all" indicates that all pages are selected.  "selection" indicates that no
261         pages but a set of shapes is selected.
262     */
263     class Selection
264     {
265     public:
266         Selection (const OUString& rsSelection, const SdPage* pCurrentPage)
267             : mbAreAllPagesSelected(rsSelection.equalsAscii("all")),
268               mbIsShapeSelection(rsSelection.equalsAscii("selection")),
269               mnCurrentPageIndex(pCurrentPage!=NULL ? (pCurrentPage->GetPageNum()-1)/2 : -1),
270               mpSelectedPages()
271         {
272             if ( ! (mbAreAllPagesSelected || mbIsShapeSelection))
273                 mpSelectedPages.reset(new MultiSelection(rsSelection));
274         }
275 
276         bool IsMarkedOnly (void) const
277         {
278             return mbIsShapeSelection;
279         }
280 
281         /** Call with a 0 based page index.
282         */
283         bool IsSelected (const sal_Int32 nIndex) const
284         {
285             if (mbAreAllPagesSelected)
286                 return true;
287             else if (mpSelectedPages)
288                 return mpSelectedPages->IsSelected(nIndex+1);
289             else if (mbIsShapeSelection && nIndex==mnCurrentPageIndex)
290                 return true;
291             else
292                 return false;
293         }
294 
295     private:
296         const bool mbAreAllPagesSelected;
297         const bool mbIsShapeSelection;
298         const sal_Int32 mnCurrentPageIndex;
299         ::boost::scoped_ptr<MultiSelection> mpSelectedPages;
300     };
301 
302     /** A collection of values that helps to reduce the number of arguments
303         given to some functions.  Note that not all values are set at the
304         same time.
305     */
306     class PrintInfo
307     {
308     public:
309         PrintInfo (
310             const Printer* pPrinter,
311             const OUString& rsPrinterSelection,
312             const ::boost::shared_ptr<ViewShell> pView)
313             : mpPrinter(pPrinter),
314               mnDrawMode(DRAWMODE_DEFAULT),
315               msTimeDate(),
316               msPageString(),
317               maPrintSize(0,0),
318               maPageSize(0,0),
319               meOrientation(ORIENTATION_PORTRAIT),
320               maMap(),
321               maSelection(rsPrinterSelection, pView ? pView->getCurrentPage() : NULL),
322               mbPrintMarkedOnly(maSelection.IsMarkedOnly())
323         {}
324 
325         const Printer* mpPrinter;
326         sal_uLong mnDrawMode;
327         ::rtl::OUString msTimeDate;
328         ::rtl::OUString msPageString;
329         Size maPrintSize;
330         Size maPageSize;
331         Orientation meOrientation;
332         MapMode maMap;
333         const Selection maSelection;
334         bool mbPrintMarkedOnly;
335     };
336 
337 
338 
339     /** Output one page of the document to the given printer.  Note that
340         more than one document page may be output to one printer page.
341     */
342     void PrintPage (
343         Printer& rPrinter,
344         ::sd::View& rPrintView,
345         SdPage& rPage,
346         View* pView,
347         const bool bPrintMarkedOnly,
348         const SetOfByte& rVisibleLayers,
349         const SetOfByte& rPrintableLayers)
350     {
351         rPrintView.ShowSdrPage(&rPage);
352 
353         const MapMode aOriginalMapMode (rPrinter.GetMapMode());
354 
355         // Set the visible layers
356         SdrPageView* pPageView = rPrintView.GetSdrPageView();
357         OSL_ASSERT(pPageView!=NULL);
358         pPageView->SetVisibleLayers(rVisibleLayers);
359         pPageView->SetPrintableLayers(rPrintableLayers);
360 
361         if (pView!=NULL && bPrintMarkedOnly)
362             pView->DrawMarkedObj(rPrinter);
363         else
364             rPrintView.CompleteRedraw(&rPrinter, Rectangle(Point(0,0), rPage.GetSize()));
365 
366         rPrinter.SetMapMode(aOriginalMapMode);
367 
368         rPrintView.HideSdrPage();
369     }
370 
371 
372 
373 
374     /** Output a string (that typically is not part of a document page) to
375         the given printer.
376     */
377     void PrintMessage (
378         Printer& rPrinter,
379         const ::rtl::OUString& rsPageString,
380         const Point& rPageStringOffset)
381     {
382         const Font aOriginalFont (rPrinter.OutputDevice::GetFont());
383         rPrinter.SetFont(Font(FAMILY_SWISS, Size(0, 423)));
384         rPrinter.DrawText(rPageStringOffset, rsPageString);
385         rPrinter.SetFont(aOriginalFont);
386     }
387 
388 
389 
390 
391     /** Read the resource file and process it into a sequence of properties
392         that can be passed to the printing dialog.
393     */
394     class DialogCreator : Resource
395     {
396     public:
397         DialogCreator (bool bImpress)
398             : Resource(SdResId(_STR_IMPRESS_PRINT_UI_OPTIONS))
399             , mbImpress(bImpress)
400         {
401             ProcessResource();
402         }
403 
404         Sequence< beans::PropertyValue > GetDialogControls(void) const
405         {
406             if (maProperties.empty())
407                 return Sequence< beans::PropertyValue >();
408             else
409             {
410                 return Sequence<beans::PropertyValue>(
411                         &maProperties.front(),
412                         maProperties.size());
413             }
414         }
415 
416         ::std::vector<sal_Int32> GetSlidesPerPage (void) const
417         {
418             return maSlidesPerPage;
419         }
420 
421     private:
422         Any maDialog;
423         ::std::vector<beans::PropertyValue> maProperties;
424         ::std::vector<sal_Int32> maSlidesPerPage;
425         bool mbImpress;
426 
427         void ProcessResource (void)
428         {
429             SvtModuleOptions aOpt;
430             String aAppGroupname( String( SdResId( _STR_IMPRESS_PRINT_UI_GROUP_NAME ) ) );
431             aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
432                                            aOpt.GetModuleName( mbImpress ? SvtModuleOptions::E_SIMPRESS : SvtModuleOptions::E_SDRAW ) );
433             AddDialogControl( vcl::PrinterOptionsHelper::getGroupControlOpt(
434                                 aAppGroupname,
435                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:TabPage:AppPage" ) )
436                                 ) );
437 
438             uno::Sequence< rtl::OUString > aHelpIds;
439             if( mbImpress )
440             {
441                 vcl::PrinterOptionsHelper::UIControlOptions aPrintOpt;
442                 aPrintOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "JobPage" ) );
443                 AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
444                                     String( SdResId(_STR_IMPRESS_PRINT_UI_PRINT_GROUP) ),
445                                     rtl::OUString(),
446                                     aPrintOpt )
447                                     );
448 
449                 aHelpIds.realloc( 1 );
450                 aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageContentType:ListBox" ) );
451                 AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
452                                     String( SdResId( _STR_IMPRESS_PRINT_UI_CONTENT ) ),
453                                     aHelpIds,
454                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "PageContentType" ) ),
455                                     CreateChoice(_STR_IMPRESS_PRINT_UI_CONTENT_CHOICES),
456                                     0,
457                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) )
458                                     )
459                                 );
460 
461                 aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:SlidesPerPage:ListBox" ) );
462                 vcl::PrinterOptionsHelper::UIControlOptions
463                     aContentOpt( OUString( RTL_CONSTASCII_USTRINGPARAM( "PageContentType" ) ), 1 );
464                 AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
465                                     String( SdResId( _STR_IMPRESS_PRINT_UI_SLIDESPERPAGE ) ),
466                                     aHelpIds,
467                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "SlidesPerPage" ) ),
468                                     GetSlidesPerPageSequence(),
469                                     0,
470                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) ),
471                                     Sequence< sal_Bool >(),
472                                     aContentOpt
473                                     )
474                                 );
475 
476                 aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:SlidesPerPageOrder:ListBox" ) );
477                 vcl::PrinterOptionsHelper::UIControlOptions
478                     aSlidesPerPageOpt( OUString( RTL_CONSTASCII_USTRINGPARAM( "SlidesPerPage" ) ), -1, sal_True );
479                 AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
480                                     String( SdResId( _STR_IMPRESS_PRINT_UI_ORDER ) ),
481                                     aHelpIds,
482                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "SlidesPerPageOrder" ) ),
483                                     CreateChoice(_STR_IMPRESS_PRINT_UI_ORDER_CHOICES),
484                                     0,
485                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) ),
486                                     Sequence< sal_Bool >(),
487                                     aSlidesPerPageOpt )
488                                 );
489             }
490 
491             AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
492                                String( SdResId(_STR_IMPRESS_PRINT_UI_INCLUDE_CONTENT) ), rtl::OUString() ) );
493 
494 
495             if( mbImpress )
496             {
497                 AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
498                                     String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_NAME) ),
499                                     OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ) ),
500                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrintName" ) ),
501                                     sal_False
502                                     )
503                                 );
504             }
505             else
506             {
507                 AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
508                                     String( SdResId(_STR_DRAW_PRINT_UI_IS_PRINT_NAME) ),
509                                     OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ) ),
510                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrintName" ) ),
511                                     sal_False
512                                     )
513                                 );
514             }
515 
516             AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
517                                 String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_DATE) ),
518                                 OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsPrintDateTime:CheckBox" ) ),
519                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrintDateTime" ) ),
520                                 sal_False
521                                 )
522                             );
523 
524             if( mbImpress )
525             {
526                 AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
527                                     String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_HIDDEN) ),
528                                     OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsPrintHidden:CheckBox" ) ),
529                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrintHidden" ) ),
530                                     sal_False
531                                     )
532                                 );
533             }
534 
535             AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
536                                String( SdResId(_STR_IMPRESS_PRINT_UI_QUALITY) ), rtl::OUString() ) );
537 
538             aHelpIds.realloc( 3 );
539             aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:Quality:RadioButton:0" ) );
540             aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:Quality:RadioButton:1" ) );
541             aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:Quality:RadioButton:2" ) );
542             AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
543                                 rtl::OUString(),
544                                 aHelpIds,
545                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ),
546                                 CreateChoice(_STR_IMPRESS_PRINT_UI_QUALITY_CHOICES),
547                                 0
548                                 )
549                             );
550 
551             AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
552                                String( SdResId(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS) ), rtl::OUString() ) );
553 
554             aHelpIds.realloc( 4 );
555             aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:0" ) );
556             aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:1" ) );
557             aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:2" ) );
558             aHelpIds[3] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:3" ) );
559             if( mbImpress )
560             {
561                 // FIXME: additional dependency on PrintProspect = false
562                 vcl::PrinterOptionsHelper::UIControlOptions
563                     aPageOptionsOpt( OUString( RTL_CONSTASCII_USTRINGPARAM( "PageContentType" ) ), 0 );
564                 AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
565                                     rtl::OUString(),
566                                     aHelpIds,
567                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "PageOptions" ) ),
568                                     CreateChoice(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES),
569                                     0,
570                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "Radio" ) ),
571                                     Sequence< sal_Bool >(),
572                                     aPageOptionsOpt
573                                     )
574                                 );
575             }
576             else
577             {
578                 vcl::PrinterOptionsHelper::UIControlOptions
579                     aPageOptionsOpt( OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintProspect" ) ), sal_False );
580                 AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
581                                     rtl::OUString(),
582                                     aHelpIds,
583                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "PageOptions" ) ),
584                                     CreateChoice(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES_DRAW),
585                                     0,
586                                     OUString( RTL_CONSTASCII_USTRINGPARAM( "Radio" ) ),
587                                     Sequence< sal_Bool >(),
588                                     aPageOptionsOpt
589                                     )
590                                 );
591             }
592 
593             vcl::PrinterOptionsHelper::UIControlOptions aBrochureOpt;
594             aBrochureOpt.maGroupHint = OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutPage" ) );
595             AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
596                                String( SdResId(_STR_IMPRESS_PRINT_UI_PAGE_SIDES) ), rtl::OUString(),
597                                aBrochureOpt ) );
598 
599             // brochure printing
600             AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
601                                 String( SdResId(_STR_IMPRESS_PRINT_UI_BROCHURE) ),
602                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintProspect:CheckBox" ) ),
603                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintProspect" ) ),
604                                 sal_False,
605                                 aBrochureOpt
606                                 )
607                             );
608 
609             vcl::PrinterOptionsHelper::UIControlOptions
610                 aIncludeOpt( OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintProspect" ) ), -1, sal_False );
611             aIncludeOpt.maGroupHint = OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutPage" ) );
612             aHelpIds.realloc( 1 );
613             aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintProspectInclude:ListBox" ) );
614             AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt(
615                                 String( SdResId(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE) ),
616                                 aHelpIds,
617                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintProspectInclude" ) ),
618                                 CreateChoice(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE_LIST),
619                                 0,
620                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) ),
621                                 Sequence< sal_Bool >(),
622                                 aIncludeOpt
623                                 )
624                             );
625 
626             // paper tray (on options page)
627             vcl::PrinterOptionsHelper::UIControlOptions aPaperTrayOpt;
628             aPaperTrayOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OptionsPageOptGroup" ) );
629             AddDialogControl( vcl::PrinterOptionsHelper::getBoolControlOpt(
630                                 String( SdResId(_STR_IMPRESS_PRINT_UI_PAPER_TRAY) ),
631                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintPaperFromSetup:CheckBox" ) ),
632                                 OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintPaperFromSetup" ) ),
633                                 sal_False,
634                                 aPaperTrayOpt
635                                 )
636                             );
637             // print range selection
638             vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
639             aPrintRangeOpt.mbInternalOnly = sal_True;
640             aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
641             AddDialogControl( vcl::PrinterOptionsHelper::getSubgroupControlOpt(
642                                 String( SdResId( _STR_IMPRESS_PRINT_UI_PAGE_RANGE ) ),
643                                 rtl::OUString(),
644                                 aPrintRangeOpt )
645                              );
646 
647             // create a choice for the content to create
648             rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) );
649             aHelpIds.realloc( 3 );
650             aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ) );
651             aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ) );
652             aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2" ) );
653             AddDialogControl( vcl::PrinterOptionsHelper::getChoiceControlOpt( rtl::OUString(),
654                                 aHelpIds,
655                                 aPrintRangeName,
656                                 CreateChoice(mbImpress
657                                              ? _STR_IMPRESS_PRINT_UI_PAGE_RANGE_CHOICE
658                                              : _STR_DRAW_PRINT_UI_PAGE_RANGE_CHOICE),
659                                 0 )
660                             );
661             // create a an Edit dependent on "Pages" selected
662             vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
663             AddDialogControl( vcl::PrinterOptionsHelper::getEditControlOpt( rtl::OUString(),
664                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageRange:Edit" ) ),
665                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
666                                 rtl::OUString(),
667                                 aPageRangeOpt )
668                             );
669 
670             FreeResource();
671         }
672 
673         void AddDialogControl( const Any& i_rCtrl )
674         {
675             beans::PropertyValue aVal;
676             aVal.Value = i_rCtrl;
677             maProperties.push_back( aVal );
678         }
679 
680         Sequence<rtl::OUString> CreateChoice (const sal_uInt16 nResourceId) const
681         {
682             SdResId aResourceId (nResourceId);
683             ResStringArray aChoiceStrings (aResourceId);
684 
685             const sal_uInt32 nCount (aChoiceStrings.Count());
686             Sequence<rtl::OUString> aChoices (nCount);
687             for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex)
688                 aChoices[nIndex] = aChoiceStrings.GetString(nIndex);
689 
690             return aChoices;
691         }
692 
693         Sequence<rtl::OUString> GetSlidesPerPageSequence (void)
694         {
695             const Sequence<rtl::OUString> aChoice (
696                 CreateChoice(_STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES));
697             maSlidesPerPage.clear();
698 			maSlidesPerPage.push_back(0); // first is using the default
699             for (sal_Int32 nIndex=1,nCount=aChoice.getLength(); nIndex<nCount; ++nIndex)
700                 maSlidesPerPage.push_back(aChoice[nIndex].toInt32());
701             return aChoice;
702         }
703     };
704 
705 
706 
707 
708     /** The Prepare... methods of the DocumentRenderer::Implementation class
709         create a set of PrinterPage objects that contain all necessary
710         information to do the actual printing.  There is one PrinterPage
711         object per printed page.  Derived classes implement the actual, mode
712         specific printing.
713 
714         This and all derived classes support the asynchronous printing
715         process by not storing pointers to any data with lifetime shorter
716         than the PrinterPage objects, i.e. slides, shapes, (one of) the
717         outliner (of the document).
718     */
719     class PrinterPage
720     {
721     public:
722         PrinterPage (
723             const PageKind ePageKind,
724             const MapMode& rMapMode,
725             const bool bPrintMarkedOnly,
726             const ::rtl::OUString& rsPageString,
727             const Point& rPageStringOffset,
728             const sal_uLong nDrawMode,
729             const Orientation eOrientation,
730             const sal_uInt16 nPaperTray)
731             : mePageKind(ePageKind),
732               maMap(rMapMode),
733               mbPrintMarkedOnly(bPrintMarkedOnly),
734               msPageString(rsPageString),
735               maPageStringOffset(rPageStringOffset),
736               mnDrawMode(nDrawMode),
737               meOrientation(eOrientation),
738               mnPaperTray(nPaperTray)
739         {
740         }
741 
742         virtual ~PrinterPage (void) {}
743 
744         virtual void Print (
745             Printer& rPrinter,
746             SdDrawDocument& rDocument,
747             ViewShell& rViewShell,
748             View* pView,
749             DrawView& rPrintView,
750             const SetOfByte& rVisibleLayers,
751             const SetOfByte& rPrintableLayers) const = 0;
752 
753         sal_uLong GetDrawMode (void) const { return mnDrawMode; }
754         Orientation GetOrientation (void) const { return meOrientation; }
755         sal_uInt16 GetPaperTray (void) const { return mnPaperTray; }
756 
757     protected:
758         const PageKind mePageKind;
759         const MapMode maMap;
760         const bool mbPrintMarkedOnly;
761         const ::rtl::OUString msPageString;
762         const Point maPageStringOffset;
763         const sal_uLong mnDrawMode;
764         const Orientation meOrientation;
765         const sal_uInt16 mnPaperTray;
766     };
767 
768 
769 
770 
771     /** The RegularPrinterPage is used for printing one regular slide (no
772         notes, handout, or outline) to one printer page.
773     */
774     class RegularPrinterPage : public PrinterPage
775     {
776     public:
777         RegularPrinterPage (
778             const sal_uInt16 nPageIndex,
779             const PageKind ePageKind,
780             const MapMode& rMapMode,
781             const bool bPrintMarkedOnly,
782             const ::rtl::OUString& rsPageString,
783             const Point& rPageStringOffset,
784             const sal_uLong nDrawMode,
785             const Orientation eOrientation,
786             const sal_uInt16 nPaperTray)
787             : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, rsPageString,
788                 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
789               mnPageIndex(nPageIndex)
790         {
791         }
792 
793         virtual ~RegularPrinterPage (void) {}
794 
795         virtual void Print (
796             Printer& rPrinter,
797             SdDrawDocument& rDocument,
798             ViewShell& rViewShell,
799             View* pView,
800             DrawView& rPrintView,
801             const SetOfByte& rVisibleLayers,
802             const SetOfByte& rPrintableLayers) const
803         {
804             (void)rViewShell;
805             SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
806             rPrinter.SetMapMode(maMap);
807             PrintPage(
808                 rPrinter,
809                 rPrintView,
810                 *pPageToPrint,
811                 pView,
812                 mbPrintMarkedOnly,
813                 rVisibleLayers,
814                 rPrintableLayers);
815             PrintMessage(
816                 rPrinter,
817                 msPageString,
818                 maPageStringOffset);
819         }
820 
821     private:
822         const sal_uInt16 mnPageIndex;
823     };
824 
825 
826 
827 
828     /** Print one slide multiple times on a printer page so that the whole
829         printer page is covered.
830     */
831     class TiledPrinterPage : public PrinterPage
832     {
833     public:
834         TiledPrinterPage (
835             const sal_uInt16 nPageIndex,
836             const PageKind ePageKind,
837             const sal_Int32 nGap,
838             const bool bPrintMarkedOnly,
839             const ::rtl::OUString& rsPageString,
840             const Point& rPageStringOffset,
841             const sal_uLong nDrawMode,
842             const Orientation eOrientation,
843             const sal_uInt16 nPaperTray)
844             : PrinterPage(ePageKind, MapMode(), bPrintMarkedOnly, rsPageString,
845                 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
846               mnPageIndex(nPageIndex),
847               mnGap(nGap)
848         {
849         }
850 
851         virtual ~TiledPrinterPage (void) {}
852 
853         virtual void Print (
854             Printer& rPrinter,
855             SdDrawDocument& rDocument,
856             ViewShell& rViewShell,
857             View* pView,
858             DrawView& rPrintView,
859             const SetOfByte& rVisibleLayers,
860             const SetOfByte& rPrintableLayers) const
861         {
862             (void)rViewShell;
863             SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
864             if (pPageToPrint==NULL)
865                 return;
866             MapMode aMap (rPrinter.GetMapMode());
867 
868             const Size aPageSize (pPageToPrint->GetSize());
869             const Size aPrintSize (rPrinter.GetOutputSize());
870 
871             const sal_Int32 nPageWidth (aPageSize.Width() + mnGap
872                 - pPageToPrint->GetLftBorder() - pPageToPrint->GetRgtBorder());
873             const sal_Int32 nPageHeight (aPageSize.Height() + mnGap
874                 - pPageToPrint->GetUppBorder() - pPageToPrint->GetLwrBorder());
875             if (nPageWidth<=0 || nPageHeight<=0)
876                 return;
877 
878             // Print at least two rows and columns.  More if the document
879             // page fits completely onto the printer page.
880             const sal_Int32 nColumnCount (::std::max(sal_Int32(2),
881                     sal_Int32(aPrintSize.Width() / nPageWidth)));
882             const sal_Int32 nRowCount (::std::max(sal_Int32(2),
883                     sal_Int32(aPrintSize.Height() / nPageHeight)));
884             Point aPrintOrigin;
885             for (sal_Int32 nRow=0; nRow<nRowCount; ++nRow)
886                 for (sal_Int32 nColumn=0; nColumn<nColumnCount; ++nColumn)
887                 {
888                     aMap.SetOrigin(Point(nColumn*nPageWidth,nRow*nPageHeight));
889                     rPrinter.SetMapMode(aMap);
890                     PrintPage(
891                         rPrinter,
892                         rPrintView,
893                         *pPageToPrint,
894                         pView,
895                         mbPrintMarkedOnly,
896                         rVisibleLayers,
897                         rPrintableLayers);
898                 }
899 
900             PrintMessage(
901                 rPrinter,
902                 msPageString,
903                 maPageStringOffset);
904         }
905 
906     private:
907         const sal_uInt16 mnPageIndex;
908         const sal_Int32 mnGap;
909     };
910 
911     /** Print two slides to one printer page so that the resulting pages
912         form a booklet.
913     */
914     class BookletPrinterPage : public PrinterPage
915     {
916     public:
917         BookletPrinterPage (
918             const sal_uInt16 nFirstPageIndex,
919             const sal_uInt16 nSecondPageIndex,
920             const Point& rFirstOffset,
921             const Point& rSecondOffset,
922             const PageKind ePageKind,
923             const MapMode& rMapMode,
924             const bool bPrintMarkedOnly,
925             const sal_uLong nDrawMode,
926             const Orientation eOrientation,
927             const sal_uInt16 nPaperTray)
928             : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, ::rtl::OUString(),
929                 Point(), nDrawMode, eOrientation, nPaperTray),
930               mnFirstPageIndex(nFirstPageIndex),
931               mnSecondPageIndex(nSecondPageIndex),
932               maFirstOffset(rFirstOffset),
933               maSecondOffset(rSecondOffset)
934         {
935         }
936 
937         virtual ~BookletPrinterPage (void) {}
938 
939         virtual void Print (
940             Printer& rPrinter,
941             SdDrawDocument& rDocument,
942             ViewShell& rViewShell,
943             View* pView,
944             DrawView& rPrintView,
945             const SetOfByte& rVisibleLayers,
946             const SetOfByte& rPrintableLayers) const
947         {
948             (void)rViewShell;
949             MapMode aMap (maMap);
950             SdPage* pPageToPrint = rDocument.GetSdPage(mnFirstPageIndex, mePageKind);
951             if (pPageToPrint)
952             {
953                 aMap.SetOrigin(maFirstOffset);
954                 rPrinter.SetMapMode(aMap);
955                 PrintPage(
956                     rPrinter,
957                     rPrintView,
958                     *pPageToPrint,
959                     pView,
960                     mbPrintMarkedOnly,
961                     rVisibleLayers,
962                     rPrintableLayers);
963             }
964 
965             pPageToPrint = rDocument.GetSdPage(mnSecondPageIndex, mePageKind);
966             if( pPageToPrint )
967             {
968                 aMap.SetOrigin(maSecondOffset);
969                 rPrinter.SetMapMode(aMap);
970                 PrintPage(
971                     rPrinter,
972                     rPrintView,
973                     *pPageToPrint,
974                     pView,
975                     mbPrintMarkedOnly,
976                     rVisibleLayers,
977                     rPrintableLayers);
978             }
979         }
980 
981     private:
982         const sal_uInt16 mnFirstPageIndex;
983         const sal_uInt16 mnSecondPageIndex;
984         const Point maFirstOffset;
985         const Point maSecondOffset;
986     };
987 
988 
989 
990 
991     /** One handout page displays one to nine slides.
992     */
993     class HandoutPrinterPage : public PrinterPage
994     {
995     public:
996         HandoutPrinterPage (
997             const sal_uInt16 nHandoutPageIndex,
998             const ::std::vector<sal_uInt16>& rPageIndices,
999             const MapMode& rMapMode,
1000             const ::rtl::OUString& rsPageString,
1001             const Point& rPageStringOffset,
1002             const sal_uLong nDrawMode,
1003             const Orientation eOrientation,
1004             const sal_uInt16 nPaperTray)
1005             : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
1006                 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
1007               mnHandoutPageIndex(nHandoutPageIndex),
1008               maPageIndices(rPageIndices)
1009         {
1010         }
1011 
1012         virtual void Print (
1013             Printer& rPrinter,
1014             SdDrawDocument& rDocument,
1015             ViewShell& rViewShell,
1016             View* pView,
1017             DrawView& rPrintView,
1018             const SetOfByte& rVisibleLayers,
1019             const SetOfByte& rPrintableLayers) const
1020         {
1021             SdPage& rHandoutPage (*rDocument.GetSdPage(0, PK_HANDOUT));
1022 
1023 			Reference< com::sun::star::beans::XPropertySet > xHandoutPage( rHandoutPage.getUnoPage(), UNO_QUERY );
1024 			const rtl::OUString sPageNumber( RTL_CONSTASCII_USTRINGPARAM( "Number" ) );
1025 
1026             // Collect the page objects of the handout master.
1027             std::vector<SdrPageObj*> aHandoutPageObjects;
1028             SdrObjListIter aShapeIter (rHandoutPage);
1029             while (aShapeIter.IsMore())
1030             {
1031                 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
1032                 if (pPageObj)
1033                     aHandoutPageObjects.push_back(pPageObj);
1034             }
1035             if (aHandoutPageObjects.empty())
1036                 return;
1037 
1038             // Connect page objects with pages.
1039             std::vector<SdrPageObj*>::iterator aPageObjIter (aHandoutPageObjects.begin());
1040             for (std::vector<sal_uInt16>::const_iterator
1041                      iPageIndex(maPageIndices.begin()),
1042                      iEnd(maPageIndices.end());
1043                  iPageIndex!=iEnd && aPageObjIter!=aHandoutPageObjects.end();
1044                  ++iPageIndex)
1045             {
1046                 // Check if the page still exists.
1047                 if (*iPageIndex >= rDocument.GetSdPageCount(PK_STANDARD))
1048                     continue;
1049 
1050                 SdrPageObj* pPageObj = (*aPageObjIter++);
1051                 pPageObj->SetReferencedPage(rDocument.GetSdPage(*iPageIndex, PK_STANDARD));
1052             }
1053 
1054             // if there are more page objects than pages left, set the rest to invisible
1055             int nHangoverCount = 0;
1056             while (aPageObjIter != aHandoutPageObjects.end())
1057             {
1058                 (*aPageObjIter++)->SetReferencedPage(0L);
1059                 nHangoverCount++;
1060             }
1061 
1062             // Hide outlines for objects that have pages attached.
1063             if (nHangoverCount > 0)
1064             {
1065                 int nSkip = aHandoutPageObjects.size() - nHangoverCount;
1066                 aShapeIter.Reset();
1067                 while (aShapeIter.IsMore())
1068                 {
1069                     SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
1070                     if (pPathObj)
1071                     {
1072                         if (nSkip > 0)
1073                             --nSkip;
1074                         else
1075                             pPathObj->SetMergedItem(XLineStyleItem(XLINE_NONE));
1076                     }
1077                 }
1078             }
1079 
1080 			if( xHandoutPage.is() ) try
1081 			{
1082 				xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(mnHandoutPageIndex) ) );
1083 			}
1084 			catch( Exception& )
1085 			{
1086 			}
1087 			rViewShell.SetPrintedHandoutPageNum( mnHandoutPageIndex + 1 );
1088 
1089             MapMode aMap (rPrinter.GetMapMode());
1090             rPrinter.SetMapMode(maMap);
1091 
1092             PrintPage(
1093                 rPrinter,
1094                 rPrintView,
1095                 rHandoutPage,
1096                 pView,
1097                 false,
1098                 rVisibleLayers,
1099                 rPrintableLayers);
1100             PrintMessage(
1101                 rPrinter,
1102                 msPageString,
1103                 maPageStringOffset);
1104 
1105 			if( xHandoutPage.is() ) try
1106 			{
1107 				xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(0) ) );
1108 			}
1109 			catch( Exception& )
1110 			{
1111 			}
1112 			rViewShell.SetPrintedHandoutPageNum(1);
1113 
1114             // Restore outlines.
1115             if (nHangoverCount > 0)
1116             {
1117                 aShapeIter.Reset();
1118                 while (aShapeIter.IsMore())
1119                 {
1120                     SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
1121                     if (pPathObj != NULL)
1122                         pPathObj->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1123                 }
1124             }
1125 
1126        }
1127 
1128     private:
1129         const sal_uInt16 mnHandoutPageIndex;
1130         const ::std::vector<sal_uInt16> maPageIndices;
1131     };
1132 
1133 
1134 
1135 
1136     /** The outline information (title, subtitle, outline objects) of the
1137         document.  There is no fixed mapping of slides to printer pages.
1138     */
1139     class OutlinerPrinterPage : public PrinterPage
1140     {
1141     public:
1142         OutlinerPrinterPage (
1143             OutlinerParaObject* pParaObject,
1144             const MapMode& rMapMode,
1145             const ::rtl::OUString& rsPageString,
1146             const Point& rPageStringOffset,
1147             const sal_uLong nDrawMode,
1148             const Orientation eOrientation,
1149             const sal_uInt16 nPaperTray)
1150             : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
1151                 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
1152               mpParaObject(pParaObject)
1153         {
1154         }
1155 
1156         ~OutlinerPrinterPage (void)
1157         {
1158             mpParaObject.reset();
1159         }
1160 
1161         virtual void Print (
1162             Printer& rPrinter,
1163             SdDrawDocument& rDocument,
1164             ViewShell& rViewShell,
1165             View* pView,
1166             DrawView& rPrintView,
1167             const SetOfByte& rVisibleLayers,
1168             const SetOfByte& rPrintableLayers) const
1169         {
1170             (void)rViewShell;
1171             (void)pView;
1172             (void)rPrintView;
1173             (void)rVisibleLayers;
1174             (void)rPrintableLayers;
1175 
1176             // Set up the printer.
1177             rPrinter.SetMapMode(maMap);
1178 
1179             // Get and set up the outliner.
1180             const Rectangle aOutRect (rPrinter.GetPageOffset(), rPrinter.GetOutputSize());
1181             Outliner* pOutliner = rDocument.GetInternalOutliner();
1182             const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1183             const sal_Bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1184             const Size aSavedPaperSize (pOutliner->GetPaperSize());
1185 
1186             pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1187             pOutliner->SetPaperSize(aOutRect.GetSize());
1188             pOutliner->SetUpdateMode(sal_True);
1189             pOutliner->Clear();
1190             pOutliner->SetText(*mpParaObject);
1191 
1192             pOutliner->Draw(&rPrinter, aOutRect);
1193 
1194             PrintMessage(
1195                 rPrinter,
1196                 msPageString,
1197                 maPageStringOffset);
1198 
1199             // Restore outliner and printer.
1200             pOutliner->Clear();
1201             pOutliner->SetUpdateMode(bSavedUpdateMode);
1202             pOutliner->SetPaperSize(aSavedPaperSize);
1203             pOutliner->Init(nSavedOutlMode);
1204         }
1205 
1206     private:
1207         ::boost::scoped_ptr<OutlinerParaObject> mpParaObject;
1208     };
1209 }
1210 
1211 
1212 //===== DocumentRenderer::Implementation ======================================
1213 
1214 class DocumentRenderer::Implementation
1215     : public SfxListener,
1216       public vcl::PrinterOptionsHelper
1217 {
1218 public:
1219     Implementation (ViewShellBase& rBase)
1220         : mrBase(rBase),
1221           mbIsDisposed(false),
1222           mpPrinter(NULL),
1223           mpOptions(),
1224           maPrinterPages(),
1225           mpPrintView(),
1226           mbHasOrientationWarningBeenShown(false)
1227     {
1228         DialogCreator aCreator( mrBase.GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_IMPRESS );
1229         m_aUIProperties = aCreator.GetDialogControls();
1230         maSlidesPerPage = aCreator.GetSlidesPerPage();
1231 
1232         StartListening(mrBase);
1233     }
1234 
1235 
1236 
1237 
1238     virtual ~Implementation (void)
1239     {
1240         EndListening(mrBase);
1241     }
1242 
1243 
1244 
1245 
1246     virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
1247     {
1248         const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1249         if (pSimpleHint != NULL
1250             && pSimpleHint->GetId() == SFX_HINT_DYING
1251             && &rBroadcaster == &static_cast<SfxBroadcaster&>(mrBase))
1252         {
1253             Dispose();
1254         }
1255     }
1256 
1257 
1258 
1259     /** Process the sequence of properties given to one of the XRenderable
1260         methods.
1261     */
1262     void ProcessProperties (const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
1263     {
1264         OSL_ASSERT(!mbIsDisposed);
1265         if (mbIsDisposed)
1266             return;
1267 
1268         bool bIsValueChanged = processProperties( rOptions );
1269         bool bIsPaperChanged = false;
1270 
1271         // The RenderDevice property is handled specially: its value is
1272         // stored in mpPrinter instead of being retrieved on demand.
1273         Any aDev( getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) ) ) );
1274         Reference<awt::XDevice> xRenderDevice;
1275 
1276         if (aDev >>= xRenderDevice)
1277         {
1278             VCLXDevice* pDevice = VCLXDevice::GetImplementation(xRenderDevice);
1279             OutputDevice* pOut = pDevice ? pDevice->GetOutputDevice() : NULL;
1280             mpPrinter = dynamic_cast<Printer*>(pOut);
1281             Size aPageSizePixel = mpPrinter ? mpPrinter->GetPaperSizePixel() : Size();
1282             if( aPageSizePixel != maPrinterPageSizePixel )
1283             {
1284                 bIsPaperChanged = true;
1285                 maPrinterPageSizePixel = aPageSizePixel;
1286             }
1287         }
1288 
1289         if (bIsValueChanged)
1290         {
1291             if ( ! mpOptions )
1292                 mpOptions.reset(new PrintOptions(*this, maSlidesPerPage));
1293         }
1294         if( bIsValueChanged || bIsPaperChanged )
1295             PreparePages();
1296     }
1297 
1298 
1299 
1300     /** Return the number of pages that are to be printed.
1301     */
1302     sal_Int32 GetPrintPageCount (void)
1303     {
1304         OSL_ASSERT(!mbIsDisposed);
1305         if (mbIsDisposed)
1306             return 0;
1307         else
1308             return maPrinterPages.size();
1309     }
1310 
1311 
1312 
1313     /** Return a sequence of properties that can be returned by the
1314         XRenderable::getRenderer() method.
1315     */
1316     css::uno::Sequence<css::beans::PropertyValue> GetProperties (
1317         const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
1318     {
1319         (void)rOptions;
1320 
1321         css::uno::Sequence<css::beans::PropertyValue> aProperties (3);
1322 
1323         aProperties[0].Name = A2S("ExtraPrintUIOptions");
1324         aProperties[0].Value <<= m_aUIProperties;
1325 
1326         aProperties[1].Name = A2S("PageSize");
1327         aProperties[1].Value <<= maPrintSize;
1328 
1329         // FIXME: is this always true ?
1330         aProperties[2].Name = A2S("PageIncludesNonprintableArea");
1331         aProperties[2].Value = makeAny( sal_True );
1332 
1333         return aProperties;
1334     }
1335 
1336 
1337 
1338 
1339     /** Print one of the prepared pages.
1340     */
1341     void PrintPage (const sal_Int32 nIndex)
1342     {
1343         OSL_ASSERT(!mbIsDisposed);
1344         if (mbIsDisposed)
1345             return;
1346 
1347         Printer& rPrinter (*mpPrinter);
1348 
1349         ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1350         if ( ! pViewShell)
1351             return;
1352 
1353         SdDrawDocument* pDocument = pViewShell->GetDoc();
1354         OSL_ASSERT(pDocument!=NULL);
1355 
1356         ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1357             ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
1358 
1359         if ( ! mpPrintView)
1360             mpPrintView.reset(new DrawView(mrBase.GetDocShell(), &rPrinter, pDrawViewShell.get()));
1361 
1362         if (nIndex<0 || sal::static_int_cast<sal_uInt32>(nIndex)>=maPrinterPages.size())
1363             return;
1364 
1365         const ::boost::shared_ptr<PrinterPage> pPage (maPrinterPages[nIndex]);
1366         OSL_ASSERT(pPage);
1367         if ( ! pPage)
1368             return;
1369 
1370         const Orientation eSavedOrientation (rPrinter.GetOrientation());
1371         const sal_uLong nSavedDrawMode (rPrinter.GetDrawMode());
1372         const MapMode aSavedMapMode (rPrinter.GetMapMode());
1373         const sal_uInt16 nSavedPaperBin (rPrinter.GetPaperBin());
1374 
1375 
1376         // Set page orientation.
1377         if ( ! rPrinter.SetOrientation(pPage->GetOrientation()))
1378         {
1379             if ( ! mbHasOrientationWarningBeenShown
1380                 && mpOptions->IsWarningOrientation())
1381             {
1382                 mbHasOrientationWarningBeenShown = true;
1383                 // Show warning that the orientation could not be set.
1384                 if (pViewShell)
1385                 {
1386                     WarningBox aWarnBox(
1387                         pViewShell->GetActiveWindow(),
1388                         (WinBits)(WB_OK_CANCEL | WB_DEF_CANCEL),
1389                         String(SdResId(STR_WARN_PRINTFORMAT_FAILURE)));
1390                     if (aWarnBox.Execute() != RET_OK)
1391                         return;
1392                 }
1393             }
1394         }
1395 
1396         // Set the draw mode.
1397         rPrinter.SetDrawMode(pPage->GetDrawMode());
1398 
1399         // Set paper tray.
1400         rPrinter.SetPaperBin(pPage->GetPaperTray());
1401 
1402         // Print the actual page.
1403         pPage->Print(
1404             rPrinter,
1405             *pDocument,
1406             *pViewShell,
1407             pDrawViewShell ? pDrawViewShell->GetView() : NULL,
1408             *mpPrintView,
1409             pViewShell->GetFrameView()->GetVisibleLayers(),
1410             pViewShell->GetFrameView()->GetPrintableLayers());
1411 
1412         rPrinter.SetOrientation(eSavedOrientation);
1413         rPrinter.SetDrawMode(nSavedDrawMode);
1414         rPrinter.SetMapMode(aSavedMapMode);
1415         rPrinter.SetPaperBin(nSavedPaperBin);
1416     }
1417 
1418 
1419 
1420 
1421 private:
1422     ViewShellBase& mrBase;
1423     bool mbIsDisposed;
1424     Printer* mpPrinter;
1425     Size maPrinterPageSizePixel;
1426     ::boost::scoped_ptr<PrintOptions> mpOptions;
1427     ::std::vector< ::boost::shared_ptr< ::sd::PrinterPage> > maPrinterPages;
1428     ::boost::scoped_ptr<DrawView> mpPrintView;
1429     bool mbHasOrientationWarningBeenShown;
1430     ::std::vector<sal_Int32> maSlidesPerPage;
1431     awt::Size maPrintSize;
1432 
1433     void Dispose (void)
1434     {
1435         mbIsDisposed = true;
1436     }
1437 
1438 
1439 
1440     /** Determine and set the paper orientation.
1441     */
1442     bool SetupPaperOrientation (
1443         const PageKind ePageKind,
1444         PrintInfo& rInfo)
1445     {
1446         SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1447         rInfo.meOrientation = ORIENTATION_PORTRAIT;
1448 
1449         if( ! mpOptions->IsBooklet())
1450         {
1451             rInfo.meOrientation = pDocument->GetSdPage(0, ePageKind)->GetOrientation();
1452         }
1453         else if (rInfo.maPageSize.Width() < rInfo.maPageSize.Height())
1454             rInfo.meOrientation = ORIENTATION_LANDSCAPE;
1455 
1456         const Size aPaperSize (rInfo.mpPrinter->GetPaperSize());
1457         if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1458               (aPaperSize.Width() < aPaperSize.Height()))
1459            ||
1460             (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1461               (aPaperSize.Width() > aPaperSize.Height()))
1462           )
1463         {
1464             maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1465             //            rInfo.maPrintSize = Size(rInfo.maPrintSize.Height(), rInfo.maPrintSize.Width());
1466         }
1467         else
1468         {
1469             maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1470         }
1471 
1472         return true;
1473     }
1474 
1475 
1476 
1477     /** Top most method for preparing printer pages.  In this and the other
1478         Prepare... methods the various special cases are detected and
1479         handled.
1480         For every page that is to be printed (that may contain several
1481         slides) one PrinterPage object is created and inserted into
1482         maPrinterPages.
1483     */
1484     void PreparePages (void)
1485     {
1486         mpPrintView.reset();
1487         maPrinterPages.clear();
1488         mbHasOrientationWarningBeenShown = false;
1489 
1490         ViewShell* pShell = mrBase.GetMainViewShell().get();
1491 
1492         PrintInfo aInfo (mpPrinter, mpOptions->GetPrinterSelection(), mrBase.GetMainViewShell());
1493 
1494         if (aInfo.mpPrinter!=NULL && pShell!=NULL)
1495         {
1496 
1497             MapMode aMap (aInfo.mpPrinter->GetMapMode());
1498             aMap.SetMapUnit(MAP_100TH_MM);
1499             aInfo.maMap = aMap;
1500             mpPrinter->SetMapMode(aMap);
1501 
1502             ::Outliner& rOutliner = mrBase.GetDocument()->GetDrawOutliner();
1503             const sal_uLong nSavedControlWord (rOutliner.GetControlWord());
1504             sal_uLong nCntrl = nSavedControlWord;
1505             nCntrl &= ~EE_CNTRL_MARKFIELDS;
1506             nCntrl &= ~EE_CNTRL_ONLINESPELLING;
1507             rOutliner.SetControlWord( nCntrl );
1508 
1509             // When in outline view then apply all pending changes to the model.
1510             if (pShell->ISA(OutlineViewShell))
1511                 static_cast<OutlineViewShell*>(pShell)->PrepareClose (sal_False, sal_False);
1512 
1513             // Collect some frequently used data.
1514             if (mpOptions->IsDate())
1515             {
1516                 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getDate( Date() );
1517                 aInfo.msTimeDate += ::rtl::OUString((sal_Unicode)' ');
1518             }
1519 
1520             if (mpOptions->IsTime())
1521                 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getTime( Time(), sal_False, sal_False );
1522             aInfo.maPrintSize = aInfo.mpPrinter->GetOutputSize();
1523             maPrintSize = awt::Size(
1524                 aInfo.mpPrinter->GetPaperSize().Width(),
1525                 aInfo.mpPrinter->GetPaperSize().Height());
1526 
1527             switch (mpOptions->GetOutputQuality())
1528             {
1529                 case 1:
1530                     aInfo.mnDrawMode = DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL
1531                         | DRAWMODE_BLACKTEXT | DRAWMODE_GRAYBITMAP
1532                         | DRAWMODE_GRAYGRADIENT;
1533                     break;
1534 
1535                 case 2:
1536                     aInfo.mnDrawMode = DRAWMODE_BLACKLINE | DRAWMODE_BLACKTEXT
1537                         | DRAWMODE_WHITEFILL | DRAWMODE_GRAYBITMAP
1538                         | DRAWMODE_WHITEGRADIENT;
1539                     break;
1540 
1541                 default:
1542                     aInfo.mnDrawMode = DRAWMODE_DEFAULT;
1543             }
1544 
1545             // check if selected range of pages contains transparent objects
1546             /*
1547             const bool bPrintPages (bPrintNotes || bPrintDraw || bPrintHandout);
1548             const bool bContainsTransparency (bPrintPages && ContainsTransparency());
1549             if (pPrinter->InitJob (mrBase.GetWindow(), !bIsAPI && bContainsTransparency))
1550             */
1551 
1552             if (mpOptions->IsDraw())
1553                 PrepareStdOrNotes(PK_STANDARD, aInfo);
1554             if (mpOptions->IsNotes())
1555                 PrepareStdOrNotes(PK_NOTES, aInfo);
1556 			if (mpOptions->IsHandout())
1557             {
1558 				InitHandoutTemplate();
1559                 PrepareHandout(aInfo);
1560             }
1561             if (mpOptions->IsOutline())
1562                 PrepareOutline(aInfo);
1563 
1564             rOutliner.SetControlWord(nSavedControlWord);
1565         }
1566     }
1567 
1568 
1569 
1570 
1571     /** Create the page objects of the handout template.  When the actual
1572         printing takes place then the page objects are assigned different
1573         sets of slides for each printed page (see HandoutPrinterPage::Print).
1574     */
1575     void InitHandoutTemplate (void)
1576     {
1577         const sal_Int32 nSlidesPerHandout (mpOptions->GetHandoutPageCount());
1578         const bool bHandoutHorizontal (mpOptions->IsHandoutHorizontal());
1579 
1580         AutoLayout eLayout = AUTOLAYOUT_HANDOUT6;
1581         switch (nSlidesPerHandout)
1582         {
1583             case 0: eLayout = AUTOLAYOUT_NONE; break; // AUTOLAYOUT_HANDOUT1; break;
1584             case 1: eLayout = AUTOLAYOUT_HANDOUT1; break;
1585             case 2: eLayout = AUTOLAYOUT_HANDOUT2; break;
1586             case 3: eLayout = AUTOLAYOUT_HANDOUT3; break;
1587             case 4: eLayout = AUTOLAYOUT_HANDOUT4; break;
1588             default:
1589             case 6: eLayout = AUTOLAYOUT_HANDOUT6; break;
1590             case 9: eLayout = AUTOLAYOUT_HANDOUT9; break;
1591         }
1592 
1593         if( !mrBase.GetDocument() )
1594             return;
1595 
1596         SdDrawDocument& rModel = *mrBase.GetDocument();
1597 
1598         // first, prepare handout page (not handout master)
1599 
1600         SdPage* pHandout = rModel.GetSdPage(0, PK_HANDOUT);
1601         if( !pHandout )
1602             return;
1603 
1604         // delete all previous shapes from handout page
1605         while( pHandout->GetObjCount() )
1606         {
1607             SdrObject* pObj = pHandout->NbcRemoveObject(0);
1608             if( pObj )
1609                 SdrObject::Free( pObj  );
1610         }
1611 
1612         const bool bDrawLines (eLayout == AUTOLAYOUT_HANDOUT3);
1613 
1614         std::vector< Rectangle > aAreas;
1615         SdPage::CalculateHandoutAreas( rModel, eLayout, bHandoutHorizontal, aAreas );
1616 
1617         std::vector< Rectangle >::iterator iter( aAreas.begin() );
1618         while( iter != aAreas.end() )
1619         {
1620             pHandout->NbcInsertObject( new SdrPageObj((*iter++)) );
1621 
1622             if( bDrawLines && (iter != aAreas.end())  )
1623             {
1624                 Rectangle aRect( (*iter++) );
1625 
1626                 basegfx::B2DPolygon aPoly;
1627                 aPoly.insert(0, basegfx::B2DPoint( aRect.Left(), aRect.Top() ) );
1628                 aPoly.insert(1, basegfx::B2DPoint( aRect.Right(), aRect.Top() ) );
1629 
1630                 basegfx::B2DHomMatrix aMatrix;
1631                 aMatrix.translate( 0.0, static_cast< double >( aRect.GetHeight() / 7 ) );
1632 
1633                 basegfx::B2DPolyPolygon aPathPoly;
1634                 for( sal_uInt16 nLine = 0; nLine < 7; nLine++ )
1635                 {
1636                     aPoly.transform( aMatrix );
1637                     aPathPoly.append( aPoly );
1638                 }
1639 
1640                 SdrPathObj* pPathObj = new SdrPathObj(OBJ_PATHLINE, aPathPoly );
1641                 pPathObj->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1642                 pPathObj->SetMergedItem(XLineColorItem(String(), Color(COL_BLACK)));
1643 
1644                 pHandout->NbcInsertObject( pPathObj );
1645             }
1646         }
1647     }
1648 
1649 
1650 
1651 
1652     /** Detect whether any of the slides that are to be printed contains
1653         partially transparent or translucent shapes.
1654     */
1655     bool ContainsTransparency (const PrintInfo& rInfo) const
1656     {
1657         // const bool bPrintExcluded (mpOptions->IsPrintExcluded());
1658         bool bContainsTransparency = false;
1659 
1660         for (sal_uInt16
1661                  nIndex=0,
1662                  nCount=mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1663              nIndex < nCount && !bContainsTransparency;
1664              ++nIndex)
1665         {
1666             SdPage* pPage = GetFilteredPage(nIndex, PK_STANDARD, rInfo);
1667             if (pPage == NULL)
1668                 continue;
1669 
1670             bContainsTransparency = pPage->HasTransparentObjects();
1671             if ( ! bContainsTransparency && pPage->TRG_HasMasterPage())
1672                 bContainsTransparency = pPage->TRG_GetMasterPage().HasTransparentObjects();
1673         }
1674 
1675         return bContainsTransparency;
1676     }
1677 
1678 
1679 
1680 
1681     /** Detect whether the specified slide is to be printed.
1682         @return
1683             When the slide is not to be printed then <NULL/> is returned.
1684             Otherwise a pointer to the slide is returned.
1685     */
1686     SdPage* GetFilteredPage (
1687         const sal_Int32 nPageIndex,
1688         const PageKind ePageKind,
1689         const PrintInfo& rInfo) const
1690     {
1691         OSL_ASSERT(mrBase.GetDocument() != NULL);
1692         OSL_ASSERT(nPageIndex>=0);
1693         if ( ! rInfo.maSelection.IsSelected(nPageIndex))
1694             return NULL;
1695         SdPage* pPage = mrBase.GetDocument()->GetSdPage(
1696             sal::static_int_cast<sal_uInt16>(nPageIndex),
1697             ePageKind);
1698         if (pPage == NULL)
1699             return NULL;
1700         if ( ! pPage->IsExcluded() || mpOptions->IsPrintExcluded())
1701             return pPage;
1702         else
1703             return NULL;
1704     }
1705 
1706 
1707 
1708 
1709     /** Prepare the outline of the document for printing.  There is no fixed
1710         number of slides whose outline data is put onto one printer page.
1711         If the current printer page has enough room for the outline of the
1712         current slide then that is added.  Otherwise a new printer page is
1713         started.
1714     */
1715     void PrepareOutline (PrintInfo& rInfo)
1716     {
1717         MapMode aMap (rInfo.maMap);
1718         Point aPageOfs (rInfo.mpPrinter->GetPageOffset() );
1719         // aMap.SetOrigin(Point() - aPageOfs);
1720         aMap.SetScaleX(Fraction(1,2));
1721         aMap.SetScaleY(Fraction(1,2));
1722         mpPrinter->SetMapMode(aMap);
1723 
1724         Rectangle aOutRect(aPageOfs, rInfo.mpPrinter->GetOutputSize());
1725         if( aOutRect.GetWidth() > aOutRect.GetHeight() )
1726         {
1727             Size aPaperSize( rInfo.mpPrinter->PixelToLogic( rInfo.mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
1728             maPrintSize.Width  = aPaperSize.Height();
1729             maPrintSize.Height = aPaperSize.Width();
1730             aOutRect = Rectangle( Point( aPageOfs.Y(), aPageOfs.X() ),
1731                                   Size( aOutRect.GetHeight(), aOutRect.GetWidth() ) );
1732         }
1733 
1734         Link aOldLink;
1735         Outliner* pOutliner = mrBase.GetDocument()->GetInternalOutliner();
1736         pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1737         const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1738         const sal_Bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1739         const Size aSavedPaperSize (pOutliner->GetPaperSize());
1740         const MapMode aSavedMapMode (pOutliner->GetRefMapMode());
1741         pOutliner->SetPaperSize(aOutRect.GetSize());
1742         pOutliner->SetUpdateMode(sal_True);
1743 
1744         long nPageH = aOutRect.GetHeight();
1745 
1746         for (sal_uInt16
1747                  nIndex=0,
1748                  nCount=mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1749              nIndex < nCount;
1750              )
1751         {
1752             pOutliner->Clear();
1753             pOutliner->SetFirstPageNumber(nIndex+1);
1754 
1755             Paragraph* pPara = NULL;
1756             sal_Int32 nH (0);
1757             while (nH < nPageH && nIndex<nCount)
1758             {
1759                 SdPage* pPage = GetFilteredPage(nIndex, PK_STANDARD, rInfo);
1760                 ++nIndex;
1761                 if (pPage == NULL)
1762                     continue;
1763 
1764                 SdrTextObj* pTextObj = NULL;
1765                 sal_uInt32 nObj (0);
1766 
1767                 while (pTextObj==NULL && nObj < pPage->GetObjCount())
1768                 {
1769                     SdrObject* pObj = pPage->GetObj(nObj++);
1770                     if (pObj->GetObjInventor() == SdrInventor
1771                         && pObj->GetObjIdentifier() == OBJ_TITLETEXT)
1772                     {
1773                         pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1774                     }
1775                 }
1776 
1777                 pPara = pOutliner->GetParagraph(pOutliner->GetParagraphCount() - 1);
1778 
1779                 if (pTextObj!=NULL
1780                     && !pTextObj->IsEmptyPresObj()
1781                     && pTextObj->GetOutlinerParaObject())
1782                 {
1783                     pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1784                 }
1785                 else
1786                     pOutliner->Insert(String());
1787 
1788                 pTextObj = NULL;
1789                 nObj = 0;
1790 
1791                 while (pTextObj==NULL && nObj<pPage->GetObjCount())
1792                 {
1793                     SdrObject* pObj = pPage->GetObj(nObj++);
1794                     if (pObj->GetObjInventor() == SdrInventor
1795                         && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT)
1796                     {
1797                         pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1798                     }
1799                 }
1800 
1801                 bool bSubTitle (false);
1802                 if (!pTextObj)
1803                 {
1804                     bSubTitle = true;
1805                     pTextObj = dynamic_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_TEXT));  // Untertitel vorhanden?
1806                 }
1807 
1808                 sal_uLong nParaCount1 = pOutliner->GetParagraphCount();
1809 
1810                 if (pTextObj!=NULL
1811                     && !pTextObj->IsEmptyPresObj()
1812                     && pTextObj->GetOutlinerParaObject())
1813                 {
1814                     pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1815                 }
1816 
1817                 if (bSubTitle )
1818                 {
1819                     const sal_Int32 nParaCount2 (pOutliner->GetParagraphCount());
1820                     for (sal_Int32 nPara=nParaCount1; nPara<nParaCount2; ++nPara)
1821                     {
1822                         Paragraph* pP = pOutliner->GetParagraph(nPara);
1823                         if (pP!=NULL && pOutliner->GetDepth((sal_uInt16)nPara) > 0)
1824                             pOutliner->SetDepth(pP, 0);
1825                     }
1826                 }
1827 
1828                 nH = pOutliner->GetTextHeight();
1829             }
1830 
1831             // Remove the last paragraph when that does not fit completely on
1832             // the current page.
1833             if (nH > nPageH && pPara!=NULL)
1834             {
1835                 sal_uLong nCnt = pOutliner->GetAbsPos(
1836                     pOutliner->GetParagraph( pOutliner->GetParagraphCount() - 1 ) );
1837                 sal_uLong nParaPos = pOutliner->GetAbsPos( pPara );
1838                 nCnt -= nParaPos;
1839                 pPara = pOutliner->GetParagraph( ++nParaPos );
1840                 if ( nCnt && pPara )
1841                 {
1842                     pOutliner->Remove(pPara, nCnt);
1843                     --nIndex;
1844                 }
1845             }
1846 
1847             maPrinterPages.push_back(
1848                 ::boost::shared_ptr<PrinterPage>(
1849                     new OutlinerPrinterPage(
1850                         pOutliner->CreateParaObject(),
1851                         aMap,
1852                         rInfo.msTimeDate,
1853                         aPageOfs,
1854                         rInfo.mnDrawMode,
1855                         rInfo.meOrientation,
1856                         rInfo.mpPrinter->GetPaperBin())));
1857         }
1858 
1859         pOutliner->SetRefMapMode(aSavedMapMode);
1860         pOutliner->SetUpdateMode(bSavedUpdateMode);
1861         pOutliner->SetPaperSize(aSavedPaperSize);
1862         pOutliner->Init(nSavedOutlMode);
1863     }
1864 
1865 
1866 
1867 
1868     /** Prepare handout pages for slides that are to be printed.
1869     */
1870     void PrepareHandout (PrintInfo& rInfo)
1871     {
1872         SdDrawDocument* pDocument = mrBase.GetDocument();
1873         OSL_ASSERT(pDocument != NULL);
1874         SdPage& rHandoutPage (*pDocument->GetSdPage(0, PK_HANDOUT));
1875 
1876         const bool bScalePage (mpOptions->IsPageSize());
1877 
1878         sal_uInt16 nPaperBin;
1879         if ( ! mpOptions->IsPaperBin())
1880             nPaperBin = rHandoutPage.GetPaperBin();
1881         else
1882             nPaperBin = rInfo.mpPrinter->GetPaperBin();
1883 
1884         // Change orientation?
1885         SdPage& rMaster (dynamic_cast<SdPage&>(rHandoutPage.TRG_GetMasterPage()));
1886         rInfo.meOrientation = rMaster.GetOrientation();
1887 
1888         const Size aPaperSize (rInfo.mpPrinter->GetPaperSize());
1889         if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1890               (aPaperSize.Width() < aPaperSize.Height()))
1891            ||
1892             (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1893               (aPaperSize.Width() > aPaperSize.Height()))
1894           )
1895         {
1896             maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1897         }
1898         else
1899         {
1900             maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1901         }
1902 
1903         MapMode aMap (rInfo.maMap);
1904         const Point aPageOfs (rInfo.mpPrinter->GetPageOffset());
1905         //DrawView* pPrintView;
1906 
1907         // aMap.SetOrigin(Point() - aPageOfs);
1908 
1909         if ( bScalePage )
1910         {
1911             const Size aPageSize (rHandoutPage.GetSize());
1912             const Size aPrintSize (rInfo.mpPrinter->GetOutputSize());
1913 
1914             const double fHorz = (double) aPrintSize.Width()	/ aPageSize.Width();
1915             const double fVert = (double) aPrintSize.Height() / aPageSize.Height();
1916 
1917             Fraction	aFract;
1918             if ( fHorz < fVert )
1919                 aFract = Fraction(aPrintSize.Width(), aPageSize.Width());
1920             else
1921                 aFract = Fraction(aPrintSize.Height(), aPageSize.Height());
1922 
1923             aMap.SetScaleX(aFract);
1924             aMap.SetScaleY(aFract);
1925             aMap.SetOrigin(Point());
1926         }
1927 
1928         ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1929         pViewShell->WriteFrameViewData();
1930 
1931         // Count page shapes.
1932         sal_uInt32 nShapeCount (0);
1933         SdrObjListIter aShapeIter (rHandoutPage);
1934         while (aShapeIter.IsMore())
1935         {
1936             SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
1937             if (pPageObj)
1938                 ++nShapeCount;
1939         }
1940 
1941 		const sal_uInt16 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1942 		const sal_uInt16 nHandoutPageCount = nShapeCount ? (nPageCount + nShapeCount - 1) / nShapeCount : 0;
1943 		pViewShell->SetPrintedHandoutPageCount( nHandoutPageCount );
1944 		mrBase.GetDocument()->setHandoutPageCount( nHandoutPageCount );
1945 
1946         // Distribute pages to handout pages.
1947         ::std::vector<sal_uInt16> aPageIndices;
1948         for (sal_uInt16
1949                  nIndex=0,
1950                  nCount= nPageCount,
1951                  nHandoutPageIndex=0;
1952              nIndex <= nCount;
1953              ++nIndex)
1954         {
1955             if (nIndex < nCount)
1956             {
1957                 if (GetFilteredPage(nIndex, PK_STANDARD, rInfo) == NULL)
1958                     continue;
1959                 aPageIndices.push_back(nIndex);
1960             }
1961 
1962             // Create a printer page when we have found one page for each
1963             // placeholder or when this is the last (and special) loop.
1964             if (!aPageIndices.empty() && (aPageIndices.size() == nShapeCount || nIndex==nCount))
1965             {
1966                 maPrinterPages.push_back(
1967                     ::boost::shared_ptr<PrinterPage>(
1968                         new HandoutPrinterPage(
1969                             nHandoutPageIndex++,
1970                             aPageIndices,
1971                             aMap,
1972                             rInfo.msTimeDate,
1973                             aPageOfs,
1974                             rInfo.mnDrawMode,
1975                             rInfo.meOrientation,
1976                             nPaperBin)));
1977                 aPageIndices.clear();
1978             }
1979         }
1980 	}
1981 
1982 
1983 
1984 
1985     /** Prepare the notes pages or regular slides.
1986     */
1987     void PrepareStdOrNotes (
1988         const PageKind ePageKind,
1989         PrintInfo& rInfo)
1990     {
1991         OSL_ASSERT(rInfo.mpPrinter != NULL);
1992 
1993         // Fill in page kind specific data.
1994         SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1995         if (pDocument->GetSdPageCount(ePageKind) == 0)
1996             return;
1997         SdPage* pRefPage = pDocument->GetSdPage(0, ePageKind);
1998         rInfo.maPageSize = pRefPage->GetSize();
1999 
2000         if ( ! SetupPaperOrientation(ePageKind, rInfo))
2001             return;
2002 
2003         MapMode aMap (rInfo.maMap);
2004         // aMap.SetOrigin(Point() - rInfo.mpPrinter->GetPageOffset());
2005         rInfo.maMap = aMap;
2006 
2007         if (mpOptions->IsBooklet())
2008             PrepareBooklet(ePageKind, rInfo);
2009         else
2010             PrepareRegularPages(ePageKind, rInfo);
2011     }
2012 
2013 
2014 
2015 
2016     /** Prepare slides in a non-booklet way: one slide per one to many
2017         printer pages.
2018     */
2019     void PrepareRegularPages (
2020         const PageKind ePageKind,
2021         PrintInfo& rInfo)
2022     {
2023         ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
2024         pViewShell->WriteFrameViewData();
2025         Point aPtZero;
2026 
2027         for (sal_uInt16
2028                  nIndex=0,
2029                  nCount=mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
2030              nIndex < nCount;
2031              ++nIndex)
2032         {
2033             SdPage* pPage = GetFilteredPage(nIndex, ePageKind, rInfo);
2034             if (pPage == NULL)
2035                 continue;
2036 
2037             MapMode aMap (rInfo.maMap);
2038             // Kann sich die Seitengroesse geaendert haben?
2039             const Size aPageSize = pPage->GetSize();
2040 
2041             if (mpOptions->IsPageSize())
2042             {
2043                 const double fHorz ((double) rInfo.maPrintSize.Width()	/ aPageSize.Width());
2044                 const double fVert ((double) rInfo.maPrintSize.Height() / aPageSize.Height());
2045 
2046                 Fraction aFract;
2047                 if (fHorz < fVert)
2048                     aFract = Fraction(rInfo.maPrintSize.Width(), aPageSize.Width());
2049                 else
2050                     aFract = Fraction(rInfo.maPrintSize.Height(), aPageSize.Height());
2051 
2052                 aMap.SetScaleX(aFract);
2053                 aMap.SetScaleY(aFract);
2054                 aMap.SetOrigin(Point());
2055             }
2056 
2057             if (mpOptions->IsPrintPageName())
2058             {
2059                 rInfo.msPageString = pPage->GetName();
2060                 rInfo.msPageString += ::rtl::OUString(sal_Unicode(' '));
2061             }
2062             else
2063                 rInfo.msPageString = ::rtl::OUString();
2064             rInfo.msPageString += rInfo.msTimeDate;
2065 
2066             long aPageWidth   = aPageSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder();
2067             long aPageHeight  = aPageSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder();
2068             // Bugfix zu 44530:
2069             // Falls implizit umgestellt wurde (Landscape/Portrait)
2070             // wird dies beim Kacheln, bzw. aufteilen (Poster) beruecksichtigt
2071             sal_Bool bSwitchPageSize = sal_False;
2072             if( ( rInfo.maPrintSize.Width() > rInfo.maPrintSize.Height()
2073                     && aPageWidth < aPageHeight )
2074                 || ( rInfo.maPrintSize.Width() < rInfo.maPrintSize.Height()
2075                     && aPageWidth > aPageHeight ) )
2076             {
2077                 bSwitchPageSize = sal_True;
2078                 const sal_Int32 nTmp (rInfo.maPrintSize.Width());
2079                 rInfo.maPrintSize.Width() = rInfo.maPrintSize.Height();
2080                 rInfo.maPrintSize.Height() = nTmp;
2081             }
2082 
2083             if (mpOptions->IsTilePage()
2084                 && aPageWidth < rInfo.maPrintSize.Width()
2085                 && aPageHeight < rInfo.maPrintSize.Height())
2086             {
2087                 // Put multiple slides on one printer page.
2088                 PrepareTiledPage(nIndex, *pPage, ePageKind, rInfo);
2089             }
2090             else
2091             {
2092                 rInfo.maMap = aMap;
2093                 PrepareScaledPage(nIndex, *pPage, ePageKind, rInfo);
2094             }
2095         }
2096     }
2097 
2098 
2099 
2100 
2101     /** Put two slides on one printer page.
2102     */
2103     void PrepareBooklet (
2104         const PageKind ePageKind,
2105         const PrintInfo& rInfo)
2106     {
2107         MapMode aStdMap (rInfo.maMap);
2108         Point aOffset;
2109         Size aPrintSize_2 (rInfo.maPrintSize);
2110         Size aPageSize_2 (rInfo.maPageSize);
2111 
2112         if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2113             aPrintSize_2.Width() >>= 1;
2114         else
2115             aPrintSize_2.Height() >>= 1;
2116 
2117         const double fPageWH = (double) aPageSize_2.Width() / aPageSize_2.Height();
2118         const double fPrintWH = (double) aPrintSize_2.Width() / aPrintSize_2.Height();
2119 
2120         if( fPageWH < fPrintWH )
2121         {
2122             aPageSize_2.Width() = (long) ( aPrintSize_2.Height() * fPageWH );
2123             aPageSize_2.Height()= aPrintSize_2.Height();
2124         }
2125         else
2126         {
2127             aPageSize_2.Width() = aPrintSize_2.Width();
2128             aPageSize_2.Height() = (long) ( aPrintSize_2.Width() / fPageWH );
2129         }
2130 
2131         MapMode aMap (rInfo.maMap);
2132         aMap.SetScaleX( Fraction( aPageSize_2.Width(), rInfo.maPageSize.Width() ) );
2133         aMap.SetScaleY( Fraction( aPageSize_2.Height(), rInfo.maPageSize.Height() ) );
2134 
2135         // calculate adjusted print size
2136         const Size aAdjustedPrintSize (OutputDevice::LogicToLogic(
2137             rInfo.maPrintSize,
2138             aStdMap,
2139             aMap));
2140 
2141         if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2142         {
2143             aOffset.X() = ( ( aAdjustedPrintSize.Width() >> 1 ) - rInfo.maPageSize.Width() ) >> 1;
2144             aOffset.Y() = ( aAdjustedPrintSize.Height() - rInfo.maPageSize.Height() ) >> 1;
2145         }
2146         else
2147         {
2148             aOffset.X() = ( aAdjustedPrintSize.Width() - rInfo.maPageSize.Width() ) >> 1;
2149             aOffset.Y() = ( ( aAdjustedPrintSize.Height() >> 1 ) - rInfo.maPageSize.Height() ) >> 1;
2150         }
2151 
2152         // create vector of pages to print
2153         ::std::vector< sal_uInt16 > aPageVector;
2154         for (sal_uInt16
2155                  nIndex=0,
2156                  nCount=mrBase.GetDocument()->GetSdPageCount(ePageKind);
2157              nIndex < nCount;
2158              ++nIndex)
2159         {
2160             SdPage* pPage = GetFilteredPage(nIndex, ePageKind, rInfo);
2161             if (pPage != NULL)
2162                 aPageVector.push_back(nIndex);
2163         }
2164 
2165         // create pairs of pages to print on each page
2166         typedef ::std::vector< ::std::pair< sal_uInt16, sal_uInt16 > > PairVector;
2167         PairVector aPairVector;
2168         if ( ! aPageVector.empty())
2169         {
2170             sal_uInt32 nFirstIndex = 0, nLastIndex = aPageVector.size() - 1;
2171 
2172             if( aPageVector.size() & 1 )
2173                 aPairVector.push_back( ::std::make_pair( (sal_uInt16) 65535, aPageVector[ nFirstIndex++ ] ) );
2174             else
2175                 aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2176 
2177             while( nFirstIndex < nLastIndex )
2178             {
2179                 if( nFirstIndex & 1 )
2180                     aPairVector.push_back( ::std::make_pair( aPageVector[ nFirstIndex++ ], aPageVector[ nLastIndex-- ] ) );
2181                 else
2182                     aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2183             }
2184         }
2185 
2186         for (sal_uInt32
2187                  nIndex=0,
2188                  nCount=aPairVector.size();
2189              nIndex < nCount;
2190              ++nIndex)
2191         {
2192             const bool bIsIndexOdd (nIndex & 1);
2193             if ((!bIsIndexOdd && mpOptions->IsPrintFrontPage())
2194                 || (bIsIndexOdd && mpOptions->IsPrintBackPage()))
2195             {
2196                 const ::std::pair<sal_uInt16, sal_uInt16> aPair (aPairVector[nIndex]);
2197                 Point aSecondOffset (aOffset);
2198                 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2199                     aSecondOffset.X() += aAdjustedPrintSize.Width() / 2;
2200                 else
2201                     aSecondOffset.Y() += aAdjustedPrintSize.Height() / 2;
2202                 maPrinterPages.push_back(
2203                     ::boost::shared_ptr<PrinterPage>(
2204                         new BookletPrinterPage(
2205                             aPair.first,
2206                             aPair.second,
2207                             aOffset,
2208                             aSecondOffset,
2209                             ePageKind,
2210                             aMap,
2211                             rInfo.mbPrintMarkedOnly,
2212                             rInfo.mnDrawMode,
2213                             rInfo.meOrientation,
2214                             rInfo.mpPrinter->GetPaperBin())));
2215 
2216             }
2217         }
2218     }
2219 
2220 
2221 
2222 
2223     /** Print one slide multiple times on one printer page so that the whole
2224         printer page is covered.
2225     */
2226     void PrepareTiledPage (
2227         const sal_Int32 nPageIndex,
2228         const SdPage& rPage,
2229         const PageKind ePageKind,
2230         const PrintInfo& rInfo)
2231     {
2232         sal_uInt16 nPaperBin;
2233         if ( ! mpOptions->IsPaperBin())
2234             nPaperBin = rPage.GetPaperBin();
2235         else
2236             nPaperBin = rInfo.mpPrinter->GetPaperBin();
2237 
2238         maPrinterPages.push_back(
2239             ::boost::shared_ptr<PrinterPage>(
2240                 new TiledPrinterPage(
2241                     sal::static_int_cast<sal_uInt16>(nPageIndex),
2242                     ePageKind,
2243                     500,
2244                     rInfo.mbPrintMarkedOnly,
2245                     rInfo.msPageString,
2246                     rInfo.mpPrinter->GetPageOffset(),
2247                     rInfo.mnDrawMode,
2248                     rInfo.meOrientation,
2249                     nPaperBin)));
2250     }
2251 
2252 
2253 
2254     /** Print one standard slide or notes page on one to many printer
2255         pages.  More than on printer page is used when the slide is larger
2256         than the printable area.
2257     */
2258     void PrepareScaledPage (
2259         const sal_Int32 nPageIndex,
2260         const SdPage& rPage,
2261         const PageKind ePageKind,
2262         const PrintInfo& rInfo)
2263     {
2264         const Point aPageOffset (rInfo.mpPrinter->GetPageOffset());
2265 
2266         sal_uInt16 nPaperBin;
2267         if ( ! mpOptions->IsPaperBin())
2268             nPaperBin = rPage.GetPaperBin();
2269         else
2270             nPaperBin = rInfo.mpPrinter->GetPaperBin();
2271 
2272         // For pages larger then the printable area there
2273         // are three options:
2274         // 1. Scale down to the page to the printable area.
2275         // 2. Print only the upper left part of the page
2276         //    (without the unprintable borders).
2277         // 3. Split the page into parts of the size of the
2278         // printable area.
2279         const bool bScalePage (mpOptions->IsPageSize());
2280         const bool bCutPage (mpOptions->IsCutPage());
2281         MapMode aMap (rInfo.maMap);
2282         if (bScalePage || bCutPage)
2283         {
2284             // Handle 1 and 2.
2285 
2286             // if CutPage is set then do not move it, otherwise move the
2287             // scaled page to printable area
2288             #if 0
2289             if (bCutPage)
2290                 aMap.SetOrigin(Point(-aPageOffset.X(), -aPageOffset.Y()));
2291             else
2292                 aMap.SetOrigin(Point(0,0));
2293             #endif
2294             maPrinterPages.push_back(
2295                 ::boost::shared_ptr<PrinterPage>(
2296                     new RegularPrinterPage(
2297                         sal::static_int_cast<sal_uInt16>(nPageIndex),
2298                         ePageKind,
2299                         aMap,
2300                         rInfo.mbPrintMarkedOnly,
2301                         rInfo.msPageString,
2302                         aPageOffset,
2303                         rInfo.mnDrawMode,
2304                         rInfo.meOrientation,
2305                         nPaperBin)));
2306         }
2307         else
2308         {
2309             // Handle 3.  Print parts of the page in the size of the
2310             // printable area until the whole page is covered.
2311 
2312             // keep the page content at its position if it fits, otherwise
2313             // move it to the printable area
2314             const long nPageWidth (
2315                 rInfo.maPageSize.Width() - rPage.GetLftBorder() - rPage.GetRgtBorder());
2316             const long nPageHeight (
2317                 rInfo.maPageSize.Height() - rPage.GetUppBorder() - rPage.GetLwrBorder());
2318             #if 0
2319             Point aOrigin (
2320                 nPageWidth < rInfo.maPrintSize.Width() ? -aPageOffset.X() : 0,
2321                 nPageHeight < rInfo.maPrintSize.Height() ? -aPageOffset.Y() : 0);
2322             #else
2323             Point aOrigin ( 0, 0 );
2324             #endif
2325             for (Point aPageOrigin = aOrigin;
2326                  -aPageOrigin.Y()<nPageHeight;
2327                  aPageOrigin.Y() -= rInfo.maPrintSize.Height())
2328             {
2329                 for (aPageOrigin.X()=aOrigin.X();
2330                      -aPageOrigin.X()<nPageWidth;
2331                      aPageOrigin.X() -= rInfo.maPrintSize.Width())
2332                 {
2333                     aMap.SetOrigin(aPageOrigin);
2334                     maPrinterPages.push_back(
2335                         ::boost::shared_ptr<PrinterPage>(
2336                             new RegularPrinterPage(
2337                                 sal::static_int_cast<sal_uInt16>(nPageIndex),
2338                                 ePageKind,
2339                                 aMap,
2340                                 rInfo.mbPrintMarkedOnly,
2341                                 rInfo.msPageString,
2342                                 aPageOffset,
2343                                 rInfo.mnDrawMode,
2344                                 rInfo.meOrientation,
2345                                 nPaperBin)));
2346                 }
2347             }
2348         }
2349     }
2350 };
2351 
2352 
2353 
2354 
2355 //===== DocumentRenderer ======================================================
2356 
2357 DocumentRenderer::DocumentRenderer (ViewShellBase& rBase)
2358     : DocumentRendererInterfaceBase(m_aMutex),
2359       mpImpl(new Implementation(rBase))
2360 {
2361 }
2362 
2363 
2364 
2365 
2366 DocumentRenderer::~DocumentRenderer (void)
2367 {
2368 }
2369 
2370 
2371 
2372 
2373 //----- XRenderable -----------------------------------------------------------
2374 
2375 sal_Int32 SAL_CALL DocumentRenderer::getRendererCount (
2376     const css::uno::Any& aSelection,
2377     const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
2378     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2379 {
2380     (void)aSelection;
2381     mpImpl->ProcessProperties(rOptions);
2382     return mpImpl->GetPrintPageCount();
2383 }
2384 
2385 
2386 
2387 
2388 Sequence<beans::PropertyValue> SAL_CALL DocumentRenderer::getRenderer (
2389     sal_Int32 nRenderer,
2390     const css::uno::Any& rSelection,
2391     const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2392     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2393 {
2394     (void)nRenderer;
2395     (void)rSelection;
2396     mpImpl->ProcessProperties(rOptions);
2397     return mpImpl->GetProperties(rOptions);
2398 }
2399 
2400 
2401 
2402 
2403 void SAL_CALL DocumentRenderer::render (
2404     sal_Int32 nRenderer,
2405     const css::uno::Any& rSelection,
2406     const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2407     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2408 {
2409     (void)rSelection;
2410     mpImpl->ProcessProperties(rOptions);
2411     mpImpl->PrintPage(nRenderer);
2412 }
2413 
2414 
2415 
2416 } // end of namespace sd
2417