bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / view / DocumentRenderer.cxx
blob734c61a636f134503e7d8053648a564d8a0e106a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include "DocumentRenderer.hxx"
23 #include "DocumentRenderer.hrc"
25 #include "drawdoc.hxx"
26 #include "optsitem.hxx"
27 #include "sdresid.hxx"
28 #include "strings.hrc"
29 #include "sdattr.hxx"
30 #include "Window.hxx"
31 #include "drawview.hxx"
32 #include "DrawViewShell.hxx"
33 #include "FrameView.hxx"
34 #include "Outliner.hxx"
35 #include "OutlineViewShell.hxx"
37 #include <basegfx/polygon/b2dpolygon.hxx>
38 #include <basegfx/polygon/b2dpolypolygon.hxx>
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <sfx2/printer.hxx>
41 #include <editeng/editstat.hxx>
42 #include <editeng/outlobj.hxx>
43 #include <svx/svdetc.hxx>
44 #include <svx/svditer.hxx>
45 #include <svx/svdopage.hxx>
46 #include <svx/svdopath.hxx>
47 #include <svx/xlnclit.hxx>
48 #include <toolkit/awt/vclxdevice.hxx>
49 #include <tools/resary.hxx>
50 #include <unotools/localedatawrapper.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <unotools/moduleoptions.hxx>
54 #include <vector>
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
59 namespace sd {
61 namespace {
63 /** Convenience class to extract values from the sequence of properties
64 given to one of the XRenderable methods.
66 class PrintOptions
68 public:
69 PrintOptions (
70 const vcl::PrinterOptionsHelper& rHelper,
71 const ::std::vector<sal_Int32>& rSlidesPerPage)
72 : mrProperties(rHelper),
73 maSlidesPerPage(rSlidesPerPage)
77 bool IsWarningOrientation() const
79 return GetBoolValue(NULL, true);
82 bool IsPrintPageName() const
84 return GetBoolValue("IsPrintName");
87 bool IsDate() const
89 return GetBoolValue("IsPrintDateTime");
92 bool IsTime() const
94 return GetBoolValue("IsPrintDateTime");
97 bool IsHiddenPages() const
99 return GetBoolValue("IsPrintHidden");
102 bool IsHandoutHorizontal() const
104 return GetBoolValue("SlidesPerPageOrder", sal_Int32(0));
107 sal_Int32 GetHandoutPageCount() const
109 sal_uInt32 nIndex = static_cast<sal_Int32>(mrProperties.getIntValue("SlidesPerPage", sal_Int32(0)));
110 if (nIndex<maSlidesPerPage.size())
111 return maSlidesPerPage[nIndex];
112 else if ( ! maSlidesPerPage.empty())
113 return maSlidesPerPage[0];
114 else
115 return 0;
118 bool IsDraw() const
120 return GetBoolValue("PageContentType", sal_Int32(0));
123 bool IsHandout() const
125 return GetBoolValue("PageContentType", sal_Int32(1));
128 bool IsNotes() const
130 return GetBoolValue("PageContentType", sal_Int32(2));
133 bool IsOutline() const
135 return GetBoolValue("PageContentType", sal_Int32(3));
138 sal_uLong GetOutputQuality() const
140 sal_Int32 nQuality = static_cast<sal_Int32>(mrProperties.getIntValue( "Quality", sal_Int32(0) ));
141 return nQuality;
144 bool IsPageSize() const
146 return GetBoolValue("PageOptions", sal_Int32(1));
149 bool IsTilePage() const
151 return GetBoolValue("PageOptions", sal_Int32(2)) || GetBoolValue("PageOptions", sal_Int32(3));
154 bool IsCutPage() const
156 return GetBoolValue("PageOptions", sal_Int32(0));
159 bool IsBooklet() const
161 return GetBoolValue("PrintProspect", false);
164 bool IsPrinterPreferred(DocumentType eDocType) const
166 bool bIsDraw = eDocType == DOCUMENT_TYPE_DRAW;
167 return IsTilePage() || IsPageSize() || IsBooklet() || (!bIsDraw && !IsNotes());
170 bool IsPrintExcluded() const
172 return (IsNotes() || IsDraw() || IsHandout()) && IsHiddenPages();
175 bool IsPrintFrontPage() const
177 sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
178 return nInclude == 0 || nInclude == 1;
181 bool IsPrintBackPage() const
183 sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
184 return nInclude == 0 || nInclude == 2;
187 bool IsPaperBin() const
189 return GetBoolValue("PrintPaperFromSetup", false);
192 bool IsPrintMarkedOnly() const
194 return GetBoolValue("PrintContent", sal_Int32(2));
197 OUString GetPrinterSelection (sal_Int32 nPageCount, sal_Int32 nCurrentPageIndex) const
199 sal_Int32 nContent = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintContent", 0 ));
200 OUString sFullRange = "1-" + OUString::number(nPageCount);
202 if (nContent == 0) // all pages/slides
204 return sFullRange;
207 if (nContent == 1) // range
209 OUString sValue = mrProperties.getStringValue("PageRange");
210 return sValue.isEmpty() ? sFullRange : sValue;
213 if (nContent == 2 && // selection
214 nCurrentPageIndex >= 0)
216 return OUString::number(nCurrentPageIndex + 1);
219 return OUString();
222 private:
223 const vcl::PrinterOptionsHelper& mrProperties;
224 const ::std::vector<sal_Int32> maSlidesPerPage;
226 /** When the value of the property with name pName is a boolean then
227 return its value. When the property is unknown then
228 bDefaultValue is returned. Otherwise <FALSE/> is returned.
230 bool GetBoolValue (
231 const sal_Char* pName,
232 const bool bDefaultValue = false) const
234 bool bValue = mrProperties.getBoolValue( pName, bDefaultValue );
235 return bValue;
238 /** Return <TRUE/> when the value of the property with name pName is
239 an integer and its value is nTriggerValue. Otherwise <FALSE/> is
240 returned.
242 bool GetBoolValue (
243 const sal_Char* pName,
244 const sal_Int32 nTriggerValue) const
246 sal_Int32 nValue = static_cast<sal_Int32>(mrProperties.getIntValue( pName ));
247 return nValue == nTriggerValue;
251 /** A collection of values that helps to reduce the number of arguments
252 given to some functions. Note that not all values are set at the
253 same time.
255 class PrintInfo
257 public:
258 PrintInfo (
259 Printer* pPrinter,
260 const bool bPrintMarkedOnly)
261 : mpPrinter(pPrinter),
262 mnDrawMode(DrawModeFlags::Default),
263 msTimeDate(),
264 msPageString(),
265 maPrintSize(0,0),
266 maPageSize(0,0),
267 meOrientation(ORIENTATION_PORTRAIT),
268 maMap(),
269 mbPrintMarkedOnly(bPrintMarkedOnly)
272 const VclPtr<Printer> mpPrinter;
273 DrawModeFlags mnDrawMode;
274 OUString msTimeDate;
275 OUString msPageString;
276 Size maPrintSize;
277 Size maPageSize;
278 Orientation meOrientation;
279 MapMode maMap;
280 const bool mbPrintMarkedOnly;
283 /** Output one page of the document to the given printer. Note that
284 more than one document page may be output to one printer page.
286 void PrintPage (
287 Printer& rPrinter,
288 ::sd::View& rPrintView,
289 SdPage& rPage,
290 View* pView,
291 const bool bPrintMarkedOnly,
292 const SetOfByte& rVisibleLayers,
293 const SetOfByte& rPrintableLayers)
295 rPrintView.ShowSdrPage(&rPage);
297 const MapMode aOriginalMapMode (rPrinter.GetMapMode());
299 // Set the visible layers
300 SdrPageView* pPageView = rPrintView.GetSdrPageView();
301 OSL_ASSERT(pPageView!=NULL);
302 pPageView->SetVisibleLayers(rVisibleLayers);
303 pPageView->SetPrintableLayers(rPrintableLayers);
305 if (pView!=NULL && bPrintMarkedOnly)
306 pView->DrawMarkedObj(rPrinter);
307 else
308 rPrintView.CompleteRedraw(&rPrinter,
309 vcl::Region(Rectangle(Point(0,0), rPage.GetSize())));
311 rPrinter.SetMapMode(aOriginalMapMode);
313 rPrintView.HideSdrPage();
316 /** Output a string (that typically is not part of a document page) to
317 the given printer.
319 void PrintMessage (
320 Printer& rPrinter,
321 const OUString& rsPageString,
322 const Point& rPageStringOffset)
324 const vcl::Font aOriginalFont (rPrinter.OutputDevice::GetFont());
325 rPrinter.SetFont(vcl::Font(FAMILY_SWISS, Size(0, 423)));
326 rPrinter.DrawText(rPageStringOffset, rsPageString);
327 rPrinter.SetFont(aOriginalFont);
330 /** Read the resource file and process it into a sequence of properties
331 that can be passed to the printing dialog.
333 class DialogCreator : Resource
335 public:
336 DialogCreator (bool bImpress, sal_Int32 nCurPage)
337 : Resource(SdResId(_STR_IMPRESS_PRINT_UI_OPTIONS))
338 , mbImpress(bImpress)
339 , mnCurPage(nCurPage)
341 ProcessResource();
344 Sequence< beans::PropertyValue > GetDialogControls() const
346 if (maProperties.empty())
347 return Sequence< beans::PropertyValue >();
348 else
350 return Sequence<beans::PropertyValue>(
351 &maProperties.front(),
352 maProperties.size());
356 ::std::vector<sal_Int32> GetSlidesPerPage() const
358 return maSlidesPerPage;
361 private:
362 ::std::vector<beans::PropertyValue> maProperties;
363 ::std::vector<sal_Int32> maSlidesPerPage;
364 bool mbImpress;
365 sal_Int32 mnCurPage;
367 void ProcessResource()
369 // load the writer PrinterOptions into the custom tab
370 beans::PropertyValue aOptionsUIFile;
371 aOptionsUIFile.Name = "OptionsUIFile";
372 if( mbImpress )
373 aOptionsUIFile.Value <<= OUString("modules/simpress/ui/printeroptions.ui");
374 else
375 aOptionsUIFile.Value <<= OUString("modules/sdraw/ui/printeroptions.ui");
376 maProperties.push_back(aOptionsUIFile);
378 SvtModuleOptions aOpt;
379 OUString aAppGroupname(SD_RESSTR(_STR_IMPRESS_PRINT_UI_GROUP_NAME));
380 aAppGroupname = aAppGroupname.replaceFirst("%s", aOpt.GetModuleName(
381 mbImpress ? SvtModuleOptions::EModule::IMPRESS : SvtModuleOptions::EModule::DRAW));
382 AddDialogControl(vcl::PrinterOptionsHelper::setGroupControlOpt("tabcontrol-page2", aAppGroupname, ".HelpID:vcl:PrintDialog:TabPage:AppPage"));
384 uno::Sequence< OUString > aHelpIds, aWidgetIds;
385 if( mbImpress )
387 vcl::PrinterOptionsHelper::UIControlOptions aPrintOpt;
388 aPrintOpt.maGroupHint = "JobPage" ;
389 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("extraimpressprintoptions",
390 SD_RESSTR(_STR_IMPRESS_PRINT_UI_PRINT_GROUP),
392 aPrintOpt ));
394 aHelpIds.realloc( 1 );
395 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PageContentType:ListBox" ;
396 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
397 "impressdocument",
398 SD_RESSTR(_STR_IMPRESS_PRINT_UI_CONTENT),
399 aHelpIds,
400 "PageContentType" ,
401 CreateChoice(_STR_IMPRESS_PRINT_UI_CONTENT_CHOICES),
405 aHelpIds[0] = ".HelpID:vcl:PrintDialog:SlidesPerPage:ListBox" ;
406 vcl::PrinterOptionsHelper::UIControlOptions aContentOpt( "PageContentType" , 1 );
407 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
408 "slidesperpage",
409 SD_RESSTR(_STR_IMPRESS_PRINT_UI_SLIDESPERPAGE),
410 aHelpIds,
411 "SlidesPerPage" ,
412 GetSlidesPerPageSequence(),
414 Sequence< sal_Bool >(),
415 aContentOpt
419 aHelpIds[0] = ".HelpID:vcl:PrintDialog:SlidesPerPageOrder:ListBox" ;
420 vcl::PrinterOptionsHelper::UIControlOptions aSlidesPerPageOpt( "SlidesPerPage" , -1, true );
421 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
422 "slidesperpageorder",
423 SD_RESSTR(_STR_IMPRESS_PRINT_UI_ORDER),
424 aHelpIds,
425 "SlidesPerPageOrder" ,
426 CreateChoice(_STR_IMPRESS_PRINT_UI_ORDER_CHOICES),
428 Sequence< sal_Bool >(),
429 aSlidesPerPageOpt )
433 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("contents",
434 SD_RESSTR(_STR_IMPRESS_PRINT_UI_INCLUDE_CONTENT), "" ) );
436 if( mbImpress )
438 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printname",
439 SD_RESSTR(_STR_IMPRESS_PRINT_UI_IS_PRINT_NAME),
440 ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ,
441 "IsPrintName" ,
442 false
446 else
448 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printname",
449 SD_RESSTR(_STR_DRAW_PRINT_UI_IS_PRINT_NAME),
450 ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ,
451 "IsPrintName" ,
452 false
457 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printdatetime",
458 SD_RESSTR(_STR_IMPRESS_PRINT_UI_IS_PRINT_DATE),
459 ".HelpID:vcl:PrintDialog:IsPrintDateTime:CheckBox" ,
460 "IsPrintDateTime" ,
461 false
465 if( mbImpress )
467 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printhidden",
468 SD_RESSTR(_STR_IMPRESS_PRINT_UI_IS_PRINT_HIDDEN),
469 ".HelpID:vcl:PrintDialog:IsPrintHidden:CheckBox" ,
470 "IsPrintHidden" ,
471 false
476 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("color",
477 SD_RESSTR(_STR_IMPRESS_PRINT_UI_QUALITY), "" ) );
479 aHelpIds.realloc( 3 );
480 aHelpIds[0] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:0" ;
481 aHelpIds[1] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:1" ;
482 aHelpIds[2] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:2" ;
483 aWidgetIds.realloc( 3 );
484 aWidgetIds[0] = "originalcolors";
485 aWidgetIds[1] = "grayscale";
486 aWidgetIds[2] = "blackandwhite";
487 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(
488 aWidgetIds,
490 aHelpIds,
491 "Quality" ,
492 CreateChoice(_STR_IMPRESS_PRINT_UI_QUALITY_CHOICES),
496 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("pagesizes",
497 SD_RESSTR(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS), "" ) );
499 aHelpIds.realloc( 4 );
500 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:0" ;
501 aHelpIds[1] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:1" ;
502 aHelpIds[2] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:2" ;
503 aHelpIds[3] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:3" ;
504 aWidgetIds.realloc( 4 );
505 aWidgetIds[0] = "originalsize";
506 aWidgetIds[1] = "fittoprintable";
507 aWidgetIds[2] = "distributeonmultiple";
508 aWidgetIds[3] = "tilesheet";
510 vcl::PrinterOptionsHelper::UIControlOptions aPageOptionsOpt("PrintProspect", 0);
511 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(
512 aWidgetIds,
514 aHelpIds,
515 "PageOptions" ,
516 CreateChoice(mbImpress ? _STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES : _STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES_DRAW),
518 Sequence< sal_Bool >(),
519 aPageOptionsOpt
523 vcl::PrinterOptionsHelper::UIControlOptions aBrochureOpt;
524 aBrochureOpt.maGroupHint = "LayoutPage" ;
525 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("pagesides",
526 SD_RESSTR(_STR_IMPRESS_PRINT_UI_PAGE_SIDES), "",
527 aBrochureOpt ) );
529 // brochure printing
530 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("brochure",
531 SD_RESSTR(_STR_IMPRESS_PRINT_UI_BROCHURE),
532 ".HelpID:vcl:PrintDialog:PrintProspect:CheckBox" ,
533 "PrintProspect" ,
534 false,
535 aBrochureOpt
539 vcl::PrinterOptionsHelper::UIControlOptions
540 aIncludeOpt( "PrintProspect" , -1, false );
541 aIncludeOpt.maGroupHint = "LayoutPage" ;
542 aHelpIds.realloc( 1 );
543 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PrintProspectInclude:ListBox" ;
544 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
545 "brochureinclude",
546 SD_RESSTR(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE),
547 aHelpIds,
548 "PrintProspectInclude" ,
549 CreateChoice(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE_LIST),
551 Sequence< sal_Bool >(),
552 aIncludeOpt
556 // paper tray (on options page)
557 vcl::PrinterOptionsHelper::UIControlOptions aPaperTrayOpt;
558 aPaperTrayOpt.maGroupHint = "OptionsPageOptGroup" ;
559 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printpaperfromsetup",
560 SD_RESSTR(_STR_IMPRESS_PRINT_UI_PAPER_TRAY),
561 ".HelpID:vcl:PrintDialog:PrintPaperFromSetup:CheckBox" ,
562 "PrintPaperFromSetup" ,
563 false,
564 aPaperTrayOpt
567 // print range selection
568 vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
569 aPrintRangeOpt.mbInternalOnly = true;
570 aPrintRangeOpt.maGroupHint = "PrintRange" ;
571 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("printrange",
572 SD_RESSTR(_STR_IMPRESS_PRINT_UI_PAGE_RANGE),
574 aPrintRangeOpt )
577 // create a choice for the content to create
578 OUString aPrintRangeName( "PrintContent" );
579 aHelpIds.realloc( 3 );
580 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ;
581 aHelpIds[1] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ;
582 aHelpIds[2] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2" ;
583 aWidgetIds.realloc( 3 );
584 aWidgetIds[0] = "printallpages";
585 aWidgetIds[1] = "printpages";
586 aWidgetIds[2] = "printselection";
587 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(aWidgetIds, "",
588 aHelpIds,
589 aPrintRangeName,
590 CreateChoice(mbImpress
591 ? _STR_IMPRESS_PRINT_UI_PAGE_RANGE_CHOICE
592 : _STR_DRAW_PRINT_UI_PAGE_RANGE_CHOICE),
595 // create a an Edit dependent on "Pages" selected
596 vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, true );
597 AddDialogControl(vcl::PrinterOptionsHelper::setEditControlOpt("pagerange", "",
598 ".HelpID:vcl:PrintDialog:PageRange:Edit", "PageRange",
599 OUString::number(mnCurPage + 1), aPageRangeOpt));
601 FreeResource();
604 void AddDialogControl( const Any& i_rCtrl )
606 beans::PropertyValue aVal;
607 aVal.Value = i_rCtrl;
608 maProperties.push_back( aVal );
611 static Sequence<OUString> CreateChoice (const sal_uInt16 nResourceId)
613 SdResId aResourceId (nResourceId);
614 ResStringArray aChoiceStrings (aResourceId);
616 const sal_uInt32 nCount (aChoiceStrings.Count());
617 Sequence<OUString> aChoices (nCount);
618 for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex)
619 aChoices[nIndex] = aChoiceStrings.GetString(nIndex);
621 return aChoices;
624 Sequence<OUString> GetSlidesPerPageSequence()
626 const Sequence<OUString> aChoice (
627 CreateChoice(_STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES));
628 maSlidesPerPage.clear();
629 maSlidesPerPage.push_back(0); // first is using the default
630 for (sal_Int32 nIndex=1,nCount=aChoice.getLength(); nIndex<nCount; ++nIndex)
631 maSlidesPerPage.push_back(aChoice[nIndex].toInt32());
632 return aChoice;
636 /** The Prepare... methods of the DocumentRenderer::Implementation class
637 create a set of PrinterPage objects that contain all necessary
638 information to do the actual printing. There is one PrinterPage
639 object per printed page. Derived classes implement the actual, mode
640 specific printing.
642 This and all derived classes support the asynchronous printing
643 process by not storing pointers to any data with lifetime shorter
644 than the PrinterPage objects, i.e. slides, shapes, (one of) the
645 outliner (of the document).
647 class PrinterPage
649 public:
650 PrinterPage (
651 const PageKind ePageKind,
652 const MapMode& rMapMode,
653 const bool bPrintMarkedOnly,
654 const OUString& rsPageString,
655 const Point& rPageStringOffset,
656 const DrawModeFlags nDrawMode,
657 const Orientation eOrientation,
658 const sal_uInt16 nPaperTray)
659 : mePageKind(ePageKind),
660 maMap(rMapMode),
661 mbPrintMarkedOnly(bPrintMarkedOnly),
662 msPageString(rsPageString),
663 maPageStringOffset(rPageStringOffset),
664 mnDrawMode(nDrawMode),
665 meOrientation(eOrientation),
666 mnPaperTray(nPaperTray)
670 virtual ~PrinterPage() {}
672 virtual void Print (
673 Printer& rPrinter,
674 SdDrawDocument& rDocument,
675 ViewShell& rViewShell,
676 View* pView,
677 DrawView& rPrintView,
678 const SetOfByte& rVisibleLayers,
679 const SetOfByte& rPrintableLayers) const = 0;
681 DrawModeFlags GetDrawMode() const { return mnDrawMode; }
682 Orientation GetOrientation() const { return meOrientation; }
683 sal_uInt16 GetPaperTray() const { return mnPaperTray; }
685 protected:
686 const PageKind mePageKind;
687 const MapMode maMap;
688 const bool mbPrintMarkedOnly;
689 const OUString msPageString;
690 const Point maPageStringOffset;
691 const DrawModeFlags mnDrawMode;
692 const Orientation meOrientation;
693 const sal_uInt16 mnPaperTray;
696 /** The RegularPrinterPage is used for printing one regular slide (no
697 notes, handout, or outline) to one printer page.
699 class RegularPrinterPage : public PrinterPage
701 public:
702 RegularPrinterPage (
703 const sal_uInt16 nPageIndex,
704 const PageKind ePageKind,
705 const MapMode& rMapMode,
706 const bool bPrintMarkedOnly,
707 const OUString& rsPageString,
708 const Point& rPageStringOffset,
709 const DrawModeFlags nDrawMode,
710 const Orientation eOrientation,
711 const sal_uInt16 nPaperTray)
712 : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, rsPageString,
713 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
714 mnPageIndex(nPageIndex)
718 virtual ~RegularPrinterPage() {}
720 virtual void Print (
721 Printer& rPrinter,
722 SdDrawDocument& rDocument,
723 ViewShell& rViewShell,
724 View* pView,
725 DrawView& rPrintView,
726 const SetOfByte& rVisibleLayers,
727 const SetOfByte& rPrintableLayers) const SAL_OVERRIDE
729 (void)rViewShell;
730 SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
731 rPrinter.SetMapMode(maMap);
732 PrintPage(
733 rPrinter,
734 rPrintView,
735 *pPageToPrint,
736 pView,
737 mbPrintMarkedOnly,
738 rVisibleLayers,
739 rPrintableLayers);
740 PrintMessage(
741 rPrinter,
742 msPageString,
743 maPageStringOffset);
746 private:
747 const sal_uInt16 mnPageIndex;
750 /** Print one slide multiple times on a printer page so that the whole
751 printer page is covered.
753 class TiledPrinterPage : public PrinterPage
755 public:
756 TiledPrinterPage (
757 const sal_uInt16 nPageIndex,
758 const PageKind ePageKind,
759 const sal_Int32 nGap,
760 const bool bPrintMarkedOnly,
761 const OUString& rsPageString,
762 const Point& rPageStringOffset,
763 const DrawModeFlags nDrawMode,
764 const Orientation eOrientation,
765 const sal_uInt16 nPaperTray)
766 : PrinterPage(ePageKind, MapMode(), bPrintMarkedOnly, rsPageString,
767 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
768 mnPageIndex(nPageIndex),
769 mnGap(nGap)
773 virtual ~TiledPrinterPage() {}
775 virtual void Print (
776 Printer& rPrinter,
777 SdDrawDocument& rDocument,
778 ViewShell& rViewShell,
779 View* pView,
780 DrawView& rPrintView,
781 const SetOfByte& rVisibleLayers,
782 const SetOfByte& rPrintableLayers) const SAL_OVERRIDE
784 (void)rViewShell;
785 SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
786 if (pPageToPrint==NULL)
787 return;
788 MapMode aMap (rPrinter.GetMapMode());
790 const Size aPageSize (pPageToPrint->GetSize());
791 const Size aPrintSize (rPrinter.GetOutputSize());
793 const sal_Int32 nPageWidth (aPageSize.Width() + mnGap
794 - pPageToPrint->GetLftBorder() - pPageToPrint->GetRgtBorder());
795 const sal_Int32 nPageHeight (aPageSize.Height() + mnGap
796 - pPageToPrint->GetUppBorder() - pPageToPrint->GetLwrBorder());
797 if (nPageWidth<=0 || nPageHeight<=0)
798 return;
800 // Print at least two rows and columns. More if the document
801 // page fits completely onto the printer page.
802 const sal_Int32 nColumnCount (::std::max(sal_Int32(2),
803 sal_Int32(aPrintSize.Width() / nPageWidth)));
804 const sal_Int32 nRowCount (::std::max(sal_Int32(2),
805 sal_Int32(aPrintSize.Height() / nPageHeight)));
806 for (sal_Int32 nRow=0; nRow<nRowCount; ++nRow)
807 for (sal_Int32 nColumn=0; nColumn<nColumnCount; ++nColumn)
809 aMap.SetOrigin(Point(nColumn*nPageWidth,nRow*nPageHeight));
810 rPrinter.SetMapMode(aMap);
811 PrintPage(
812 rPrinter,
813 rPrintView,
814 *pPageToPrint,
815 pView,
816 mbPrintMarkedOnly,
817 rVisibleLayers,
818 rPrintableLayers);
821 PrintMessage(
822 rPrinter,
823 msPageString,
824 maPageStringOffset);
827 private:
828 const sal_uInt16 mnPageIndex;
829 const sal_Int32 mnGap;
832 /** Print two slides to one printer page so that the resulting pages
833 form a booklet.
835 class BookletPrinterPage : public PrinterPage
837 public:
838 BookletPrinterPage (
839 const sal_uInt16 nFirstPageIndex,
840 const sal_uInt16 nSecondPageIndex,
841 const Point& rFirstOffset,
842 const Point& rSecondOffset,
843 const PageKind ePageKind,
844 const MapMode& rMapMode,
845 const bool bPrintMarkedOnly,
846 const DrawModeFlags nDrawMode,
847 const Orientation eOrientation,
848 const sal_uInt16 nPaperTray)
849 : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, "",
850 Point(), nDrawMode, eOrientation, nPaperTray),
851 mnFirstPageIndex(nFirstPageIndex),
852 mnSecondPageIndex(nSecondPageIndex),
853 maFirstOffset(rFirstOffset),
854 maSecondOffset(rSecondOffset)
858 virtual ~BookletPrinterPage() {}
860 virtual void Print (
861 Printer& rPrinter,
862 SdDrawDocument& rDocument,
863 ViewShell& rViewShell,
864 View* pView,
865 DrawView& rPrintView,
866 const SetOfByte& rVisibleLayers,
867 const SetOfByte& rPrintableLayers) const SAL_OVERRIDE
869 (void)rViewShell;
870 MapMode aMap (maMap);
871 SdPage* pPageToPrint = rDocument.GetSdPage(mnFirstPageIndex, mePageKind);
872 if (pPageToPrint)
874 aMap.SetOrigin(maFirstOffset);
875 rPrinter.SetMapMode(aMap);
876 PrintPage(
877 rPrinter,
878 rPrintView,
879 *pPageToPrint,
880 pView,
881 mbPrintMarkedOnly,
882 rVisibleLayers,
883 rPrintableLayers);
886 pPageToPrint = rDocument.GetSdPage(mnSecondPageIndex, mePageKind);
887 if( pPageToPrint )
889 aMap.SetOrigin(maSecondOffset);
890 rPrinter.SetMapMode(aMap);
891 PrintPage(
892 rPrinter,
893 rPrintView,
894 *pPageToPrint,
895 pView,
896 mbPrintMarkedOnly,
897 rVisibleLayers,
898 rPrintableLayers);
902 private:
903 const sal_uInt16 mnFirstPageIndex;
904 const sal_uInt16 mnSecondPageIndex;
905 const Point maFirstOffset;
906 const Point maSecondOffset;
909 /** One handout page displays one to nine slides.
911 class HandoutPrinterPage : public PrinterPage
913 public:
914 HandoutPrinterPage (
915 const sal_uInt16 nHandoutPageIndex,
916 const ::std::vector<sal_uInt16>& rPageIndices,
917 const MapMode& rMapMode,
918 const OUString& rsPageString,
919 const Point& rPageStringOffset,
920 const DrawModeFlags nDrawMode,
921 const Orientation eOrientation,
922 const sal_uInt16 nPaperTray)
923 : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
924 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
925 mnHandoutPageIndex(nHandoutPageIndex),
926 maPageIndices(rPageIndices)
930 virtual void Print (
931 Printer& rPrinter,
932 SdDrawDocument& rDocument,
933 ViewShell& rViewShell,
934 View* pView,
935 DrawView& rPrintView,
936 const SetOfByte& rVisibleLayers,
937 const SetOfByte& rPrintableLayers) const SAL_OVERRIDE
939 SdPage& rHandoutPage (*rDocument.GetSdPage(0, PK_HANDOUT));
941 Reference< com::sun::star::beans::XPropertySet > xHandoutPage( rHandoutPage.getUnoPage(), UNO_QUERY );
942 const OUString sPageNumber( "Number" );
944 // Collect the page objects of the handout master.
945 std::vector<SdrPageObj*> aHandoutPageObjects;
946 SdrObjListIter aShapeIter (rHandoutPage);
947 while (aShapeIter.IsMore())
949 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
950 if (pPageObj)
951 aHandoutPageObjects.push_back(pPageObj);
953 if (aHandoutPageObjects.empty())
954 return;
956 // Connect page objects with pages.
957 std::vector<SdrPageObj*>::iterator aPageObjIter (aHandoutPageObjects.begin());
958 for (std::vector<sal_uInt16>::const_iterator
959 iPageIndex(maPageIndices.begin()),
960 iEnd(maPageIndices.end());
961 iPageIndex!=iEnd && aPageObjIter!=aHandoutPageObjects.end();
962 ++iPageIndex)
964 // Check if the page still exists.
965 if (*iPageIndex >= rDocument.GetSdPageCount(PK_STANDARD))
966 continue;
968 SdrPageObj* pPageObj = (*aPageObjIter++);
969 pPageObj->SetReferencedPage(rDocument.GetSdPage(*iPageIndex, PK_STANDARD));
972 // if there are more page objects than pages left, set the rest to invisible
973 int nHangoverCount = 0;
974 while (aPageObjIter != aHandoutPageObjects.end())
976 (*aPageObjIter++)->SetReferencedPage(0L);
977 nHangoverCount++;
980 // Hide outlines for objects that have pages attached.
981 if (nHangoverCount > 0)
983 int nSkip = aHandoutPageObjects.size() - nHangoverCount;
984 aShapeIter.Reset();
985 while (aShapeIter.IsMore())
987 SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
988 if (pPathObj)
990 if (nSkip > 0)
991 --nSkip;
992 else
993 pPathObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
998 if( xHandoutPage.is() ) try
1000 xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(mnHandoutPageIndex) ) );
1002 catch( Exception& )
1005 rViewShell.SetPrintedHandoutPageNum( mnHandoutPageIndex + 1 );
1007 MapMode aMap (rPrinter.GetMapMode());
1008 rPrinter.SetMapMode(maMap);
1010 PrintPage(
1011 rPrinter,
1012 rPrintView,
1013 rHandoutPage,
1014 pView,
1015 false,
1016 rVisibleLayers,
1017 rPrintableLayers);
1018 PrintMessage(
1019 rPrinter,
1020 msPageString,
1021 maPageStringOffset);
1023 if( xHandoutPage.is() ) try
1025 xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(0) ) );
1027 catch( Exception& )
1030 rViewShell.SetPrintedHandoutPageNum(1);
1032 // Restore outlines.
1033 if (nHangoverCount > 0)
1035 aShapeIter.Reset();
1036 while (aShapeIter.IsMore())
1038 SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
1039 if (pPathObj != NULL)
1040 pPathObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
1046 private:
1047 const sal_uInt16 mnHandoutPageIndex;
1048 const ::std::vector<sal_uInt16> maPageIndices;
1051 /** The outline information (title, subtitle, outline objects) of the
1052 document. There is no fixed mapping of slides to printer pages.
1054 class OutlinerPrinterPage : public PrinterPage
1056 public:
1057 OutlinerPrinterPage (
1058 OutlinerParaObject* pParaObject,
1059 const MapMode& rMapMode,
1060 const OUString& rsPageString,
1061 const Point& rPageStringOffset,
1062 const DrawModeFlags nDrawMode,
1063 const Orientation eOrientation,
1064 const sal_uInt16 nPaperTray)
1065 : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
1066 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
1067 mpParaObject(pParaObject)
1071 virtual ~OutlinerPrinterPage()
1073 mpParaObject.reset();
1076 virtual void Print (
1077 Printer& rPrinter,
1078 SdDrawDocument& rDocument,
1079 ViewShell& rViewShell,
1080 View* pView,
1081 DrawView& rPrintView,
1082 const SetOfByte& rVisibleLayers,
1083 const SetOfByte& rPrintableLayers) const SAL_OVERRIDE
1085 (void)rViewShell;
1086 (void)pView;
1087 (void)rPrintView;
1088 (void)rVisibleLayers;
1089 (void)rPrintableLayers;
1091 // Set up the printer.
1092 rPrinter.SetMapMode(maMap);
1094 // Get and set up the outliner.
1095 const Rectangle aOutRect (rPrinter.GetPageOffset(), rPrinter.GetOutputSize());
1096 Outliner* pOutliner = rDocument.GetInternalOutliner();
1097 const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1098 const bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1099 const Size aSavedPaperSize (pOutliner->GetPaperSize());
1101 pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1102 pOutliner->SetPaperSize(aOutRect.GetSize());
1103 pOutliner->SetUpdateMode(true);
1104 pOutliner->Clear();
1105 pOutliner->SetText(*mpParaObject);
1107 pOutliner->Draw(&rPrinter, aOutRect);
1109 PrintMessage(
1110 rPrinter,
1111 msPageString,
1112 maPageStringOffset);
1114 // Restore outliner and printer.
1115 pOutliner->Clear();
1116 pOutliner->SetUpdateMode(bSavedUpdateMode);
1117 pOutliner->SetPaperSize(aSavedPaperSize);
1118 pOutliner->Init(nSavedOutlMode);
1121 private:
1122 ::boost::scoped_ptr<OutlinerParaObject> mpParaObject;
1126 //===== DocumentRenderer::Implementation ======================================
1128 class DocumentRenderer::Implementation
1129 : public SfxListener,
1130 public vcl::PrinterOptionsHelper
1132 public:
1133 Implementation (ViewShellBase& rBase)
1134 : mxObjectShell(rBase.GetDocShell())
1135 , mrBase(rBase)
1136 , mbIsDisposed(false)
1137 , mpPrinter(NULL)
1138 , mpOptions()
1139 , maPrinterPages()
1140 , mpPrintView()
1141 , mbHasOrientationWarningBeenShown(false)
1143 DialogCreator aCreator( mrBase.GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_IMPRESS, GetCurrentPageIndex() );
1144 m_aUIProperties = aCreator.GetDialogControls();
1145 maSlidesPerPage = aCreator.GetSlidesPerPage();
1147 StartListening(mrBase);
1150 virtual ~Implementation()
1152 EndListening(mrBase);
1155 virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) SAL_OVERRIDE
1157 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1158 if (pSimpleHint != NULL
1159 && pSimpleHint->GetId() == SFX_HINT_DYING
1160 && &rBroadcaster == &static_cast<SfxBroadcaster&>(mrBase))
1162 Dispose();
1166 /** Process the sequence of properties given to one of the XRenderable
1167 methods.
1169 void ProcessProperties (const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
1171 OSL_ASSERT(!mbIsDisposed);
1172 if (mbIsDisposed)
1173 return;
1175 bool bIsValueChanged = processProperties( rOptions );
1176 bool bIsPaperChanged = false;
1178 // The RenderDevice property is handled specially: its value is
1179 // stored in mpPrinter instead of being retrieved on demand.
1180 Any aDev( getValue( "RenderDevice" ) );
1181 Reference<awt::XDevice> xRenderDevice;
1183 if (aDev >>= xRenderDevice)
1185 VCLXDevice* pDevice = VCLXDevice::GetImplementation(xRenderDevice);
1186 VclPtr< OutputDevice > pOut = pDevice ? pDevice->GetOutputDevice()
1187 : VclPtr< OutputDevice >();
1188 mpPrinter = dynamic_cast<Printer*>(pOut.get());
1189 Size aPageSizePixel = mpPrinter ? mpPrinter->GetPaperSizePixel() : Size();
1190 if( aPageSizePixel != maPrinterPageSizePixel )
1192 bIsPaperChanged = true;
1193 maPrinterPageSizePixel = aPageSizePixel;
1197 if (bIsValueChanged)
1199 if ( ! mpOptions )
1200 mpOptions.reset(new PrintOptions(*this, maSlidesPerPage));
1202 if( bIsValueChanged || bIsPaperChanged )
1203 PreparePages();
1206 /** Return the number of pages that are to be printed.
1208 sal_Int32 GetPrintPageCount()
1210 OSL_ASSERT(!mbIsDisposed);
1211 if (mbIsDisposed)
1212 return 0;
1213 else
1214 return maPrinterPages.size();
1217 /** Return a sequence of properties that can be returned by the
1218 XRenderable::getRenderer() method.
1220 css::uno::Sequence<css::beans::PropertyValue> GetProperties (
1221 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
1223 (void)rOptions;
1225 css::uno::Sequence<css::beans::PropertyValue> aProperties (3);
1227 aProperties[0].Name = "ExtraPrintUIOptions";
1228 aProperties[0].Value <<= m_aUIProperties;
1230 aProperties[1].Name = "PageSize";
1231 aProperties[1].Value <<= maPrintSize;
1233 // FIXME: is this always true ?
1234 aProperties[2].Name = "PageIncludesNonprintableArea";
1235 aProperties[2].Value = makeAny( sal_True );
1237 return aProperties;
1240 /** Print one of the prepared pages.
1242 void PrintPage (const sal_Int32 nIndex)
1244 OSL_ASSERT(!mbIsDisposed);
1245 if (mbIsDisposed)
1246 return;
1248 Printer& rPrinter (*mpPrinter);
1250 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1251 if ( ! pViewShell)
1252 return;
1254 SdDrawDocument* pDocument = pViewShell->GetDoc();
1255 OSL_ASSERT(pDocument!=NULL);
1257 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1258 ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
1260 if ( ! mpPrintView)
1261 mpPrintView.reset(new DrawView(mrBase.GetDocShell(), &rPrinter, NULL));
1263 if (nIndex<0 || sal::static_int_cast<sal_uInt32>(nIndex)>=maPrinterPages.size())
1264 return;
1266 const ::boost::shared_ptr<PrinterPage> pPage (maPrinterPages[nIndex]);
1267 OSL_ASSERT(pPage);
1268 if ( ! pPage)
1269 return;
1271 const Orientation eSavedOrientation (rPrinter.GetOrientation());
1272 const DrawModeFlags nSavedDrawMode (rPrinter.GetDrawMode());
1273 const MapMode aSavedMapMode (rPrinter.GetMapMode());
1274 const sal_uInt16 nSavedPaperBin (rPrinter.GetPaperBin());
1276 // Set page orientation.
1277 if ( ! rPrinter.SetOrientation(pPage->GetOrientation()))
1279 if ( ! mbHasOrientationWarningBeenShown
1280 && mpOptions->IsWarningOrientation())
1282 mbHasOrientationWarningBeenShown = true;
1283 // Show warning that the orientation could not be set.
1284 if (pViewShell)
1286 ScopedVclPtrInstance<WarningBox> aWarnBox(
1287 pViewShell->GetActiveWindow(),
1288 (WinBits)(WB_OK_CANCEL | WB_DEF_CANCEL),
1289 SD_RESSTR(STR_WARN_PRINTFORMAT_FAILURE));
1290 if (aWarnBox->Execute() != RET_OK)
1291 return;
1296 // Set the draw mode.
1297 rPrinter.SetDrawMode(pPage->GetDrawMode());
1299 // Set paper tray.
1300 rPrinter.SetPaperBin(pPage->GetPaperTray());
1302 // Print the actual page.
1303 pPage->Print(
1304 rPrinter,
1305 *pDocument,
1306 *pViewShell,
1307 pDrawViewShell ? pDrawViewShell->GetView() : NULL,
1308 *mpPrintView,
1309 pViewShell->GetFrameView()->GetVisibleLayers(),
1310 pViewShell->GetFrameView()->GetPrintableLayers());
1312 rPrinter.SetOrientation(eSavedOrientation);
1313 rPrinter.SetDrawMode(nSavedDrawMode);
1314 rPrinter.SetMapMode(aSavedMapMode);
1315 rPrinter.SetPaperBin(nSavedPaperBin);
1318 private:
1319 // rhbz#657394: keep the document alive: prevents crash when
1320 SfxObjectShellRef mxObjectShell; // destroying mpPrintView
1321 ViewShellBase& mrBase;
1322 bool mbIsDisposed;
1323 VclPtr<Printer> mpPrinter;
1324 Size maPrinterPageSizePixel;
1325 ::boost::scoped_ptr<PrintOptions> mpOptions;
1326 ::std::vector< ::boost::shared_ptr< ::sd::PrinterPage> > maPrinterPages;
1327 ::boost::scoped_ptr<DrawView> mpPrintView;
1328 bool mbHasOrientationWarningBeenShown;
1329 ::std::vector<sal_Int32> maSlidesPerPage;
1330 awt::Size maPrintSize;
1332 void Dispose()
1334 mbIsDisposed = true;
1337 sal_Int32 GetCurrentPageIndex() const
1339 const ViewShell *pShell = mrBase.GetMainViewShell().get();
1340 const SdPage *pCurrentPage = pShell ? pShell->getCurrentPage() : NULL;
1341 return pCurrentPage ? (pCurrentPage->GetPageNum()-1)/2 : -1;
1344 /** Determine and set the paper orientation.
1346 bool SetupPaperOrientation (
1347 const PageKind ePageKind,
1348 PrintInfo& rInfo)
1350 SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1351 rInfo.meOrientation = ORIENTATION_PORTRAIT;
1353 if( ! mpOptions->IsBooklet())
1355 rInfo.meOrientation = pDocument->GetSdPage(0, ePageKind)->GetOrientation();
1357 else if (rInfo.maPageSize.Width() < rInfo.maPageSize.Height())
1358 rInfo.meOrientation = ORIENTATION_LANDSCAPE;
1360 // Draw and Notes should usually abide by their specified paper size
1361 Size aPaperSize;
1362 if (!mpOptions->IsPrinterPreferred(pDocument->GetDocumentType()))
1364 aPaperSize.setWidth(rInfo.maPageSize.Width());
1365 aPaperSize.setHeight(rInfo.maPageSize.Height());
1367 else
1369 aPaperSize.setWidth(rInfo.mpPrinter->GetPaperSize().Width());
1370 aPaperSize.setHeight(rInfo.mpPrinter->GetPaperSize().Height());
1373 maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1375 if (mpOptions->IsPrinterPreferred(pDocument->GetDocumentType()))
1377 if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1378 (aPaperSize.Width() < aPaperSize.Height()))
1380 (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1381 (aPaperSize.Width() > aPaperSize.Height()))
1384 maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1388 return true;
1391 /** Top most method for preparing printer pages. In this and the other
1392 Prepare... methods the various special cases are detected and
1393 handled.
1394 For every page that is to be printed (that may contain several
1395 slides) one PrinterPage object is created and inserted into
1396 maPrinterPages.
1398 void PreparePages()
1400 mpPrintView.reset();
1401 maPrinterPages.clear();
1402 mbHasOrientationWarningBeenShown = false;
1404 ViewShell* pShell = mrBase.GetMainViewShell().get();
1406 PrintInfo aInfo (mpPrinter, mpOptions->IsPrintMarkedOnly());
1408 if (aInfo.mpPrinter!=nullptr && pShell!=NULL)
1411 MapMode aMap (aInfo.mpPrinter->GetMapMode());
1412 aMap.SetMapUnit(MAP_100TH_MM);
1413 aInfo.maMap = aMap;
1414 mpPrinter->SetMapMode(aMap);
1416 ::Outliner& rOutliner = mrBase.GetDocument()->GetDrawOutliner();
1417 const EEControlBits nSavedControlWord (rOutliner.GetControlWord());
1418 EEControlBits nCntrl = nSavedControlWord;
1419 nCntrl &= ~EEControlBits::MARKFIELDS;
1420 nCntrl &= ~EEControlBits::ONLINESPELLING;
1421 rOutliner.SetControlWord( nCntrl );
1423 // When in outline view then apply all pending changes to the model.
1424 if (pShell->ISA(OutlineViewShell))
1425 static_cast<OutlineViewShell*>(pShell)->PrepareClose (false);
1427 // Collect some frequently used data.
1428 if (mpOptions->IsDate())
1430 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getDate( Date( Date::SYSTEM ) );
1431 aInfo.msTimeDate += " ";
1434 if (mpOptions->IsTime())
1435 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getTime( ::tools::Time( ::tools::Time::SYSTEM ), false, false );
1437 // Draw and Notes should usually use specified paper size when printing
1438 if (!mpOptions->IsPrinterPreferred(mrBase.GetDocShell()->GetDocumentType()))
1440 aInfo.maPrintSize = mrBase.GetDocument()->GetSdPage(0, PK_STANDARD)->GetSize();
1441 maPrintSize = awt::Size(aInfo.maPrintSize.Width(),
1442 aInfo.maPrintSize.Height());
1444 else
1446 aInfo.maPrintSize = aInfo.mpPrinter->GetOutputSize();
1447 maPrintSize = awt::Size(
1448 aInfo.mpPrinter->GetPaperSize().Width(),
1449 aInfo.mpPrinter->GetPaperSize().Height());
1452 switch (mpOptions->GetOutputQuality())
1454 case 1: // Grayscale
1455 aInfo.mnDrawMode = DrawModeFlags::GrayLine | DrawModeFlags::GrayFill
1456 | DrawModeFlags::GrayText | DrawModeFlags::GrayBitmap
1457 | DrawModeFlags::GrayGradient;
1458 break;
1460 case 2: // Black & White
1461 aInfo.mnDrawMode = DrawModeFlags::BlackLine | DrawModeFlags::WhiteFill
1462 | DrawModeFlags::BlackText | DrawModeFlags::GrayBitmap
1463 | DrawModeFlags::WhiteGradient;
1464 break;
1466 default:
1467 aInfo.mnDrawMode = DrawModeFlags::Default;
1470 if (mpOptions->IsDraw())
1471 PrepareStdOrNotes(PK_STANDARD, aInfo);
1472 if (mpOptions->IsNotes())
1473 PrepareStdOrNotes(PK_NOTES, aInfo);
1474 if (mpOptions->IsHandout())
1476 InitHandoutTemplate();
1477 PrepareHandout(aInfo);
1479 if (mpOptions->IsOutline())
1480 PrepareOutline(aInfo);
1482 rOutliner.SetControlWord(nSavedControlWord);
1486 /** Create the page objects of the handout template. When the actual
1487 printing takes place then the page objects are assigned different
1488 sets of slides for each printed page (see HandoutPrinterPage::Print).
1490 void InitHandoutTemplate()
1492 const sal_Int32 nSlidesPerHandout (mpOptions->GetHandoutPageCount());
1493 const bool bHandoutHorizontal (mpOptions->IsHandoutHorizontal());
1495 AutoLayout eLayout = AUTOLAYOUT_HANDOUT6;
1496 switch (nSlidesPerHandout)
1498 case 0: eLayout = AUTOLAYOUT_NONE; break; // AUTOLAYOUT_HANDOUT1; break;
1499 case 1: eLayout = AUTOLAYOUT_HANDOUT1; break;
1500 case 2: eLayout = AUTOLAYOUT_HANDOUT2; break;
1501 case 3: eLayout = AUTOLAYOUT_HANDOUT3; break;
1502 case 4: eLayout = AUTOLAYOUT_HANDOUT4; break;
1503 default:
1504 case 6: eLayout = AUTOLAYOUT_HANDOUT6; break;
1505 case 9: eLayout = AUTOLAYOUT_HANDOUT9; break;
1508 if( !mrBase.GetDocument() )
1509 return;
1511 SdDrawDocument& rModel = *mrBase.GetDocument();
1513 // first, prepare handout page (not handout master)
1515 SdPage* pHandout = rModel.GetSdPage(0, PK_HANDOUT);
1516 if( !pHandout )
1517 return;
1519 // delete all previous shapes from handout page
1520 while( pHandout->GetObjCount() )
1522 SdrObject* pObj = pHandout->NbcRemoveObject(0);
1523 if( pObj )
1524 SdrObject::Free( pObj );
1527 const bool bDrawLines (eLayout == AUTOLAYOUT_HANDOUT3);
1529 std::vector< Rectangle > aAreas;
1530 SdPage::CalculateHandoutAreas( rModel, eLayout, bHandoutHorizontal, aAreas );
1532 std::vector< Rectangle >::iterator iter( aAreas.begin() );
1533 while( iter != aAreas.end() )
1535 pHandout->NbcInsertObject( new SdrPageObj((*iter++)) );
1537 if( bDrawLines && (iter != aAreas.end()) )
1539 Rectangle aRect( (*iter++) );
1541 basegfx::B2DPolygon aPoly;
1542 aPoly.insert(0, basegfx::B2DPoint( aRect.Left(), aRect.Top() ) );
1543 aPoly.insert(1, basegfx::B2DPoint( aRect.Right(), aRect.Top() ) );
1545 basegfx::B2DHomMatrix aMatrix;
1546 aMatrix.translate( 0.0, static_cast< double >( aRect.GetHeight() / 7 ) );
1548 basegfx::B2DPolyPolygon aPathPoly;
1549 for( sal_uInt16 nLine = 0; nLine < 7; nLine++ )
1551 aPoly.transform( aMatrix );
1552 aPathPoly.append( aPoly );
1555 SdrPathObj* pPathObj = new SdrPathObj(OBJ_PATHLINE, aPathPoly );
1556 pPathObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
1557 pPathObj->SetMergedItem(XLineColorItem(OUString(), Color(COL_BLACK)));
1559 pHandout->NbcInsertObject( pPathObj );
1564 /** Detect whether the specified slide is to be printed.
1565 @return
1566 When the slide is not to be printed then <NULL/> is returned.
1567 Otherwise a pointer to the slide is returned.
1569 SdPage* GetFilteredPage (
1570 const sal_Int32 nPageIndex,
1571 const PageKind ePageKind) const
1573 OSL_ASSERT(mrBase.GetDocument() != NULL);
1574 OSL_ASSERT(nPageIndex>=0);
1575 SdPage* pPage = mrBase.GetDocument()->GetSdPage(
1576 sal::static_int_cast<sal_uInt16>(nPageIndex),
1577 ePageKind);
1578 if (pPage == NULL)
1579 return NULL;
1580 if ( ! pPage->IsExcluded() || mpOptions->IsPrintExcluded())
1581 return pPage;
1582 else
1583 return NULL;
1586 /** Prepare the outline of the document for printing. There is no fixed
1587 number of slides whose outline data is put onto one printer page.
1588 If the current printer page has enough room for the outline of the
1589 current slide then that is added. Otherwise a new printer page is
1590 started.
1592 void PrepareOutline (PrintInfo& rInfo)
1594 MapMode aMap (rInfo.maMap);
1595 Point aPageOfs (rInfo.mpPrinter->GetPageOffset() );
1596 aMap.SetScaleX(Fraction(1,2));
1597 aMap.SetScaleY(Fraction(1,2));
1598 mpPrinter->SetMapMode(aMap);
1600 Rectangle aOutRect(aPageOfs, rInfo.mpPrinter->GetOutputSize());
1601 if( aOutRect.GetWidth() > aOutRect.GetHeight() )
1603 Size aPaperSize( rInfo.mpPrinter->PixelToLogic( rInfo.mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
1604 maPrintSize.Width = aPaperSize.Height();
1605 maPrintSize.Height = aPaperSize.Width();
1606 const long nRotatedWidth = aOutRect.GetHeight();
1607 const long nRotatedHeight = aOutRect.GetWidth();
1608 aOutRect = Rectangle( Point( aPageOfs.Y(), aPageOfs.X() ),
1609 Size( nRotatedWidth, nRotatedHeight ) );
1612 Outliner* pOutliner = mrBase.GetDocument()->GetInternalOutliner();
1613 pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1614 const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1615 const bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1616 const Size aSavedPaperSize (pOutliner->GetPaperSize());
1617 const MapMode aSavedMapMode (pOutliner->GetRefMapMode());
1618 pOutliner->SetPaperSize(aOutRect.GetSize());
1619 pOutliner->SetUpdateMode(true);
1621 long nPageH = aOutRect.GetHeight();
1623 ::std::vector< sal_Int32 > aPages;
1624 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1625 StringRangeEnumerator::getRangesFromString(
1626 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1627 aPages, 0, nPageCount-1);
1629 for (size_t nIndex = 0, nCount = aPages.size(); nIndex < nCount;)
1631 pOutliner->Clear();
1632 pOutliner->SetFirstPageNumber(aPages[nIndex]+1);
1634 Paragraph* pPara = NULL;
1635 sal_Int32 nH (0);
1636 while (nH < nPageH && nIndex<nCount)
1638 SdPage* pPage = GetFilteredPage(aPages[nIndex], PK_STANDARD);
1639 ++nIndex;
1640 if (pPage == NULL)
1641 continue;
1643 SdrTextObj* pTextObj = NULL;
1644 size_t nObj (0);
1646 while (pTextObj==NULL && nObj < pPage->GetObjCount())
1648 SdrObject* pObj = pPage->GetObj(nObj++);
1649 if (pObj->GetObjInventor() == SdrInventor
1650 && pObj->GetObjIdentifier() == OBJ_TITLETEXT)
1652 pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1656 pPara = pOutliner->GetParagraph(pOutliner->GetParagraphCount() - 1);
1658 if (pTextObj!=NULL
1659 && !pTextObj->IsEmptyPresObj()
1660 && pTextObj->GetOutlinerParaObject())
1662 pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1664 else
1665 pOutliner->Insert(OUString());
1667 pTextObj = NULL;
1668 nObj = 0;
1670 while (pTextObj==NULL && nObj<pPage->GetObjCount())
1672 SdrObject* pObj = pPage->GetObj(nObj++);
1673 if (pObj->GetObjInventor() == SdrInventor
1674 && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT)
1676 pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1680 bool bSubTitle (false);
1681 if (!pTextObj)
1683 bSubTitle = true;
1684 pTextObj = dynamic_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_TEXT)); // Untertitel vorhanden?
1687 sal_Int32 nParaCount1 = pOutliner->GetParagraphCount();
1689 if (pTextObj!=NULL
1690 && !pTextObj->IsEmptyPresObj()
1691 && pTextObj->GetOutlinerParaObject())
1693 pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1696 if (bSubTitle )
1698 const sal_Int32 nParaCount2 (pOutliner->GetParagraphCount());
1699 for (sal_Int32 nPara=nParaCount1; nPara<nParaCount2; ++nPara)
1701 Paragraph* pP = pOutliner->GetParagraph(nPara);
1702 if (pP!=NULL && pOutliner->GetDepth(nPara) > 0)
1703 pOutliner->SetDepth(pP, 0);
1707 nH = pOutliner->GetTextHeight();
1710 // Remove the last paragraph when that does not fit completely on
1711 // the current page.
1712 if (nH > nPageH && pPara!=NULL)
1714 sal_Int32 nCnt = pOutliner->GetAbsPos(
1715 pOutliner->GetParagraph( pOutliner->GetParagraphCount() - 1 ) );
1716 sal_Int32 nParaPos = pOutliner->GetAbsPos( pPara );
1717 nCnt -= nParaPos;
1718 pPara = pOutliner->GetParagraph( ++nParaPos );
1719 if ( nCnt && pPara )
1721 pOutliner->Remove(pPara, nCnt);
1722 --nIndex;
1726 maPrinterPages.push_back(
1727 ::boost::shared_ptr<PrinterPage>(
1728 new OutlinerPrinterPage(
1729 pOutliner->CreateParaObject(),
1730 aMap,
1731 rInfo.msTimeDate,
1732 aPageOfs,
1733 rInfo.mnDrawMode,
1734 rInfo.meOrientation,
1735 rInfo.mpPrinter->GetPaperBin())));
1738 pOutliner->SetRefMapMode(aSavedMapMode);
1739 pOutliner->SetUpdateMode(bSavedUpdateMode);
1740 pOutliner->SetPaperSize(aSavedPaperSize);
1741 pOutliner->Init(nSavedOutlMode);
1744 /** Prepare handout pages for slides that are to be printed.
1746 void PrepareHandout (PrintInfo& rInfo)
1748 SdDrawDocument* pDocument = mrBase.GetDocument();
1749 OSL_ASSERT(pDocument != NULL);
1750 SdPage& rHandoutPage (*pDocument->GetSdPage(0, PK_HANDOUT));
1752 const bool bScalePage (mpOptions->IsPageSize());
1754 sal_uInt16 nPaperBin;
1755 if ( ! mpOptions->IsPaperBin())
1756 nPaperBin = rHandoutPage.GetPaperBin();
1757 else
1758 nPaperBin = rInfo.mpPrinter->GetPaperBin();
1760 // Change orientation?
1761 SdPage& rMaster (dynamic_cast<SdPage&>(rHandoutPage.TRG_GetMasterPage()));
1762 rInfo.meOrientation = rMaster.GetOrientation();
1764 const Size aPaperSize (rInfo.mpPrinter->GetPaperSize());
1765 if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1766 (aPaperSize.Width() < aPaperSize.Height()))
1768 (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1769 (aPaperSize.Width() > aPaperSize.Height()))
1772 maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1774 else
1776 maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1779 MapMode aMap (rInfo.maMap);
1780 const Point aPageOfs (rInfo.mpPrinter->GetPageOffset());
1782 if ( bScalePage )
1784 const Size aPageSize (rHandoutPage.GetSize());
1785 const Size aPrintSize (rInfo.mpPrinter->GetOutputSize());
1787 const double fHorz = (double) aPrintSize.Width() / aPageSize.Width();
1788 const double fVert = (double) aPrintSize.Height() / aPageSize.Height();
1790 Fraction aFract;
1791 if ( fHorz < fVert )
1792 aFract = Fraction(aPrintSize.Width(), aPageSize.Width());
1793 else
1794 aFract = Fraction(aPrintSize.Height(), aPageSize.Height());
1796 aMap.SetScaleX(aFract);
1797 aMap.SetScaleY(aFract);
1798 aMap.SetOrigin(Point());
1801 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1802 pViewShell->WriteFrameViewData();
1804 // Count page shapes.
1805 sal_uInt32 nShapeCount (0);
1806 SdrObjListIter aShapeIter (rHandoutPage);
1807 while (aShapeIter.IsMore())
1809 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
1810 if (pPageObj)
1811 ++nShapeCount;
1814 const sal_uInt16 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1815 const sal_uInt16 nHandoutPageCount = nShapeCount ? (nPageCount + nShapeCount - 1) / nShapeCount : 0;
1816 pViewShell->SetPrintedHandoutPageCount( nHandoutPageCount );
1817 mrBase.GetDocument()->setHandoutPageCount( nHandoutPageCount );
1819 // Distribute pages to handout pages.
1820 StringRangeEnumerator aRangeEnum(
1821 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1822 0, nPageCount-1);
1823 ::std::vector<sal_uInt16> aPageIndices;
1824 sal_uInt16 nPrinterPageIndex = 0;
1825 StringRangeEnumerator::Iterator it = aRangeEnum.begin(), itEnd = aRangeEnum.end();
1826 bool bLastLoop = (it == itEnd);
1827 while (!bLastLoop)
1829 sal_Int32 nPageIndex = *it;
1830 ++it;
1831 bLastLoop = (it == itEnd);
1833 if (GetFilteredPage(nPageIndex, PK_STANDARD))
1834 aPageIndices.push_back(nPageIndex);
1835 else if (!bLastLoop)
1836 continue;
1838 // Create a printer page when we have found one page for each
1839 // placeholder or when this is the last (and special) loop.
1840 if (!aPageIndices.empty() && (aPageIndices.size() == nShapeCount || bLastLoop))
1842 maPrinterPages.push_back(
1843 ::boost::shared_ptr<PrinterPage>(
1844 new HandoutPrinterPage(
1845 nPrinterPageIndex++,
1846 aPageIndices,
1847 aMap,
1848 rInfo.msTimeDate,
1849 aPageOfs,
1850 rInfo.mnDrawMode,
1851 rInfo.meOrientation,
1852 nPaperBin)));
1853 aPageIndices.clear();
1858 /** Prepare the notes pages or regular slides.
1860 void PrepareStdOrNotes (
1861 const PageKind ePageKind,
1862 PrintInfo& rInfo)
1864 OSL_ASSERT(rInfo.mpPrinter != nullptr);
1866 // Fill in page kind specific data.
1867 SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1868 if (pDocument->GetSdPageCount(ePageKind) == 0)
1869 return;
1870 SdPage* pRefPage = pDocument->GetSdPage(0, ePageKind);
1871 rInfo.maPageSize = pRefPage->GetSize();
1873 if ( ! SetupPaperOrientation(ePageKind, rInfo))
1874 return;
1876 MapMode aMap (rInfo.maMap);
1877 rInfo.maMap = aMap;
1879 if (mpOptions->IsBooklet())
1880 PrepareBooklet(ePageKind, rInfo);
1881 else
1882 PrepareRegularPages(ePageKind, rInfo);
1885 /** Prepare slides in a non-booklet way: one slide per one to many
1886 printer pages.
1888 void PrepareRegularPages (
1889 const PageKind ePageKind,
1890 PrintInfo& rInfo)
1892 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1893 pViewShell->WriteFrameViewData();
1895 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1896 StringRangeEnumerator aRangeEnum(
1897 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1898 0, nPageCount-1);
1899 for (StringRangeEnumerator::Iterator
1900 it = aRangeEnum.begin(),
1901 itEnd = aRangeEnum.end();
1902 it != itEnd;
1903 ++it)
1905 SdPage* pPage = GetFilteredPage(*it, ePageKind);
1906 if (pPage == NULL)
1907 continue;
1909 MapMode aMap (rInfo.maMap);
1910 // is it possible that the page size changed?
1911 const Size aPageSize = pPage->GetSize();
1913 if (mpOptions->IsPageSize())
1915 const double fHorz ((double) rInfo.maPrintSize.Width() / aPageSize.Width());
1916 const double fVert ((double) rInfo.maPrintSize.Height() / aPageSize.Height());
1918 Fraction aFract;
1919 if (fHorz < fVert)
1920 aFract = Fraction(rInfo.maPrintSize.Width(), aPageSize.Width());
1921 else
1922 aFract = Fraction(rInfo.maPrintSize.Height(), aPageSize.Height());
1924 aMap.SetScaleX(aFract);
1925 aMap.SetScaleY(aFract);
1926 aMap.SetOrigin(Point());
1929 if (mpOptions->IsPrintPageName())
1931 rInfo.msPageString = pPage->GetName();
1932 rInfo.msPageString += " ";
1934 else
1935 rInfo.msPageString.clear();
1936 rInfo.msPageString += rInfo.msTimeDate;
1938 long aPageWidth = aPageSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder();
1939 long aPageHeight = aPageSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder();
1940 // Bugfix for 44530:
1941 // if it was implicitly changed (Landscape/Portrait),
1942 // this is considered for tiling, respectively for the splitting up
1943 // (Poster)
1944 if( ( rInfo.maPrintSize.Width() > rInfo.maPrintSize.Height()
1945 && aPageWidth < aPageHeight )
1946 || ( rInfo.maPrintSize.Width() < rInfo.maPrintSize.Height()
1947 && aPageWidth > aPageHeight ) )
1949 const sal_Int32 nTmp (rInfo.maPrintSize.Width());
1950 rInfo.maPrintSize.Width() = rInfo.maPrintSize.Height();
1951 rInfo.maPrintSize.Height() = nTmp;
1954 if (mpOptions->IsTilePage()
1955 && aPageWidth < rInfo.maPrintSize.Width()
1956 && aPageHeight < rInfo.maPrintSize.Height())
1958 // Put multiple slides on one printer page.
1959 PrepareTiledPage(*it, *pPage, ePageKind, rInfo);
1961 else
1963 rInfo.maMap = aMap;
1964 PrepareScaledPage(*it, *pPage, ePageKind, rInfo);
1969 /** Put two slides on one printer page.
1971 void PrepareBooklet (
1972 const PageKind ePageKind,
1973 const PrintInfo& rInfo)
1975 MapMode aStdMap (rInfo.maMap);
1976 Point aOffset;
1977 Size aPrintSize_2 (rInfo.maPrintSize);
1978 Size aPageSize_2 (rInfo.maPageSize);
1980 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
1981 aPrintSize_2.Width() >>= 1;
1982 else
1983 aPrintSize_2.Height() >>= 1;
1985 const double fPageWH = (double) aPageSize_2.Width() / aPageSize_2.Height();
1986 const double fPrintWH = (double) aPrintSize_2.Width() / aPrintSize_2.Height();
1988 if( fPageWH < fPrintWH )
1990 aPageSize_2.Width() = (long) ( aPrintSize_2.Height() * fPageWH );
1991 aPageSize_2.Height()= aPrintSize_2.Height();
1993 else
1995 aPageSize_2.Width() = aPrintSize_2.Width();
1996 aPageSize_2.Height() = (long) ( aPrintSize_2.Width() / fPageWH );
1999 MapMode aMap (rInfo.maMap);
2000 aMap.SetScaleX( Fraction( aPageSize_2.Width(), rInfo.maPageSize.Width() ) );
2001 aMap.SetScaleY( Fraction( aPageSize_2.Height(), rInfo.maPageSize.Height() ) );
2003 // calculate adjusted print size
2004 const Size aAdjustedPrintSize (OutputDevice::LogicToLogic(
2005 rInfo.maPrintSize,
2006 aStdMap,
2007 aMap));
2009 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2011 aOffset.X() = ( ( aAdjustedPrintSize.Width() >> 1 ) - rInfo.maPageSize.Width() ) >> 1;
2012 aOffset.Y() = ( aAdjustedPrintSize.Height() - rInfo.maPageSize.Height() ) >> 1;
2014 else
2016 aOffset.X() = ( aAdjustedPrintSize.Width() - rInfo.maPageSize.Width() ) >> 1;
2017 aOffset.Y() = ( ( aAdjustedPrintSize.Height() >> 1 ) - rInfo.maPageSize.Height() ) >> 1;
2020 // create vector of pages to print
2021 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(ePageKind);
2022 StringRangeEnumerator aRangeEnum(
2023 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
2024 0, nPageCount-1);
2025 ::std::vector< sal_uInt16 > aPageVector;
2026 for (StringRangeEnumerator::Iterator
2027 it = aRangeEnum.begin(),
2028 itEnd = aRangeEnum.end();
2029 it != itEnd;
2030 ++it)
2032 SdPage* pPage = GetFilteredPage(*it, ePageKind);
2033 if (pPage != NULL)
2034 aPageVector.push_back(*it);
2037 // create pairs of pages to print on each page
2038 typedef ::std::vector< ::std::pair< sal_uInt16, sal_uInt16 > > PairVector;
2039 PairVector aPairVector;
2040 if ( ! aPageVector.empty())
2042 sal_uInt32 nFirstIndex = 0, nLastIndex = aPageVector.size() - 1;
2044 if( aPageVector.size() & 1 )
2045 aPairVector.push_back( ::std::make_pair( (sal_uInt16) 65535, aPageVector[ nFirstIndex++ ] ) );
2046 else
2047 aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2049 while( nFirstIndex < nLastIndex )
2051 if( nFirstIndex & 1 )
2052 aPairVector.push_back( ::std::make_pair( aPageVector[ nFirstIndex++ ], aPageVector[ nLastIndex-- ] ) );
2053 else
2054 aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2058 for (sal_uInt32
2059 nIndex=0,
2060 nCount=aPairVector.size();
2061 nIndex < nCount;
2062 ++nIndex)
2064 const bool bIsIndexOdd (nIndex & 1);
2065 if ((!bIsIndexOdd && mpOptions->IsPrintFrontPage())
2066 || (bIsIndexOdd && mpOptions->IsPrintBackPage()))
2068 const ::std::pair<sal_uInt16, sal_uInt16> aPair (aPairVector[nIndex]);
2069 Point aSecondOffset (aOffset);
2070 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2071 aSecondOffset.X() += aAdjustedPrintSize.Width() / 2;
2072 else
2073 aSecondOffset.Y() += aAdjustedPrintSize.Height() / 2;
2074 maPrinterPages.push_back(
2075 ::boost::shared_ptr<PrinterPage>(
2076 new BookletPrinterPage(
2077 aPair.first,
2078 aPair.second,
2079 aOffset,
2080 aSecondOffset,
2081 ePageKind,
2082 aMap,
2083 rInfo.mbPrintMarkedOnly,
2084 rInfo.mnDrawMode,
2085 rInfo.meOrientation,
2086 rInfo.mpPrinter->GetPaperBin())));
2092 /** Print one slide multiple times on one printer page so that the whole
2093 printer page is covered.
2095 void PrepareTiledPage (
2096 const sal_Int32 nPageIndex,
2097 const SdPage& rPage,
2098 const PageKind ePageKind,
2099 const PrintInfo& rInfo)
2101 sal_uInt16 nPaperBin;
2102 if ( ! mpOptions->IsPaperBin())
2103 nPaperBin = rPage.GetPaperBin();
2104 else
2105 nPaperBin = rInfo.mpPrinter->GetPaperBin();
2107 maPrinterPages.push_back(
2108 ::boost::shared_ptr<PrinterPage>(
2109 new TiledPrinterPage(
2110 sal::static_int_cast<sal_uInt16>(nPageIndex),
2111 ePageKind,
2112 500,
2113 rInfo.mbPrintMarkedOnly,
2114 rInfo.msPageString,
2115 rInfo.mpPrinter->GetPageOffset(),
2116 rInfo.mnDrawMode,
2117 rInfo.meOrientation,
2118 nPaperBin)));
2121 /** Print one standard slide or notes page on one to many printer
2122 pages. More than on printer page is used when the slide is larger
2123 than the printable area.
2125 void PrepareScaledPage (
2126 const sal_Int32 nPageIndex,
2127 const SdPage& rPage,
2128 const PageKind ePageKind,
2129 const PrintInfo& rInfo)
2131 const Point aPageOffset (rInfo.mpPrinter->GetPageOffset());
2133 sal_uInt16 nPaperBin;
2134 if ( ! mpOptions->IsPaperBin())
2135 nPaperBin = rPage.GetPaperBin();
2136 else
2137 nPaperBin = rInfo.mpPrinter->GetPaperBin();
2139 // For pages larger then the printable area there
2140 // are three options:
2141 // 1. Scale down to the page to the printable area.
2142 // 2. Print only the upper left part of the page
2143 // (without the unprintable borders).
2144 // 3. Split the page into parts of the size of the
2145 // printable area.
2146 const bool bScalePage (mpOptions->IsPageSize());
2147 const bool bCutPage (mpOptions->IsCutPage());
2148 MapMode aMap (rInfo.maMap);
2149 if (bScalePage || bCutPage)
2151 // Handle 1 and 2.
2153 // if CutPage is set then do not move it, otherwise move the
2154 // scaled page to printable area
2155 maPrinterPages.push_back(
2156 ::boost::shared_ptr<PrinterPage>(
2157 new RegularPrinterPage(
2158 sal::static_int_cast<sal_uInt16>(nPageIndex),
2159 ePageKind,
2160 aMap,
2161 rInfo.mbPrintMarkedOnly,
2162 rInfo.msPageString,
2163 aPageOffset,
2164 rInfo.mnDrawMode,
2165 rInfo.meOrientation,
2166 nPaperBin)));
2168 else
2170 // Handle 3. Print parts of the page in the size of the
2171 // printable area until the whole page is covered.
2173 // keep the page content at its position if it fits, otherwise
2174 // move it to the printable area
2175 const long nPageWidth (
2176 rInfo.maPageSize.Width() - rPage.GetLftBorder() - rPage.GetRgtBorder());
2177 const long nPageHeight (
2178 rInfo.maPageSize.Height() - rPage.GetUppBorder() - rPage.GetLwrBorder());
2180 Point aOrigin ( 0, 0 );
2182 for (Point aPageOrigin = aOrigin;
2183 -aPageOrigin.Y()<nPageHeight;
2184 aPageOrigin.Y() -= rInfo.maPrintSize.Height())
2186 for (aPageOrigin.X()=aOrigin.X();
2187 -aPageOrigin.X()<nPageWidth;
2188 aPageOrigin.X() -= rInfo.maPrintSize.Width())
2190 aMap.SetOrigin(aPageOrigin);
2191 maPrinterPages.push_back(
2192 ::boost::shared_ptr<PrinterPage>(
2193 new RegularPrinterPage(
2194 sal::static_int_cast<sal_uInt16>(nPageIndex),
2195 ePageKind,
2196 aMap,
2197 rInfo.mbPrintMarkedOnly,
2198 rInfo.msPageString,
2199 aPageOffset,
2200 rInfo.mnDrawMode,
2201 rInfo.meOrientation,
2202 nPaperBin)));
2209 //===== DocumentRenderer ======================================================
2211 DocumentRenderer::DocumentRenderer (ViewShellBase& rBase)
2212 : DocumentRendererInterfaceBase(m_aMutex),
2213 mpImpl(new Implementation(rBase))
2217 DocumentRenderer::~DocumentRenderer()
2221 //----- XRenderable -----------------------------------------------------------
2223 sal_Int32 SAL_CALL DocumentRenderer::getRendererCount (
2224 const css::uno::Any& aSelection,
2225 const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
2226 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
2228 (void)aSelection;
2229 mpImpl->ProcessProperties(rOptions);
2230 return mpImpl->GetPrintPageCount();
2233 Sequence<beans::PropertyValue> SAL_CALL DocumentRenderer::getRenderer (
2234 sal_Int32 nRenderer,
2235 const css::uno::Any& rSelection,
2236 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2237 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
2239 (void)nRenderer;
2240 (void)rSelection;
2241 mpImpl->ProcessProperties(rOptions);
2242 return mpImpl->GetProperties(rOptions);
2245 void SAL_CALL DocumentRenderer::render (
2246 sal_Int32 nRenderer,
2247 const css::uno::Any& rSelection,
2248 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2249 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
2251 (void)rSelection;
2252 mpImpl->ProcessProperties(rOptions);
2253 mpImpl->PrintPage(nRenderer);
2256 } // end of namespace sd
2258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */