fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / view / DocumentRenderer.cxx
bloba544515609f11fb25007f69cda0541e28f56c9d7
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 .
21 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include "DocumentRenderer.hxx"
24 #include "DocumentRenderer.hrc"
26 #include "drawdoc.hxx"
27 #include "optsitem.hxx"
28 #include "sdresid.hxx"
29 #include "strings.hrc"
30 #include "sdattr.hxx"
31 #include "Window.hxx"
32 #include "drawview.hxx"
33 #include "DrawViewShell.hxx"
34 #include "FrameView.hxx"
35 #include "Outliner.hxx"
36 #include "OutlineViewShell.hxx"
38 #include <basegfx/polygon/b2dpolygon.hxx>
39 #include <basegfx/polygon/b2dpolypolygon.hxx>
40 #include <basegfx/matrix/b2dhommatrix.hxx>
41 #include <sfx2/printer.hxx>
42 #include <editeng/editstat.hxx>
43 #include <editeng/outlobj.hxx>
44 #include <svx/svdetc.hxx>
45 #include <svx/svditer.hxx>
46 #include <svx/svdopage.hxx>
47 #include <svx/svdopath.hxx>
48 #include <svx/xlnclit.hxx>
49 #include <toolkit/awt/vclxdevice.hxx>
50 #include <tools/resary.hxx>
51 #include <unotools/localedatawrapper.hxx>
52 #include <vcl/msgbox.hxx>
53 #include <unotools/moduleoptions.hxx>
55 #include <vector>
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
61 namespace sd {
63 namespace {
66 /** Convenience class to extract values from the sequence of properties
67 given to one of the XRenderable methods.
69 class PrintOptions
71 public:
72 PrintOptions (
73 const vcl::PrinterOptionsHelper& rHelper,
74 const ::std::vector<sal_Int32>& rSlidesPerPage)
75 : mrProperties(rHelper),
76 maSlidesPerPage(rSlidesPerPage)
80 bool IsWarningOrientation() const
82 return GetBoolValue(NULL, true);
85 bool IsPrintPageName() const
87 return GetBoolValue("IsPrintName");
90 bool IsDate() const
92 return GetBoolValue("IsPrintDateTime");
95 bool IsTime() const
97 return GetBoolValue("IsPrintDateTime");
100 bool IsHiddenPages() const
102 return GetBoolValue("IsPrintHidden");
105 bool IsHandoutHorizontal() const
107 return GetBoolValue("SlidesPerPageOrder", sal_Int32(0));
110 sal_Int32 GetHandoutPageCount() const
112 sal_uInt32 nIndex = static_cast<sal_Int32>(mrProperties.getIntValue("SlidesPerPage", sal_Int32(0)));
113 if (nIndex<maSlidesPerPage.size())
114 return maSlidesPerPage[nIndex];
115 else if ( ! maSlidesPerPage.empty())
116 return maSlidesPerPage[0];
117 else
118 return 0;
121 bool IsDraw() const
123 return GetBoolValue("PageContentType", sal_Int32(0));
126 bool IsHandout() const
128 return GetBoolValue("PageContentType", sal_Int32(1));
131 bool IsNotes() const
133 return GetBoolValue("PageContentType", sal_Int32(2));
136 bool IsOutline() const
138 return GetBoolValue("PageContentType", sal_Int32(3));
141 sal_uLong GetOutputQuality() const
143 sal_Int32 nQuality = static_cast<sal_Int32>(mrProperties.getIntValue( "Quality", sal_Int32(0) ));
144 return nQuality;
147 bool IsPageSize() const
149 return GetBoolValue("PageOptions", sal_Int32(1));
152 bool IsTilePage() const
154 return GetBoolValue("PageOptions", sal_Int32(2)) || GetBoolValue("PageOptions", sal_Int32(3));
157 bool IsCutPage() const
159 return GetBoolValue("PageOptions", sal_Int32(0));
162 bool IsBooklet() const
164 return GetBoolValue("PrintProspect", false);
167 bool IsPrintExcluded() const
169 return (IsNotes() || IsDraw() || IsHandout()) && IsHiddenPages();
172 bool IsPrintFrontPage() const
174 sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
175 return nInclude == 0 || nInclude == 1;
178 bool IsPrintBackPage() const
180 sal_Int32 nInclude = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintProspectInclude", 0 ));
181 return nInclude == 0 || nInclude == 2;
184 bool IsPaperBin() const
186 return GetBoolValue("PrintPaperFromSetup", false);
189 bool IsPrintMarkedOnly() const
191 return GetBoolValue("PrintContent", sal_Int32(2));
194 OUString GetPrinterSelection (sal_Int32 nPageCount, sal_Int32 nCurrentPageIndex) const
196 sal_Int32 nContent = static_cast<sal_Int32>(mrProperties.getIntValue( "PrintContent", 0 ));
197 OUString sFullRange = OUStringBuffer()
198 .append(static_cast<sal_Int32>(1))
199 .append(static_cast<sal_Unicode>('-'))
200 .append(nPageCount).makeStringAndClear();
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::valueOf(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 sal_Bool bValue = mrProperties.getBoolValue( pName, bDefaultValue );
235 return bValue;
238 /** Return <TRUE/> when the value of the property with name pName is
239 a string and its value equals pValue. When the property is
240 unknown then bDefaultValue is returned. Otherwise <FALSE/> is
241 returned.
243 bool GetBoolValue (
244 const sal_Char* pName,
245 const sal_Char* pValue,
246 const bool bDefaultValue = false) const
248 OUString sValue( mrProperties.getStringValue( pName ) );
249 if (!sValue.isEmpty())
250 return sValue.equalsAscii(pValue);
251 else
252 return bDefaultValue;
255 /** Return <TRUE/> when the value of the property with name pName is
256 an integer and its value is nTriggerValue. Otherwise <FALSE/> is
257 returned.
259 bool GetBoolValue (
260 const sal_Char* pName,
261 const sal_Int32 nTriggerValue) const
263 sal_Int32 nValue = static_cast<sal_Int32>(mrProperties.getIntValue( pName ));
264 return nValue == nTriggerValue;
270 /** A collection of values that helps to reduce the number of arguments
271 given to some functions. Note that not all values are set at the
272 same time.
274 class PrintInfo
276 public:
277 PrintInfo (
278 const Printer* pPrinter,
279 const bool bPrintMarkedOnly)
280 : mpPrinter(pPrinter),
281 mnDrawMode(DRAWMODE_DEFAULT),
282 msTimeDate(),
283 msPageString(),
284 maPrintSize(0,0),
285 maPageSize(0,0),
286 meOrientation(ORIENTATION_PORTRAIT),
287 maMap(),
288 mbPrintMarkedOnly(bPrintMarkedOnly)
291 const Printer* mpPrinter;
292 sal_uLong mnDrawMode;
293 OUString msTimeDate;
294 OUString msPageString;
295 Size maPrintSize;
296 Size maPageSize;
297 Orientation meOrientation;
298 MapMode maMap;
299 const bool mbPrintMarkedOnly;
304 /** Output one page of the document to the given printer. Note that
305 more than one document page may be output to one printer page.
307 void PrintPage (
308 Printer& rPrinter,
309 ::sd::View& rPrintView,
310 SdPage& rPage,
311 View* pView,
312 const bool bPrintMarkedOnly,
313 const SetOfByte& rVisibleLayers,
314 const SetOfByte& rPrintableLayers)
316 rPrintView.ShowSdrPage(&rPage);
318 const MapMode aOriginalMapMode (rPrinter.GetMapMode());
320 // Set the visible layers
321 SdrPageView* pPageView = rPrintView.GetSdrPageView();
322 OSL_ASSERT(pPageView!=NULL);
323 pPageView->SetVisibleLayers(rVisibleLayers);
324 pPageView->SetPrintableLayers(rPrintableLayers);
326 if (pView!=NULL && bPrintMarkedOnly)
327 pView->DrawMarkedObj(rPrinter);
328 else
329 rPrintView.CompleteRedraw(&rPrinter,
330 Region(Rectangle(Point(0,0), rPage.GetSize())));
332 rPrinter.SetMapMode(aOriginalMapMode);
334 rPrintView.HideSdrPage();
340 /** Output a string (that typically is not part of a document page) to
341 the given printer.
343 void PrintMessage (
344 Printer& rPrinter,
345 const OUString& rsPageString,
346 const Point& rPageStringOffset)
348 const Font aOriginalFont (rPrinter.OutputDevice::GetFont());
349 rPrinter.SetFont(Font(FAMILY_SWISS, Size(0, 423)));
350 rPrinter.DrawText(rPageStringOffset, rsPageString);
351 rPrinter.SetFont(aOriginalFont);
357 /** Read the resource file and process it into a sequence of properties
358 that can be passed to the printing dialog.
360 class DialogCreator : Resource
362 public:
363 DialogCreator (bool bImpress, sal_Int32 nCurPage)
364 : Resource(SdResId(_STR_IMPRESS_PRINT_UI_OPTIONS))
365 , mbImpress(bImpress)
366 , mnCurPage(nCurPage)
368 ProcessResource();
371 Sequence< beans::PropertyValue > GetDialogControls() const
373 if (maProperties.empty())
374 return Sequence< beans::PropertyValue >();
375 else
377 return Sequence<beans::PropertyValue>(
378 &maProperties.front(),
379 maProperties.size());
383 ::std::vector<sal_Int32> GetSlidesPerPage() const
385 return maSlidesPerPage;
388 private:
389 Any maDialog;
390 ::std::vector<beans::PropertyValue> maProperties;
391 ::std::vector<sal_Int32> maSlidesPerPage;
392 bool mbImpress;
393 sal_Int32 mnCurPage;
395 void ProcessResource()
397 // load the writer PrinterOptions into the custom tab
398 beans::PropertyValue aOptionsUIFile;
399 aOptionsUIFile.Name = OUString("OptionsUIFile");
400 if( mbImpress )
401 aOptionsUIFile.Value <<= OUString("modules/simpress/ui/printeroptions.ui");
402 else
403 aOptionsUIFile.Value <<= OUString("modules/sdraw/ui/printeroptions.ui");
404 maProperties.push_back(aOptionsUIFile);
406 SvtModuleOptions aOpt;
407 String aAppGroupname( String( SdResId( _STR_IMPRESS_PRINT_UI_GROUP_NAME ) ) );
408 aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
409 aOpt.GetModuleName( mbImpress ? SvtModuleOptions::E_SIMPRESS : SvtModuleOptions::E_SDRAW ) );
410 AddDialogControl(vcl::PrinterOptionsHelper::setGroupControlOpt("tabcontrol-page2", aAppGroupname, ".HelpID:vcl:PrintDialog:TabPage:AppPage"));
412 uno::Sequence< OUString > aHelpIds, aWidgetIds;
413 if( mbImpress )
415 vcl::PrinterOptionsHelper::UIControlOptions aPrintOpt;
416 aPrintOpt.maGroupHint = "JobPage" ;
417 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("extraimpressprintoptions",
418 String( SdResId(_STR_IMPRESS_PRINT_UI_PRINT_GROUP) ),
420 aPrintOpt ));
422 aHelpIds.realloc( 1 );
423 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PageContentType:ListBox" ;
424 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
425 "impressdocument",
426 String( SdResId( _STR_IMPRESS_PRINT_UI_CONTENT ) ),
427 aHelpIds,
428 "PageContentType" ,
429 CreateChoice(_STR_IMPRESS_PRINT_UI_CONTENT_CHOICES),
433 aHelpIds[0] = ".HelpID:vcl:PrintDialog:SlidesPerPage:ListBox" ;
434 vcl::PrinterOptionsHelper::UIControlOptions aContentOpt( "PageContentType" , 1 );
435 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
436 "slidesperpage",
437 String( SdResId( _STR_IMPRESS_PRINT_UI_SLIDESPERPAGE ) ),
438 aHelpIds,
439 "SlidesPerPage" ,
440 GetSlidesPerPageSequence(),
442 Sequence< sal_Bool >(),
443 aContentOpt
447 aHelpIds[0] = ".HelpID:vcl:PrintDialog:SlidesPerPageOrder:ListBox" ;
448 vcl::PrinterOptionsHelper::UIControlOptions aSlidesPerPageOpt( "SlidesPerPage" , -1, sal_True );
449 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
450 "slidesperpageorder",
451 String( SdResId( _STR_IMPRESS_PRINT_UI_ORDER ) ),
452 aHelpIds,
453 "SlidesPerPageOrder" ,
454 CreateChoice(_STR_IMPRESS_PRINT_UI_ORDER_CHOICES),
456 Sequence< sal_Bool >(),
457 aSlidesPerPageOpt )
461 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("contents",
462 String( SdResId(_STR_IMPRESS_PRINT_UI_INCLUDE_CONTENT) ), "" ) );
465 if( mbImpress )
467 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printname",
468 String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_NAME) ),
469 ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ,
470 "IsPrintName" ,
471 sal_False
475 else
477 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printname",
478 String( SdResId(_STR_DRAW_PRINT_UI_IS_PRINT_NAME) ),
479 ".HelpID:vcl:PrintDialog:IsPrintName:CheckBox" ,
480 "IsPrintName" ,
481 sal_False
486 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printdatetime",
487 String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_DATE) ),
488 ".HelpID:vcl:PrintDialog:IsPrintDateTime:CheckBox" ,
489 "IsPrintDateTime" ,
490 sal_False
494 if( mbImpress )
496 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printhidden",
497 String( SdResId(_STR_IMPRESS_PRINT_UI_IS_PRINT_HIDDEN) ),
498 ".HelpID:vcl:PrintDialog:IsPrintHidden:CheckBox" ,
499 "IsPrintHidden" ,
500 sal_False
505 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("color",
506 String( SdResId(_STR_IMPRESS_PRINT_UI_QUALITY) ), "" ) );
508 aHelpIds.realloc( 3 );
509 aHelpIds[0] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:0" ;
510 aHelpIds[1] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:1" ;
511 aHelpIds[2] = ".HelpID:vcl:PrintDialog:Quality:RadioButton:2" ;
512 aWidgetIds.realloc( 3 );
513 aWidgetIds[0] = "originalcolors";
514 aWidgetIds[1] = "grayscale";
515 aWidgetIds[2] = "blackandwhite";
516 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(
517 aWidgetIds,
519 aHelpIds,
520 "Quality" ,
521 CreateChoice(_STR_IMPRESS_PRINT_UI_QUALITY_CHOICES),
525 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("pagesizes",
526 String( SdResId(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS) ), "" ) );
528 aHelpIds.realloc( 4 );
529 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:0" ;
530 aHelpIds[1] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:1" ;
531 aHelpIds[2] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:2" ;
532 aHelpIds[3] = ".HelpID:vcl:PrintDialog:PageOptions:RadioButton:3" ;
533 aWidgetIds.realloc( 4 );
534 aWidgetIds[0] = "originalsize";
535 aWidgetIds[1] = "fittoprintable";
536 aWidgetIds[2] = "distributeonmultiple";
537 aWidgetIds[3] = "tilesheet";
538 if( mbImpress )
540 // FIXME: additional dependency on PrintProspect = false
541 vcl::PrinterOptionsHelper::UIControlOptions aPageOptionsOpt( "PageContentType" , 0 );
542 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(
543 aWidgetIds,
545 aHelpIds,
546 "PageOptions" ,
547 CreateChoice(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES),
549 Sequence< sal_Bool >(),
550 aPageOptionsOpt
554 else
556 vcl::PrinterOptionsHelper::UIControlOptions aPageOptionsOpt( "PrintProspect" , sal_False );
557 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(
558 aWidgetIds,
560 aHelpIds,
561 "PageOptions" ,
562 CreateChoice(_STR_IMPRESS_PRINT_UI_PAGE_OPTIONS_CHOICES_DRAW),
564 Sequence< sal_Bool >(),
565 aPageOptionsOpt
570 vcl::PrinterOptionsHelper::UIControlOptions aBrochureOpt;
571 aBrochureOpt.maGroupHint = "LayoutPage" ;
572 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("pagesides",
573 String( SdResId(_STR_IMPRESS_PRINT_UI_PAGE_SIDES) ), "",
574 aBrochureOpt ) );
576 // brochure printing
577 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("brochure",
578 String( SdResId(_STR_IMPRESS_PRINT_UI_BROCHURE) ),
579 ".HelpID:vcl:PrintDialog:PrintProspect:CheckBox" ,
580 "PrintProspect" ,
581 sal_False,
582 aBrochureOpt
586 vcl::PrinterOptionsHelper::UIControlOptions
587 aIncludeOpt( "PrintProspect" , -1, sal_False );
588 aIncludeOpt.maGroupHint = "LayoutPage" ;
589 aHelpIds.realloc( 1 );
590 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PrintProspectInclude:ListBox" ;
591 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceListControlOpt(
592 "brochureinclude",
593 String( SdResId(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE) ),
594 aHelpIds,
595 "PrintProspectInclude" ,
596 CreateChoice(_STR_IMPRESS_PRINT_UI_BROCHURE_INCLUDE_LIST),
598 Sequence< sal_Bool >(),
599 aIncludeOpt
603 // paper tray (on options page)
604 vcl::PrinterOptionsHelper::UIControlOptions aPaperTrayOpt;
605 aPaperTrayOpt.maGroupHint = "OptionsPageOptGroup" ;
606 AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt("printpaperfromsetup",
607 String( SdResId(_STR_IMPRESS_PRINT_UI_PAPER_TRAY) ),
608 ".HelpID:vcl:PrintDialog:PrintPaperFromSetup:CheckBox" ,
609 "PrintPaperFromSetup" ,
610 sal_False,
611 aPaperTrayOpt
614 // print range selection
615 vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
616 aPrintRangeOpt.mbInternalOnly = sal_True;
617 aPrintRangeOpt.maGroupHint = "PrintRange" ;
618 AddDialogControl( vcl::PrinterOptionsHelper::setSubgroupControlOpt("printrange",
619 String( SdResId( _STR_IMPRESS_PRINT_UI_PAGE_RANGE ) ),
621 aPrintRangeOpt )
624 // create a choice for the content to create
625 OUString aPrintRangeName( "PrintContent" );
626 aHelpIds.realloc( 3 );
627 aHelpIds[0] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ;
628 aHelpIds[1] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ;
629 aHelpIds[2] = ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2" ;
630 aWidgetIds.realloc( 3 );
631 aWidgetIds[0] = "printallpages";
632 aWidgetIds[1] = "printpages";
633 aWidgetIds[2] = "printselection";
634 AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(aWidgetIds, "",
635 aHelpIds,
636 aPrintRangeName,
637 CreateChoice(mbImpress
638 ? _STR_IMPRESS_PRINT_UI_PAGE_RANGE_CHOICE
639 : _STR_DRAW_PRINT_UI_PAGE_RANGE_CHOICE),
642 // create a an Edit dependent on "Pages" selected
643 vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
644 AddDialogControl(vcl::PrinterOptionsHelper::setEditControlOpt("pagerange", "",
645 ".HelpID:vcl:PrintDialog:PageRange:Edit", "PageRange",
646 OUString::valueOf(mnCurPage + 1), aPageRangeOpt));
648 FreeResource();
651 void AddDialogControl( const Any& i_rCtrl )
653 beans::PropertyValue aVal;
654 aVal.Value = i_rCtrl;
655 maProperties.push_back( aVal );
658 Sequence<OUString> CreateChoice (const sal_uInt16 nResourceId) const
660 SdResId aResourceId (nResourceId);
661 ResStringArray aChoiceStrings (aResourceId);
663 const sal_uInt32 nCount (aChoiceStrings.Count());
664 Sequence<OUString> aChoices (nCount);
665 for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex)
666 aChoices[nIndex] = aChoiceStrings.GetString(nIndex);
668 return aChoices;
671 Sequence<OUString> GetSlidesPerPageSequence()
673 const Sequence<OUString> aChoice (
674 CreateChoice(_STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES));
675 maSlidesPerPage.clear();
676 maSlidesPerPage.push_back(0); // first is using the default
677 for (sal_Int32 nIndex=1,nCount=aChoice.getLength(); nIndex<nCount; ++nIndex)
678 maSlidesPerPage.push_back(aChoice[nIndex].toInt32());
679 return aChoice;
686 /** The Prepare... methods of the DocumentRenderer::Implementation class
687 create a set of PrinterPage objects that contain all necessary
688 information to do the actual printing. There is one PrinterPage
689 object per printed page. Derived classes implement the actual, mode
690 specific printing.
692 This and all derived classes support the asynchronous printing
693 process by not storing pointers to any data with lifetime shorter
694 than the PrinterPage objects, i.e. slides, shapes, (one of) the
695 outliner (of the document).
697 class PrinterPage
699 public:
700 PrinterPage (
701 const PageKind ePageKind,
702 const MapMode& rMapMode,
703 const bool bPrintMarkedOnly,
704 const OUString& rsPageString,
705 const Point& rPageStringOffset,
706 const sal_uLong nDrawMode,
707 const Orientation eOrientation,
708 const sal_uInt16 nPaperTray)
709 : mePageKind(ePageKind),
710 maMap(rMapMode),
711 mbPrintMarkedOnly(bPrintMarkedOnly),
712 msPageString(rsPageString),
713 maPageStringOffset(rPageStringOffset),
714 mnDrawMode(nDrawMode),
715 meOrientation(eOrientation),
716 mnPaperTray(nPaperTray)
720 virtual ~PrinterPage() {}
722 virtual void Print (
723 Printer& rPrinter,
724 SdDrawDocument& rDocument,
725 ViewShell& rViewShell,
726 View* pView,
727 DrawView& rPrintView,
728 const SetOfByte& rVisibleLayers,
729 const SetOfByte& rPrintableLayers) const = 0;
731 sal_uLong GetDrawMode() const { return mnDrawMode; }
732 Orientation GetOrientation() const { return meOrientation; }
733 sal_uInt16 GetPaperTray() const { return mnPaperTray; }
735 protected:
736 const PageKind mePageKind;
737 const MapMode maMap;
738 const bool mbPrintMarkedOnly;
739 const OUString msPageString;
740 const Point maPageStringOffset;
741 const sal_uLong mnDrawMode;
742 const Orientation meOrientation;
743 const sal_uInt16 mnPaperTray;
749 /** The RegularPrinterPage is used for printing one regular slide (no
750 notes, handout, or outline) to one printer page.
752 class RegularPrinterPage : public PrinterPage
754 public:
755 RegularPrinterPage (
756 const sal_uInt16 nPageIndex,
757 const PageKind ePageKind,
758 const MapMode& rMapMode,
759 const bool bPrintMarkedOnly,
760 const OUString& rsPageString,
761 const Point& rPageStringOffset,
762 const sal_uLong nDrawMode,
763 const Orientation eOrientation,
764 const sal_uInt16 nPaperTray)
765 : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, rsPageString,
766 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
767 mnPageIndex(nPageIndex)
771 virtual ~RegularPrinterPage() {}
773 virtual void Print (
774 Printer& rPrinter,
775 SdDrawDocument& rDocument,
776 ViewShell& rViewShell,
777 View* pView,
778 DrawView& rPrintView,
779 const SetOfByte& rVisibleLayers,
780 const SetOfByte& rPrintableLayers) const
782 (void)rViewShell;
783 SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
784 rPrinter.SetMapMode(maMap);
785 PrintPage(
786 rPrinter,
787 rPrintView,
788 *pPageToPrint,
789 pView,
790 mbPrintMarkedOnly,
791 rVisibleLayers,
792 rPrintableLayers);
793 PrintMessage(
794 rPrinter,
795 msPageString,
796 maPageStringOffset);
799 private:
800 const sal_uInt16 mnPageIndex;
806 /** Print one slide multiple times on a printer page so that the whole
807 printer page is covered.
809 class TiledPrinterPage : public PrinterPage
811 public:
812 TiledPrinterPage (
813 const sal_uInt16 nPageIndex,
814 const PageKind ePageKind,
815 const sal_Int32 nGap,
816 const bool bPrintMarkedOnly,
817 const OUString& rsPageString,
818 const Point& rPageStringOffset,
819 const sal_uLong nDrawMode,
820 const Orientation eOrientation,
821 const sal_uInt16 nPaperTray)
822 : PrinterPage(ePageKind, MapMode(), bPrintMarkedOnly, rsPageString,
823 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
824 mnPageIndex(nPageIndex),
825 mnGap(nGap)
829 virtual ~TiledPrinterPage() {}
831 virtual void Print (
832 Printer& rPrinter,
833 SdDrawDocument& rDocument,
834 ViewShell& rViewShell,
835 View* pView,
836 DrawView& rPrintView,
837 const SetOfByte& rVisibleLayers,
838 const SetOfByte& rPrintableLayers) const
840 (void)rViewShell;
841 SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind);
842 if (pPageToPrint==NULL)
843 return;
844 MapMode aMap (rPrinter.GetMapMode());
846 const Size aPageSize (pPageToPrint->GetSize());
847 const Size aPrintSize (rPrinter.GetOutputSize());
849 const sal_Int32 nPageWidth (aPageSize.Width() + mnGap
850 - pPageToPrint->GetLftBorder() - pPageToPrint->GetRgtBorder());
851 const sal_Int32 nPageHeight (aPageSize.Height() + mnGap
852 - pPageToPrint->GetUppBorder() - pPageToPrint->GetLwrBorder());
853 if (nPageWidth<=0 || nPageHeight<=0)
854 return;
856 // Print at least two rows and columns. More if the document
857 // page fits completely onto the printer page.
858 const sal_Int32 nColumnCount (::std::max(sal_Int32(2),
859 sal_Int32(aPrintSize.Width() / nPageWidth)));
860 const sal_Int32 nRowCount (::std::max(sal_Int32(2),
861 sal_Int32(aPrintSize.Height() / nPageHeight)));
862 for (sal_Int32 nRow=0; nRow<nRowCount; ++nRow)
863 for (sal_Int32 nColumn=0; nColumn<nColumnCount; ++nColumn)
865 aMap.SetOrigin(Point(nColumn*nPageWidth,nRow*nPageHeight));
866 rPrinter.SetMapMode(aMap);
867 PrintPage(
868 rPrinter,
869 rPrintView,
870 *pPageToPrint,
871 pView,
872 mbPrintMarkedOnly,
873 rVisibleLayers,
874 rPrintableLayers);
877 PrintMessage(
878 rPrinter,
879 msPageString,
880 maPageStringOffset);
883 private:
884 const sal_uInt16 mnPageIndex;
885 const sal_Int32 mnGap;
888 /** Print two slides to one printer page so that the resulting pages
889 form a booklet.
891 class BookletPrinterPage : public PrinterPage
893 public:
894 BookletPrinterPage (
895 const sal_uInt16 nFirstPageIndex,
896 const sal_uInt16 nSecondPageIndex,
897 const Point& rFirstOffset,
898 const Point& rSecondOffset,
899 const PageKind ePageKind,
900 const MapMode& rMapMode,
901 const bool bPrintMarkedOnly,
902 const sal_uLong nDrawMode,
903 const Orientation eOrientation,
904 const sal_uInt16 nPaperTray)
905 : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, "",
906 Point(), nDrawMode, eOrientation, nPaperTray),
907 mnFirstPageIndex(nFirstPageIndex),
908 mnSecondPageIndex(nSecondPageIndex),
909 maFirstOffset(rFirstOffset),
910 maSecondOffset(rSecondOffset)
914 virtual ~BookletPrinterPage() {}
916 virtual void Print (
917 Printer& rPrinter,
918 SdDrawDocument& rDocument,
919 ViewShell& rViewShell,
920 View* pView,
921 DrawView& rPrintView,
922 const SetOfByte& rVisibleLayers,
923 const SetOfByte& rPrintableLayers) const
925 (void)rViewShell;
926 MapMode aMap (maMap);
927 SdPage* pPageToPrint = rDocument.GetSdPage(mnFirstPageIndex, mePageKind);
928 if (pPageToPrint)
930 aMap.SetOrigin(maFirstOffset);
931 rPrinter.SetMapMode(aMap);
932 PrintPage(
933 rPrinter,
934 rPrintView,
935 *pPageToPrint,
936 pView,
937 mbPrintMarkedOnly,
938 rVisibleLayers,
939 rPrintableLayers);
942 pPageToPrint = rDocument.GetSdPage(mnSecondPageIndex, mePageKind);
943 if( pPageToPrint )
945 aMap.SetOrigin(maSecondOffset);
946 rPrinter.SetMapMode(aMap);
947 PrintPage(
948 rPrinter,
949 rPrintView,
950 *pPageToPrint,
951 pView,
952 mbPrintMarkedOnly,
953 rVisibleLayers,
954 rPrintableLayers);
958 private:
959 const sal_uInt16 mnFirstPageIndex;
960 const sal_uInt16 mnSecondPageIndex;
961 const Point maFirstOffset;
962 const Point maSecondOffset;
968 /** One handout page displays one to nine slides.
970 class HandoutPrinterPage : public PrinterPage
972 public:
973 HandoutPrinterPage (
974 const sal_uInt16 nHandoutPageIndex,
975 const ::std::vector<sal_uInt16>& rPageIndices,
976 const MapMode& rMapMode,
977 const OUString& rsPageString,
978 const Point& rPageStringOffset,
979 const sal_uLong nDrawMode,
980 const Orientation eOrientation,
981 const sal_uInt16 nPaperTray)
982 : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
983 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
984 mnHandoutPageIndex(nHandoutPageIndex),
985 maPageIndices(rPageIndices)
989 virtual void Print (
990 Printer& rPrinter,
991 SdDrawDocument& rDocument,
992 ViewShell& rViewShell,
993 View* pView,
994 DrawView& rPrintView,
995 const SetOfByte& rVisibleLayers,
996 const SetOfByte& rPrintableLayers) const
998 SdPage& rHandoutPage (*rDocument.GetSdPage(0, PK_HANDOUT));
1000 Reference< com::sun::star::beans::XPropertySet > xHandoutPage( rHandoutPage.getUnoPage(), UNO_QUERY );
1001 const OUString sPageNumber( "Number" );
1003 // Collect the page objects of the handout master.
1004 std::vector<SdrPageObj*> aHandoutPageObjects;
1005 SdrObjListIter aShapeIter (rHandoutPage);
1006 while (aShapeIter.IsMore())
1008 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
1009 if (pPageObj)
1010 aHandoutPageObjects.push_back(pPageObj);
1012 if (aHandoutPageObjects.empty())
1013 return;
1015 // Connect page objects with pages.
1016 std::vector<SdrPageObj*>::iterator aPageObjIter (aHandoutPageObjects.begin());
1017 for (std::vector<sal_uInt16>::const_iterator
1018 iPageIndex(maPageIndices.begin()),
1019 iEnd(maPageIndices.end());
1020 iPageIndex!=iEnd && aPageObjIter!=aHandoutPageObjects.end();
1021 ++iPageIndex)
1023 // Check if the page still exists.
1024 if (*iPageIndex >= rDocument.GetSdPageCount(PK_STANDARD))
1025 continue;
1027 SdrPageObj* pPageObj = (*aPageObjIter++);
1028 pPageObj->SetReferencedPage(rDocument.GetSdPage(*iPageIndex, PK_STANDARD));
1031 // if there are more page objects than pages left, set the rest to invisible
1032 int nHangoverCount = 0;
1033 while (aPageObjIter != aHandoutPageObjects.end())
1035 (*aPageObjIter++)->SetReferencedPage(0L);
1036 nHangoverCount++;
1039 // Hide outlines for objects that have pages attached.
1040 if (nHangoverCount > 0)
1042 int nSkip = aHandoutPageObjects.size() - nHangoverCount;
1043 aShapeIter.Reset();
1044 while (aShapeIter.IsMore())
1046 SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
1047 if (pPathObj)
1049 if (nSkip > 0)
1050 --nSkip;
1051 else
1052 pPathObj->SetMergedItem(XLineStyleItem(XLINE_NONE));
1057 if( xHandoutPage.is() ) try
1059 xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(mnHandoutPageIndex) ) );
1061 catch( Exception& )
1064 rViewShell.SetPrintedHandoutPageNum( mnHandoutPageIndex + 1 );
1066 MapMode aMap (rPrinter.GetMapMode());
1067 rPrinter.SetMapMode(maMap);
1069 PrintPage(
1070 rPrinter,
1071 rPrintView,
1072 rHandoutPage,
1073 pView,
1074 false,
1075 rVisibleLayers,
1076 rPrintableLayers);
1077 PrintMessage(
1078 rPrinter,
1079 msPageString,
1080 maPageStringOffset);
1082 if( xHandoutPage.is() ) try
1084 xHandoutPage->setPropertyValue( sPageNumber, Any( static_cast<sal_Int16>(0) ) );
1086 catch( Exception& )
1089 rViewShell.SetPrintedHandoutPageNum(1);
1091 // Restore outlines.
1092 if (nHangoverCount > 0)
1094 aShapeIter.Reset();
1095 while (aShapeIter.IsMore())
1097 SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next());
1098 if (pPathObj != NULL)
1099 pPathObj->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1105 private:
1106 const sal_uInt16 mnHandoutPageIndex;
1107 const ::std::vector<sal_uInt16> maPageIndices;
1113 /** The outline information (title, subtitle, outline objects) of the
1114 document. There is no fixed mapping of slides to printer pages.
1116 class OutlinerPrinterPage : public PrinterPage
1118 public:
1119 OutlinerPrinterPage (
1120 OutlinerParaObject* pParaObject,
1121 const MapMode& rMapMode,
1122 const OUString& rsPageString,
1123 const Point& rPageStringOffset,
1124 const sal_uLong nDrawMode,
1125 const Orientation eOrientation,
1126 const sal_uInt16 nPaperTray)
1127 : PrinterPage(PK_HANDOUT, rMapMode, false, rsPageString,
1128 rPageStringOffset, nDrawMode, eOrientation, nPaperTray),
1129 mpParaObject(pParaObject)
1133 ~OutlinerPrinterPage()
1135 mpParaObject.reset();
1138 virtual void Print (
1139 Printer& rPrinter,
1140 SdDrawDocument& rDocument,
1141 ViewShell& rViewShell,
1142 View* pView,
1143 DrawView& rPrintView,
1144 const SetOfByte& rVisibleLayers,
1145 const SetOfByte& rPrintableLayers) const
1147 (void)rViewShell;
1148 (void)pView;
1149 (void)rPrintView;
1150 (void)rVisibleLayers;
1151 (void)rPrintableLayers;
1153 // Set up the printer.
1154 rPrinter.SetMapMode(maMap);
1156 // Get and set up the outliner.
1157 const Rectangle aOutRect (rPrinter.GetPageOffset(), rPrinter.GetOutputSize());
1158 Outliner* pOutliner = rDocument.GetInternalOutliner();
1159 const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1160 const sal_Bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1161 const Size aSavedPaperSize (pOutliner->GetPaperSize());
1163 pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1164 pOutliner->SetPaperSize(aOutRect.GetSize());
1165 pOutliner->SetUpdateMode(sal_True);
1166 pOutliner->Clear();
1167 pOutliner->SetText(*mpParaObject);
1169 pOutliner->Draw(&rPrinter, aOutRect);
1171 PrintMessage(
1172 rPrinter,
1173 msPageString,
1174 maPageStringOffset);
1176 // Restore outliner and printer.
1177 pOutliner->Clear();
1178 pOutliner->SetUpdateMode(bSavedUpdateMode);
1179 pOutliner->SetPaperSize(aSavedPaperSize);
1180 pOutliner->Init(nSavedOutlMode);
1183 private:
1184 ::boost::scoped_ptr<OutlinerParaObject> mpParaObject;
1189 //===== DocumentRenderer::Implementation ======================================
1191 class DocumentRenderer::Implementation
1192 : public SfxListener,
1193 public vcl::PrinterOptionsHelper
1195 public:
1196 Implementation (ViewShellBase& rBase)
1197 : mxObjectShell(rBase.GetDocShell())
1198 , mrBase(rBase)
1199 , mbIsDisposed(false)
1200 , mpPrinter(NULL)
1201 , mpOptions()
1202 , maPrinterPages()
1203 , mpPrintView()
1204 , mbHasOrientationWarningBeenShown(false)
1206 DialogCreator aCreator( mrBase.GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_IMPRESS, GetCurrentPageIndex() );
1207 m_aUIProperties = aCreator.GetDialogControls();
1208 maSlidesPerPage = aCreator.GetSlidesPerPage();
1210 StartListening(mrBase);
1216 virtual ~Implementation()
1218 EndListening(mrBase);
1224 virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
1226 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
1227 if (pSimpleHint != NULL
1228 && pSimpleHint->GetId() == SFX_HINT_DYING
1229 && &rBroadcaster == &static_cast<SfxBroadcaster&>(mrBase))
1231 Dispose();
1237 /** Process the sequence of properties given to one of the XRenderable
1238 methods.
1240 void ProcessProperties (const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
1242 OSL_ASSERT(!mbIsDisposed);
1243 if (mbIsDisposed)
1244 return;
1246 bool bIsValueChanged = processProperties( rOptions );
1247 bool bIsPaperChanged = false;
1249 // The RenderDevice property is handled specially: its value is
1250 // stored in mpPrinter instead of being retrieved on demand.
1251 Any aDev( getValue( "RenderDevice" ) );
1252 Reference<awt::XDevice> xRenderDevice;
1254 if (aDev >>= xRenderDevice)
1256 VCLXDevice* pDevice = VCLXDevice::GetImplementation(xRenderDevice);
1257 OutputDevice* pOut = pDevice ? pDevice->GetOutputDevice() : NULL;
1258 mpPrinter = dynamic_cast<Printer*>(pOut);
1259 Size aPageSizePixel = mpPrinter ? mpPrinter->GetPaperSizePixel() : Size();
1260 if( aPageSizePixel != maPrinterPageSizePixel )
1262 bIsPaperChanged = true;
1263 maPrinterPageSizePixel = aPageSizePixel;
1267 if (bIsValueChanged)
1269 if ( ! mpOptions )
1270 mpOptions.reset(new PrintOptions(*this, maSlidesPerPage));
1272 if( bIsValueChanged || bIsPaperChanged )
1273 PreparePages();
1278 /** Return the number of pages that are to be printed.
1280 sal_Int32 GetPrintPageCount()
1282 OSL_ASSERT(!mbIsDisposed);
1283 if (mbIsDisposed)
1284 return 0;
1285 else
1286 return maPrinterPages.size();
1291 /** Return a sequence of properties that can be returned by the
1292 XRenderable::getRenderer() method.
1294 css::uno::Sequence<css::beans::PropertyValue> GetProperties (
1295 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
1297 (void)rOptions;
1299 css::uno::Sequence<css::beans::PropertyValue> aProperties (3);
1301 aProperties[0].Name = "ExtraPrintUIOptions";
1302 aProperties[0].Value <<= m_aUIProperties;
1304 aProperties[1].Name = "PageSize";
1305 aProperties[1].Value <<= maPrintSize;
1307 // FIXME: is this always true ?
1308 aProperties[2].Name = "PageIncludesNonprintableArea";
1309 aProperties[2].Value = makeAny( sal_True );
1311 return aProperties;
1317 /** Print one of the prepared pages.
1319 void PrintPage (const sal_Int32 nIndex)
1321 OSL_ASSERT(!mbIsDisposed);
1322 if (mbIsDisposed)
1323 return;
1325 Printer& rPrinter (*mpPrinter);
1327 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1328 if ( ! pViewShell)
1329 return;
1331 SdDrawDocument* pDocument = pViewShell->GetDoc();
1332 OSL_ASSERT(pDocument!=NULL);
1334 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
1335 ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
1337 if ( ! mpPrintView)
1338 mpPrintView.reset(new DrawView(mrBase.GetDocShell(), &rPrinter, NULL));
1340 if (nIndex<0 || sal::static_int_cast<sal_uInt32>(nIndex)>=maPrinterPages.size())
1341 return;
1343 const ::boost::shared_ptr<PrinterPage> pPage (maPrinterPages[nIndex]);
1344 OSL_ASSERT(pPage);
1345 if ( ! pPage)
1346 return;
1348 const Orientation eSavedOrientation (rPrinter.GetOrientation());
1349 const sal_uLong nSavedDrawMode (rPrinter.GetDrawMode());
1350 const MapMode aSavedMapMode (rPrinter.GetMapMode());
1351 const sal_uInt16 nSavedPaperBin (rPrinter.GetPaperBin());
1354 // Set page orientation.
1355 if ( ! rPrinter.SetOrientation(pPage->GetOrientation()))
1357 if ( ! mbHasOrientationWarningBeenShown
1358 && mpOptions->IsWarningOrientation())
1360 mbHasOrientationWarningBeenShown = true;
1361 // Show warning that the orientation could not be set.
1362 if (pViewShell)
1364 WarningBox aWarnBox(
1365 pViewShell->GetActiveWindow(),
1366 (WinBits)(WB_OK_CANCEL | WB_DEF_CANCEL),
1367 String(SdResId(STR_WARN_PRINTFORMAT_FAILURE)));
1368 if (aWarnBox.Execute() != RET_OK)
1369 return;
1374 // Set the draw mode.
1375 rPrinter.SetDrawMode(pPage->GetDrawMode());
1377 // Set paper tray.
1378 rPrinter.SetPaperBin(pPage->GetPaperTray());
1380 // Print the actual page.
1381 pPage->Print(
1382 rPrinter,
1383 *pDocument,
1384 *pViewShell,
1385 pDrawViewShell ? pDrawViewShell->GetView() : NULL,
1386 *mpPrintView,
1387 pViewShell->GetFrameView()->GetVisibleLayers(),
1388 pViewShell->GetFrameView()->GetPrintableLayers());
1390 rPrinter.SetOrientation(eSavedOrientation);
1391 rPrinter.SetDrawMode(nSavedDrawMode);
1392 rPrinter.SetMapMode(aSavedMapMode);
1393 rPrinter.SetPaperBin(nSavedPaperBin);
1399 private:
1400 // rhbz#657394: keep the document alive: prevents crash when
1401 SfxObjectShellRef mxObjectShell; // destroying mpPrintView
1402 ViewShellBase& mrBase;
1403 bool mbIsDisposed;
1404 Printer* mpPrinter;
1405 Size maPrinterPageSizePixel;
1406 ::boost::scoped_ptr<PrintOptions> mpOptions;
1407 ::std::vector< ::boost::shared_ptr< ::sd::PrinterPage> > maPrinterPages;
1408 ::boost::scoped_ptr<DrawView> mpPrintView;
1409 bool mbHasOrientationWarningBeenShown;
1410 ::std::vector<sal_Int32> maSlidesPerPage;
1411 awt::Size maPrintSize;
1413 void Dispose()
1415 mbIsDisposed = true;
1418 sal_Int32 GetCurrentPageIndex() const
1420 const ViewShell *pShell = mrBase.GetMainViewShell().get();
1421 const SdPage *pCurrentPage = pShell ? pShell->getCurrentPage() : NULL;
1422 return pCurrentPage ? (pCurrentPage->GetPageNum()-1)/2 : -1;
1425 /** Determine and set the paper orientation.
1427 bool SetupPaperOrientation (
1428 const PageKind ePageKind,
1429 PrintInfo& rInfo)
1431 SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1432 rInfo.meOrientation = ORIENTATION_PORTRAIT;
1434 if( ! mpOptions->IsBooklet())
1436 rInfo.meOrientation = pDocument->GetSdPage(0, ePageKind)->GetOrientation();
1438 else if (rInfo.maPageSize.Width() < rInfo.maPageSize.Height())
1439 rInfo.meOrientation = ORIENTATION_LANDSCAPE;
1441 const Size aPaperSize (rInfo.mpPrinter->GetPaperSize());
1442 if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1443 (aPaperSize.Width() < aPaperSize.Height()))
1445 (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1446 (aPaperSize.Width() > aPaperSize.Height()))
1449 maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1451 else
1453 maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1456 return true;
1461 /** Top most method for preparing printer pages. In this and the other
1462 Prepare... methods the various special cases are detected and
1463 handled.
1464 For every page that is to be printed (that may contain several
1465 slides) one PrinterPage object is created and inserted into
1466 maPrinterPages.
1468 void PreparePages()
1470 mpPrintView.reset();
1471 maPrinterPages.clear();
1472 mbHasOrientationWarningBeenShown = false;
1474 ViewShell* pShell = mrBase.GetMainViewShell().get();
1476 PrintInfo aInfo (mpPrinter, mpOptions->IsPrintMarkedOnly());
1478 if (aInfo.mpPrinter!=NULL && pShell!=NULL)
1481 MapMode aMap (aInfo.mpPrinter->GetMapMode());
1482 aMap.SetMapUnit(MAP_100TH_MM);
1483 aInfo.maMap = aMap;
1484 mpPrinter->SetMapMode(aMap);
1486 ::Outliner& rOutliner = mrBase.GetDocument()->GetDrawOutliner();
1487 const sal_uLong nSavedControlWord (rOutliner.GetControlWord());
1488 sal_uLong nCntrl = nSavedControlWord;
1489 nCntrl &= ~EE_CNTRL_MARKFIELDS;
1490 nCntrl &= ~EE_CNTRL_ONLINESPELLING;
1491 rOutliner.SetControlWord( nCntrl );
1493 // When in outline view then apply all pending changes to the model.
1494 if (pShell->ISA(OutlineViewShell))
1495 static_cast<OutlineViewShell*>(pShell)->PrepareClose (sal_False, sal_False);
1497 // Collect some frequently used data.
1498 if (mpOptions->IsDate())
1500 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getDate( Date( Date::SYSTEM ) );
1501 aInfo.msTimeDate += OUString((sal_Unicode)' ');
1504 if (mpOptions->IsTime())
1505 aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData()->getTime( Time( Time::SYSTEM ), sal_False, sal_False );
1506 aInfo.maPrintSize = aInfo.mpPrinter->GetOutputSize();
1507 maPrintSize = awt::Size(
1508 aInfo.mpPrinter->GetPaperSize().Width(),
1509 aInfo.mpPrinter->GetPaperSize().Height());
1511 switch (mpOptions->GetOutputQuality())
1513 case 1:
1514 aInfo.mnDrawMode = DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL
1515 | DRAWMODE_GRAYTEXT | DRAWMODE_GRAYBITMAP
1516 | DRAWMODE_GRAYGRADIENT;
1517 break;
1519 case 2:
1520 aInfo.mnDrawMode = DRAWMODE_BLACKLINE | DRAWMODE_WHITEFILL
1521 | DRAWMODE_BLACKTEXT | DRAWMODE_WHITEBITMAP
1522 | DRAWMODE_WHITEGRADIENT;
1523 break;
1525 default:
1526 aInfo.mnDrawMode = DRAWMODE_DEFAULT;
1529 if (mpOptions->IsDraw())
1530 PrepareStdOrNotes(PK_STANDARD, aInfo);
1531 if (mpOptions->IsNotes())
1532 PrepareStdOrNotes(PK_NOTES, aInfo);
1533 if (mpOptions->IsHandout())
1535 InitHandoutTemplate();
1536 PrepareHandout(aInfo);
1538 if (mpOptions->IsOutline())
1539 PrepareOutline(aInfo);
1541 rOutliner.SetControlWord(nSavedControlWord);
1548 /** Create the page objects of the handout template. When the actual
1549 printing takes place then the page objects are assigned different
1550 sets of slides for each printed page (see HandoutPrinterPage::Print).
1552 void InitHandoutTemplate()
1554 const sal_Int32 nSlidesPerHandout (mpOptions->GetHandoutPageCount());
1555 const bool bHandoutHorizontal (mpOptions->IsHandoutHorizontal());
1557 AutoLayout eLayout = AUTOLAYOUT_HANDOUT6;
1558 switch (nSlidesPerHandout)
1560 case 0: eLayout = AUTOLAYOUT_NONE; break; // AUTOLAYOUT_HANDOUT1; break;
1561 case 1: eLayout = AUTOLAYOUT_HANDOUT1; break;
1562 case 2: eLayout = AUTOLAYOUT_HANDOUT2; break;
1563 case 3: eLayout = AUTOLAYOUT_HANDOUT3; break;
1564 case 4: eLayout = AUTOLAYOUT_HANDOUT4; break;
1565 default:
1566 case 6: eLayout = AUTOLAYOUT_HANDOUT6; break;
1567 case 9: eLayout = AUTOLAYOUT_HANDOUT9; break;
1570 if( !mrBase.GetDocument() )
1571 return;
1573 SdDrawDocument& rModel = *mrBase.GetDocument();
1575 // first, prepare handout page (not handout master)
1577 SdPage* pHandout = rModel.GetSdPage(0, PK_HANDOUT);
1578 if( !pHandout )
1579 return;
1581 // delete all previous shapes from handout page
1582 while( pHandout->GetObjCount() )
1584 SdrObject* pObj = pHandout->NbcRemoveObject(0);
1585 if( pObj )
1586 SdrObject::Free( pObj );
1589 const bool bDrawLines (eLayout == AUTOLAYOUT_HANDOUT3);
1591 std::vector< Rectangle > aAreas;
1592 SdPage::CalculateHandoutAreas( rModel, eLayout, bHandoutHorizontal, aAreas );
1594 std::vector< Rectangle >::iterator iter( aAreas.begin() );
1595 while( iter != aAreas.end() )
1597 pHandout->NbcInsertObject( new SdrPageObj((*iter++)) );
1599 if( bDrawLines && (iter != aAreas.end()) )
1601 Rectangle aRect( (*iter++) );
1603 basegfx::B2DPolygon aPoly;
1604 aPoly.insert(0, basegfx::B2DPoint( aRect.Left(), aRect.Top() ) );
1605 aPoly.insert(1, basegfx::B2DPoint( aRect.Right(), aRect.Top() ) );
1607 basegfx::B2DHomMatrix aMatrix;
1608 aMatrix.translate( 0.0, static_cast< double >( aRect.GetHeight() / 7 ) );
1610 basegfx::B2DPolyPolygon aPathPoly;
1611 for( sal_uInt16 nLine = 0; nLine < 7; nLine++ )
1613 aPoly.transform( aMatrix );
1614 aPathPoly.append( aPoly );
1617 SdrPathObj* pPathObj = new SdrPathObj(OBJ_PATHLINE, aPathPoly );
1618 pPathObj->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1619 pPathObj->SetMergedItem(XLineColorItem(String(), Color(COL_BLACK)));
1621 pHandout->NbcInsertObject( pPathObj );
1629 /** Detect whether the specified slide is to be printed.
1630 @return
1631 When the slide is not to be printed then <NULL/> is returned.
1632 Otherwise a pointer to the slide is returned.
1634 SdPage* GetFilteredPage (
1635 const sal_Int32 nPageIndex,
1636 const PageKind ePageKind) const
1638 OSL_ASSERT(mrBase.GetDocument() != NULL);
1639 OSL_ASSERT(nPageIndex>=0);
1640 SdPage* pPage = mrBase.GetDocument()->GetSdPage(
1641 sal::static_int_cast<sal_uInt16>(nPageIndex),
1642 ePageKind);
1643 if (pPage == NULL)
1644 return NULL;
1645 if ( ! pPage->IsExcluded() || mpOptions->IsPrintExcluded())
1646 return pPage;
1647 else
1648 return NULL;
1654 /** Prepare the outline of the document for printing. There is no fixed
1655 number of slides whose outline data is put onto one printer page.
1656 If the current printer page has enough room for the outline of the
1657 current slide then that is added. Otherwise a new printer page is
1658 started.
1660 void PrepareOutline (PrintInfo& rInfo)
1662 MapMode aMap (rInfo.maMap);
1663 Point aPageOfs (rInfo.mpPrinter->GetPageOffset() );
1664 aMap.SetScaleX(Fraction(1,2));
1665 aMap.SetScaleY(Fraction(1,2));
1666 mpPrinter->SetMapMode(aMap);
1668 Rectangle aOutRect(aPageOfs, rInfo.mpPrinter->GetOutputSize());
1669 if( aOutRect.GetWidth() > aOutRect.GetHeight() )
1671 Size aPaperSize( rInfo.mpPrinter->PixelToLogic( rInfo.mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
1672 maPrintSize.Width = aPaperSize.Height();
1673 maPrintSize.Height = aPaperSize.Width();
1674 aOutRect = Rectangle( Point( aPageOfs.Y(), aPageOfs.X() ),
1675 Size( aOutRect.GetHeight(), aOutRect.GetWidth() ) );
1678 Link aOldLink;
1679 Outliner* pOutliner = mrBase.GetDocument()->GetInternalOutliner();
1680 pOutliner->Init(OUTLINERMODE_OUTLINEVIEW);
1681 const sal_uInt16 nSavedOutlMode (pOutliner->GetMode());
1682 const sal_Bool bSavedUpdateMode (pOutliner->GetUpdateMode());
1683 const Size aSavedPaperSize (pOutliner->GetPaperSize());
1684 const MapMode aSavedMapMode (pOutliner->GetRefMapMode());
1685 pOutliner->SetPaperSize(aOutRect.GetSize());
1686 pOutliner->SetUpdateMode(sal_True);
1688 long nPageH = aOutRect.GetHeight();
1690 ::std::vector< sal_Int32 > aPages;
1691 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1692 StringRangeEnumerator::getRangesFromString(
1693 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1694 aPages, 0, nPageCount-1);
1696 for (size_t nIndex = 0, nCount = aPages.size(); nIndex < nCount;)
1698 pOutliner->Clear();
1699 pOutliner->SetFirstPageNumber(aPages[nIndex]+1);
1701 Paragraph* pPara = NULL;
1702 sal_Int32 nH (0);
1703 while (nH < nPageH && nIndex<nCount)
1705 SdPage* pPage = GetFilteredPage(aPages[nIndex], PK_STANDARD);
1706 ++nIndex;
1707 if (pPage == NULL)
1708 continue;
1710 SdrTextObj* pTextObj = NULL;
1711 sal_uInt32 nObj (0);
1713 while (pTextObj==NULL && nObj < pPage->GetObjCount())
1715 SdrObject* pObj = pPage->GetObj(nObj++);
1716 if (pObj->GetObjInventor() == SdrInventor
1717 && pObj->GetObjIdentifier() == OBJ_TITLETEXT)
1719 pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1723 pPara = pOutliner->GetParagraph(pOutliner->GetParagraphCount() - 1);
1725 if (pTextObj!=NULL
1726 && !pTextObj->IsEmptyPresObj()
1727 && pTextObj->GetOutlinerParaObject())
1729 pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1731 else
1732 pOutliner->Insert(String());
1734 pTextObj = NULL;
1735 nObj = 0;
1737 while (pTextObj==NULL && nObj<pPage->GetObjCount())
1739 SdrObject* pObj = pPage->GetObj(nObj++);
1740 if (pObj->GetObjInventor() == SdrInventor
1741 && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT)
1743 pTextObj = dynamic_cast<SdrTextObj*>(pObj);
1747 bool bSubTitle (false);
1748 if (!pTextObj)
1750 bSubTitle = true;
1751 pTextObj = dynamic_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_TEXT)); // Untertitel vorhanden?
1754 sal_Int32 nParaCount1 = pOutliner->GetParagraphCount();
1756 if (pTextObj!=NULL
1757 && !pTextObj->IsEmptyPresObj()
1758 && pTextObj->GetOutlinerParaObject())
1760 pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
1763 if (bSubTitle )
1765 const sal_Int32 nParaCount2 (pOutliner->GetParagraphCount());
1766 for (sal_Int32 nPara=nParaCount1; nPara<nParaCount2; ++nPara)
1768 Paragraph* pP = pOutliner->GetParagraph(nPara);
1769 if (pP!=NULL && pOutliner->GetDepth(nPara) > 0)
1770 pOutliner->SetDepth(pP, 0);
1774 nH = pOutliner->GetTextHeight();
1777 // Remove the last paragraph when that does not fit completely on
1778 // the current page.
1779 if (nH > nPageH && pPara!=NULL)
1781 sal_Int32 nCnt = pOutliner->GetAbsPos(
1782 pOutliner->GetParagraph( pOutliner->GetParagraphCount() - 1 ) );
1783 sal_Int32 nParaPos = pOutliner->GetAbsPos( pPara );
1784 nCnt -= nParaPos;
1785 pPara = pOutliner->GetParagraph( ++nParaPos );
1786 if ( nCnt && pPara )
1788 pOutliner->Remove(pPara, nCnt);
1789 --nIndex;
1793 maPrinterPages.push_back(
1794 ::boost::shared_ptr<PrinterPage>(
1795 new OutlinerPrinterPage(
1796 pOutliner->CreateParaObject(),
1797 aMap,
1798 rInfo.msTimeDate,
1799 aPageOfs,
1800 rInfo.mnDrawMode,
1801 rInfo.meOrientation,
1802 rInfo.mpPrinter->GetPaperBin())));
1805 pOutliner->SetRefMapMode(aSavedMapMode);
1806 pOutliner->SetUpdateMode(bSavedUpdateMode);
1807 pOutliner->SetPaperSize(aSavedPaperSize);
1808 pOutliner->Init(nSavedOutlMode);
1814 /** Prepare handout pages for slides that are to be printed.
1816 void PrepareHandout (PrintInfo& rInfo)
1818 SdDrawDocument* pDocument = mrBase.GetDocument();
1819 OSL_ASSERT(pDocument != NULL);
1820 SdPage& rHandoutPage (*pDocument->GetSdPage(0, PK_HANDOUT));
1822 const bool bScalePage (mpOptions->IsPageSize());
1824 sal_uInt16 nPaperBin;
1825 if ( ! mpOptions->IsPaperBin())
1826 nPaperBin = rHandoutPage.GetPaperBin();
1827 else
1828 nPaperBin = rInfo.mpPrinter->GetPaperBin();
1830 // Change orientation?
1831 SdPage& rMaster (dynamic_cast<SdPage&>(rHandoutPage.TRG_GetMasterPage()));
1832 rInfo.meOrientation = rMaster.GetOrientation();
1834 const Size aPaperSize (rInfo.mpPrinter->GetPaperSize());
1835 if( (rInfo.meOrientation == ORIENTATION_LANDSCAPE &&
1836 (aPaperSize.Width() < aPaperSize.Height()))
1838 (rInfo.meOrientation == ORIENTATION_PORTRAIT &&
1839 (aPaperSize.Width() > aPaperSize.Height()))
1842 maPrintSize = awt::Size(aPaperSize.Height(), aPaperSize.Width());
1844 else
1846 maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height());
1849 MapMode aMap (rInfo.maMap);
1850 const Point aPageOfs (rInfo.mpPrinter->GetPageOffset());
1852 if ( bScalePage )
1854 const Size aPageSize (rHandoutPage.GetSize());
1855 const Size aPrintSize (rInfo.mpPrinter->GetOutputSize());
1857 const double fHorz = (double) aPrintSize.Width() / aPageSize.Width();
1858 const double fVert = (double) aPrintSize.Height() / aPageSize.Height();
1860 Fraction aFract;
1861 if ( fHorz < fVert )
1862 aFract = Fraction(aPrintSize.Width(), aPageSize.Width());
1863 else
1864 aFract = Fraction(aPrintSize.Height(), aPageSize.Height());
1866 aMap.SetScaleX(aFract);
1867 aMap.SetScaleY(aFract);
1868 aMap.SetOrigin(Point());
1871 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1872 pViewShell->WriteFrameViewData();
1874 // Count page shapes.
1875 sal_uInt32 nShapeCount (0);
1876 SdrObjListIter aShapeIter (rHandoutPage);
1877 while (aShapeIter.IsMore())
1879 SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next());
1880 if (pPageObj)
1881 ++nShapeCount;
1884 const sal_uInt16 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1885 const sal_uInt16 nHandoutPageCount = nShapeCount ? (nPageCount + nShapeCount - 1) / nShapeCount : 0;
1886 pViewShell->SetPrintedHandoutPageCount( nHandoutPageCount );
1887 mrBase.GetDocument()->setHandoutPageCount( nHandoutPageCount );
1889 // Distribute pages to handout pages.
1890 StringRangeEnumerator aRangeEnum(
1891 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1892 0, nPageCount-1);
1893 ::std::vector<sal_uInt16> aPageIndices;
1894 sal_uInt16 nPrinterPageIndex = 0;
1895 StringRangeEnumerator::Iterator it = aRangeEnum.begin(), itEnd = aRangeEnum.end();
1896 bool bLastLoop = (it == itEnd);
1897 while (!bLastLoop)
1899 sal_Int32 nPageIndex = *it;
1900 ++it;
1901 bLastLoop = (it == itEnd);
1903 if (GetFilteredPage(nPageIndex, PK_STANDARD))
1904 aPageIndices.push_back(nPageIndex);
1905 else if (!bLastLoop)
1906 continue;
1908 // Create a printer page when we have found one page for each
1909 // placeholder or when this is the last (and special) loop.
1910 if (!aPageIndices.empty() && (aPageIndices.size() == nShapeCount || bLastLoop))
1912 maPrinterPages.push_back(
1913 ::boost::shared_ptr<PrinterPage>(
1914 new HandoutPrinterPage(
1915 nPrinterPageIndex++,
1916 aPageIndices,
1917 aMap,
1918 rInfo.msTimeDate,
1919 aPageOfs,
1920 rInfo.mnDrawMode,
1921 rInfo.meOrientation,
1922 nPaperBin)));
1923 aPageIndices.clear();
1931 /** Prepare the notes pages or regular slides.
1933 void PrepareStdOrNotes (
1934 const PageKind ePageKind,
1935 PrintInfo& rInfo)
1937 OSL_ASSERT(rInfo.mpPrinter != NULL);
1939 // Fill in page kind specific data.
1940 SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
1941 if (pDocument->GetSdPageCount(ePageKind) == 0)
1942 return;
1943 SdPage* pRefPage = pDocument->GetSdPage(0, ePageKind);
1944 rInfo.maPageSize = pRefPage->GetSize();
1946 if ( ! SetupPaperOrientation(ePageKind, rInfo))
1947 return;
1949 MapMode aMap (rInfo.maMap);
1950 rInfo.maMap = aMap;
1952 if (mpOptions->IsBooklet())
1953 PrepareBooklet(ePageKind, rInfo);
1954 else
1955 PrepareRegularPages(ePageKind, rInfo);
1961 /** Prepare slides in a non-booklet way: one slide per one to many
1962 printer pages.
1964 void PrepareRegularPages (
1965 const PageKind ePageKind,
1966 PrintInfo& rInfo)
1968 ::boost::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
1969 pViewShell->WriteFrameViewData();
1971 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(PK_STANDARD);
1972 StringRangeEnumerator aRangeEnum(
1973 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
1974 0, nPageCount-1);
1975 for (StringRangeEnumerator::Iterator
1976 it = aRangeEnum.begin(),
1977 itEnd = aRangeEnum.end();
1978 it != itEnd;
1979 ++it)
1981 SdPage* pPage = GetFilteredPage(*it, ePageKind);
1982 if (pPage == NULL)
1983 continue;
1985 MapMode aMap (rInfo.maMap);
1986 // is it possible that the page size changed?
1987 const Size aPageSize = pPage->GetSize();
1989 if (mpOptions->IsPageSize())
1991 const double fHorz ((double) rInfo.maPrintSize.Width() / aPageSize.Width());
1992 const double fVert ((double) rInfo.maPrintSize.Height() / aPageSize.Height());
1994 Fraction aFract;
1995 if (fHorz < fVert)
1996 aFract = Fraction(rInfo.maPrintSize.Width(), aPageSize.Width());
1997 else
1998 aFract = Fraction(rInfo.maPrintSize.Height(), aPageSize.Height());
2000 aMap.SetScaleX(aFract);
2001 aMap.SetScaleY(aFract);
2002 aMap.SetOrigin(Point());
2005 if (mpOptions->IsPrintPageName())
2007 rInfo.msPageString = pPage->GetName();
2008 rInfo.msPageString += OUString(sal_Unicode(' '));
2010 else
2011 rInfo.msPageString = "";
2012 rInfo.msPageString += rInfo.msTimeDate;
2014 long aPageWidth = aPageSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder();
2015 long aPageHeight = aPageSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder();
2016 // Bugfix for 44530:
2017 // if it was implicitly changed (Landscape/Portrait),
2018 // this is considered for tiling, respectively for the splitting up
2019 // (Poster)
2020 if( ( rInfo.maPrintSize.Width() > rInfo.maPrintSize.Height()
2021 && aPageWidth < aPageHeight )
2022 || ( rInfo.maPrintSize.Width() < rInfo.maPrintSize.Height()
2023 && aPageWidth > aPageHeight ) )
2025 const sal_Int32 nTmp (rInfo.maPrintSize.Width());
2026 rInfo.maPrintSize.Width() = rInfo.maPrintSize.Height();
2027 rInfo.maPrintSize.Height() = nTmp;
2030 if (mpOptions->IsTilePage()
2031 && aPageWidth < rInfo.maPrintSize.Width()
2032 && aPageHeight < rInfo.maPrintSize.Height())
2034 // Put multiple slides on one printer page.
2035 PrepareTiledPage(*it, *pPage, ePageKind, rInfo);
2037 else
2039 rInfo.maMap = aMap;
2040 PrepareScaledPage(*it, *pPage, ePageKind, rInfo);
2048 /** Put two slides on one printer page.
2050 void PrepareBooklet (
2051 const PageKind ePageKind,
2052 const PrintInfo& rInfo)
2054 MapMode aStdMap (rInfo.maMap);
2055 Point aOffset;
2056 Size aPrintSize_2 (rInfo.maPrintSize);
2057 Size aPageSize_2 (rInfo.maPageSize);
2059 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2060 aPrintSize_2.Width() >>= 1;
2061 else
2062 aPrintSize_2.Height() >>= 1;
2064 const double fPageWH = (double) aPageSize_2.Width() / aPageSize_2.Height();
2065 const double fPrintWH = (double) aPrintSize_2.Width() / aPrintSize_2.Height();
2067 if( fPageWH < fPrintWH )
2069 aPageSize_2.Width() = (long) ( aPrintSize_2.Height() * fPageWH );
2070 aPageSize_2.Height()= aPrintSize_2.Height();
2072 else
2074 aPageSize_2.Width() = aPrintSize_2.Width();
2075 aPageSize_2.Height() = (long) ( aPrintSize_2.Width() / fPageWH );
2078 MapMode aMap (rInfo.maMap);
2079 aMap.SetScaleX( Fraction( aPageSize_2.Width(), rInfo.maPageSize.Width() ) );
2080 aMap.SetScaleY( Fraction( aPageSize_2.Height(), rInfo.maPageSize.Height() ) );
2082 // calculate adjusted print size
2083 const Size aAdjustedPrintSize (OutputDevice::LogicToLogic(
2084 rInfo.maPrintSize,
2085 aStdMap,
2086 aMap));
2088 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2090 aOffset.X() = ( ( aAdjustedPrintSize.Width() >> 1 ) - rInfo.maPageSize.Width() ) >> 1;
2091 aOffset.Y() = ( aAdjustedPrintSize.Height() - rInfo.maPageSize.Height() ) >> 1;
2093 else
2095 aOffset.X() = ( aAdjustedPrintSize.Width() - rInfo.maPageSize.Width() ) >> 1;
2096 aOffset.Y() = ( ( aAdjustedPrintSize.Height() >> 1 ) - rInfo.maPageSize.Height() ) >> 1;
2099 // create vector of pages to print
2100 sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(ePageKind);
2101 StringRangeEnumerator aRangeEnum(
2102 mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
2103 0, nPageCount-1);
2104 ::std::vector< sal_uInt16 > aPageVector;
2105 for (StringRangeEnumerator::Iterator
2106 it = aRangeEnum.begin(),
2107 itEnd = aRangeEnum.end();
2108 it != itEnd;
2109 ++it)
2111 SdPage* pPage = GetFilteredPage(*it, ePageKind);
2112 if (pPage != NULL)
2113 aPageVector.push_back(*it);
2116 // create pairs of pages to print on each page
2117 typedef ::std::vector< ::std::pair< sal_uInt16, sal_uInt16 > > PairVector;
2118 PairVector aPairVector;
2119 if ( ! aPageVector.empty())
2121 sal_uInt32 nFirstIndex = 0, nLastIndex = aPageVector.size() - 1;
2123 if( aPageVector.size() & 1 )
2124 aPairVector.push_back( ::std::make_pair( (sal_uInt16) 65535, aPageVector[ nFirstIndex++ ] ) );
2125 else
2126 aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2128 while( nFirstIndex < nLastIndex )
2130 if( nFirstIndex & 1 )
2131 aPairVector.push_back( ::std::make_pair( aPageVector[ nFirstIndex++ ], aPageVector[ nLastIndex-- ] ) );
2132 else
2133 aPairVector.push_back( ::std::make_pair( aPageVector[ nLastIndex-- ], aPageVector[ nFirstIndex++ ] ) );
2137 for (sal_uInt32
2138 nIndex=0,
2139 nCount=aPairVector.size();
2140 nIndex < nCount;
2141 ++nIndex)
2143 const bool bIsIndexOdd (nIndex & 1);
2144 if ((!bIsIndexOdd && mpOptions->IsPrintFrontPage())
2145 || (bIsIndexOdd && mpOptions->IsPrintBackPage()))
2147 const ::std::pair<sal_uInt16, sal_uInt16> aPair (aPairVector[nIndex]);
2148 Point aSecondOffset (aOffset);
2149 if (rInfo.meOrientation == ORIENTATION_LANDSCAPE)
2150 aSecondOffset.X() += aAdjustedPrintSize.Width() / 2;
2151 else
2152 aSecondOffset.Y() += aAdjustedPrintSize.Height() / 2;
2153 maPrinterPages.push_back(
2154 ::boost::shared_ptr<PrinterPage>(
2155 new BookletPrinterPage(
2156 aPair.first,
2157 aPair.second,
2158 aOffset,
2159 aSecondOffset,
2160 ePageKind,
2161 aMap,
2162 rInfo.mbPrintMarkedOnly,
2163 rInfo.mnDrawMode,
2164 rInfo.meOrientation,
2165 rInfo.mpPrinter->GetPaperBin())));
2174 /** Print one slide multiple times on one printer page so that the whole
2175 printer page is covered.
2177 void PrepareTiledPage (
2178 const sal_Int32 nPageIndex,
2179 const SdPage& rPage,
2180 const PageKind ePageKind,
2181 const PrintInfo& rInfo)
2183 sal_uInt16 nPaperBin;
2184 if ( ! mpOptions->IsPaperBin())
2185 nPaperBin = rPage.GetPaperBin();
2186 else
2187 nPaperBin = rInfo.mpPrinter->GetPaperBin();
2189 maPrinterPages.push_back(
2190 ::boost::shared_ptr<PrinterPage>(
2191 new TiledPrinterPage(
2192 sal::static_int_cast<sal_uInt16>(nPageIndex),
2193 ePageKind,
2194 500,
2195 rInfo.mbPrintMarkedOnly,
2196 rInfo.msPageString,
2197 rInfo.mpPrinter->GetPageOffset(),
2198 rInfo.mnDrawMode,
2199 rInfo.meOrientation,
2200 nPaperBin)));
2205 /** Print one standard slide or notes page on one to many printer
2206 pages. More than on printer page is used when the slide is larger
2207 than the printable area.
2209 void PrepareScaledPage (
2210 const sal_Int32 nPageIndex,
2211 const SdPage& rPage,
2212 const PageKind ePageKind,
2213 const PrintInfo& rInfo)
2215 const Point aPageOffset (rInfo.mpPrinter->GetPageOffset());
2217 sal_uInt16 nPaperBin;
2218 if ( ! mpOptions->IsPaperBin())
2219 nPaperBin = rPage.GetPaperBin();
2220 else
2221 nPaperBin = rInfo.mpPrinter->GetPaperBin();
2223 // For pages larger then the printable area there
2224 // are three options:
2225 // 1. Scale down to the page to the printable area.
2226 // 2. Print only the upper left part of the page
2227 // (without the unprintable borders).
2228 // 3. Split the page into parts of the size of the
2229 // printable area.
2230 const bool bScalePage (mpOptions->IsPageSize());
2231 const bool bCutPage (mpOptions->IsCutPage());
2232 MapMode aMap (rInfo.maMap);
2233 if (bScalePage || bCutPage)
2235 // Handle 1 and 2.
2237 // if CutPage is set then do not move it, otherwise move the
2238 // scaled page to printable area
2239 maPrinterPages.push_back(
2240 ::boost::shared_ptr<PrinterPage>(
2241 new RegularPrinterPage(
2242 sal::static_int_cast<sal_uInt16>(nPageIndex),
2243 ePageKind,
2244 aMap,
2245 rInfo.mbPrintMarkedOnly,
2246 rInfo.msPageString,
2247 aPageOffset,
2248 rInfo.mnDrawMode,
2249 rInfo.meOrientation,
2250 nPaperBin)));
2252 else
2254 // Handle 3. Print parts of the page in the size of the
2255 // printable area until the whole page is covered.
2257 // keep the page content at its position if it fits, otherwise
2258 // move it to the printable area
2259 const long nPageWidth (
2260 rInfo.maPageSize.Width() - rPage.GetLftBorder() - rPage.GetRgtBorder());
2261 const long nPageHeight (
2262 rInfo.maPageSize.Height() - rPage.GetUppBorder() - rPage.GetLwrBorder());
2264 Point aOrigin ( 0, 0 );
2266 for (Point aPageOrigin = aOrigin;
2267 -aPageOrigin.Y()<nPageHeight;
2268 aPageOrigin.Y() -= rInfo.maPrintSize.Height())
2270 for (aPageOrigin.X()=aOrigin.X();
2271 -aPageOrigin.X()<nPageWidth;
2272 aPageOrigin.X() -= rInfo.maPrintSize.Width())
2274 aMap.SetOrigin(aPageOrigin);
2275 maPrinterPages.push_back(
2276 ::boost::shared_ptr<PrinterPage>(
2277 new RegularPrinterPage(
2278 sal::static_int_cast<sal_uInt16>(nPageIndex),
2279 ePageKind,
2280 aMap,
2281 rInfo.mbPrintMarkedOnly,
2282 rInfo.msPageString,
2283 aPageOffset,
2284 rInfo.mnDrawMode,
2285 rInfo.meOrientation,
2286 nPaperBin)));
2296 //===== DocumentRenderer ======================================================
2298 DocumentRenderer::DocumentRenderer (ViewShellBase& rBase)
2299 : DocumentRendererInterfaceBase(m_aMutex),
2300 mpImpl(new Implementation(rBase))
2307 DocumentRenderer::~DocumentRenderer()
2314 //----- XRenderable -----------------------------------------------------------
2316 sal_Int32 SAL_CALL DocumentRenderer::getRendererCount (
2317 const css::uno::Any& aSelection,
2318 const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
2319 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2321 (void)aSelection;
2322 mpImpl->ProcessProperties(rOptions);
2323 return mpImpl->GetPrintPageCount();
2329 Sequence<beans::PropertyValue> SAL_CALL DocumentRenderer::getRenderer (
2330 sal_Int32 nRenderer,
2331 const css::uno::Any& rSelection,
2332 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2333 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2335 (void)nRenderer;
2336 (void)rSelection;
2337 mpImpl->ProcessProperties(rOptions);
2338 return mpImpl->GetProperties(rOptions);
2344 void SAL_CALL DocumentRenderer::render (
2345 sal_Int32 nRenderer,
2346 const css::uno::Any& rSelection,
2347 const css::uno::Sequence<css::beans::PropertyValue>& rOptions)
2348 throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
2350 (void)rSelection;
2351 mpImpl->ProcessProperties(rOptions);
2352 mpImpl->PrintPage(nRenderer);
2357 } // end of namespace sd
2359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */