xref: /core/sw/source/core/view/printdata.cxx (revision 12e48f91)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <printdata.hxx>
21 
22 #include <strings.hrc>
23 #include <doc.hxx>
24 #include <IDocumentDeviceAccess.hxx>
25 #include <unotxdoc.hxx>
26 #include <wdocsh.hxx>
27 #include <viewsh.hxx>
28 #include <docfld.hxx>
29 
30 #include <svl/cjkoptions.hxx>
31 #include <svl/ctloptions.hxx>
32 #include <toolkit/awt/vclxdevice.hxx>
33 #include <comphelper/configuration.hxx>
34 #include <unotools/moduleoptions.hxx>
35 #include <vcl/outdev.hxx>
36 #include <osl/diagnose.h>
37 
38 using namespace ::com::sun::star;
39 
SwRenderData()40 SwRenderData::SwRenderData()
41 {
42 }
43 
~SwRenderData()44 SwRenderData::~SwRenderData()
45 {
46     OSL_ENSURE( !m_pPostItShell, "m_pPostItShell should already have been deleted" );
47     OSL_ENSURE( !m_pPostItFields, " should already have been deleted" );
48 }
49 
CreatePostItData(SwDoc & rDoc,const SwViewOption * pViewOpt,OutputDevice * pOutDev)50 void SwRenderData::CreatePostItData( SwDoc& rDoc, const SwViewOption *pViewOpt, OutputDevice *pOutDev )
51 {
52     DeletePostItData();
53     m_pPostItFields.reset(new SetGetExpFields);
54     sw_GetPostIts( rDoc.getIDocumentFieldsAccess(), m_pPostItFields.get() );
55 
56     //!! Disable spell and grammar checking in the temporary document.
57     //!! Otherwise the grammar checker might process it and crash if we later on
58     //!! simply delete this document while he is still at it.
59     SwViewOption  aViewOpt( *pViewOpt );
60     aViewOpt.SetOnlineSpell( false );
61 
62     m_pPostItShell.reset(new SwViewShell(*new SwDoc, nullptr, &aViewOpt, pOutDev));
63 }
64 
DeletePostItData()65 void SwRenderData::DeletePostItData()
66 {
67     if (HasPostItData())
68     {
69         // printer needs to remain at the real document
70         m_pPostItShell->GetDoc()->getIDocumentDeviceAccess().setPrinter( nullptr, false, false );
71         {   // avoid destroying layout from SwDoc dtor
72             rtl::Reference<SwDoc> const xKeepAlive(m_pPostItShell->GetDoc());
73             m_pPostItShell.reset();
74         }
75         m_pPostItFields.reset();
76     }
77 }
78 
SetTempDocShell(SfxObjectShellLock const & xShell)79 void SwRenderData::SetTempDocShell(SfxObjectShellLock const& xShell)
80 {
81     m_xTempDocShell = xShell;
82 }
83 
NeedNewViewOptionAdjust(const SwViewShell & rCompare) const84 bool SwRenderData::NeedNewViewOptionAdjust( const SwViewShell& rCompare ) const
85 {
86     return !(m_pViewOptionAdjust && m_pViewOptionAdjust->checkShell( rCompare ));
87 }
88 
ViewOptionAdjustStart(SwViewShell & rSh,const SwViewOption & rViewOptions)89 void SwRenderData::ViewOptionAdjustStart(
90         SwViewShell &rSh, const SwViewOption &rViewOptions)
91 {
92     if (m_pViewOptionAdjust)
93     {
94         OSL_FAIL("error: there should be no ViewOptionAdjust active when calling this function" );
95     }
96     m_pViewOptionAdjust.reset(
97             new SwViewOptionAdjust_Impl( rSh, rViewOptions ));
98 }
99 
ViewOptionAdjust(SwPrintData const * const pPrtOptions,bool setShowPlaceHoldersInPDF)100 void SwRenderData::ViewOptionAdjust(SwPrintData const*const pPrtOptions, bool setShowPlaceHoldersInPDF)
101 {
102     m_pViewOptionAdjust->AdjustViewOptions( pPrtOptions, setShowPlaceHoldersInPDF );
103 }
104 
ViewOptionAdjustStop()105 void SwRenderData::ViewOptionAdjustStop()
106 {
107     m_pViewOptionAdjust.reset();
108 }
109 
ViewOptionAdjustCrashPreventionKludge()110 void SwRenderData::ViewOptionAdjustCrashPreventionKludge()
111 {
112     m_pViewOptionAdjust->DontTouchThatViewShellItSmellsFunny();
113 }
114 
MakeSwPrtOptions(SwDocShell const * const pDocShell,SwPrintUIOptions const * const pOpt,bool const bIsPDFExport)115 void SwRenderData::MakeSwPrtOptions(
116     SwDocShell const*const pDocShell,
117     SwPrintUIOptions const*const pOpt,
118     bool const bIsPDFExport)
119 {
120     if (!pDocShell || !pOpt)
121         return;
122 
123     m_pPrtOptions.reset(new SwPrintData);
124     SwPrintData & rOptions(*m_pPrtOptions);
125 
126     // get default print options
127     bool bWeb = dynamic_cast<const SwWebDocShell*>( pDocShell) !=  nullptr;
128     ::sw::InitPrintOptionsFromApplication(rOptions, bWeb);
129 
130     // get print options to use from provided properties
131     rOptions.m_bPrintGraphic          = pOpt->IsPrintGraphics();
132     rOptions.m_bPrintControl          = pOpt->IsPrintFormControls();
133     rOptions.m_bPrintLeftPages        = pOpt->IsPrintLeftPages();
134     rOptions.m_bPrintRightPages       = pOpt->IsPrintRightPages();
135     rOptions.m_bPrintPageBackground   = pOpt->IsPrintPageBackground();
136     rOptions.m_bPrintEmptyPages       = pOpt->IsPrintEmptyPages( bIsPDFExport );
137     // bUpdateFieldsInPrinting  <-- not set here; mail merge only
138     rOptions.m_bPaperFromSetup        = pOpt->IsPaperFromSetup();
139     rOptions.m_bPrintProspect         = pOpt->IsPrintProspect();
140     rOptions.m_bPrintProspectRTL      = pOpt->IsPrintProspectRTL();
141     // bModified                <-- not set here; mail merge only
142     rOptions.m_bPrintBlackFont        = pOpt->IsPrintWithBlackTextColor();
143     rOptions.m_bPrintHiddenText       = pOpt->IsPrintHiddenText();
144     rOptions.m_bPrintTextPlaceholder  = pOpt->IsPrintTextPlaceholders();
145     rOptions.m_nPrintPostIts          = pOpt->GetPrintPostItsType();
146 
147     //! needs to be set after MakeOptions since the assignment operation in that
148     //! function will destroy the pointers
149     rOptions.SetRenderData( this );
150 }
151 
SwPrintUIOptions(sal_uInt16 nCurrentPage,bool bWeb,bool bSwSrcView,bool bHasSelection,bool bHasPostIts,const SwPrintData & rDefaultPrintData)152 SwPrintUIOptions::SwPrintUIOptions(
153     sal_uInt16 nCurrentPage,
154     bool bWeb,
155     bool bSwSrcView,
156     bool bHasSelection,
157     bool bHasPostIts,
158     const SwPrintData &rDefaultPrintData ) :
159     m_rDefaultPrintData( rDefaultPrintData )
160 {
161     // printing HTML sources does not have any valid UI options.
162     // It's just the source code that gets printed...
163     if (bSwSrcView || comphelper::IsFuzzing())
164     {
165         m_aUIProperties.clear();
166         return;
167     }
168 
169     // check if either CJK or CTL is enabled
170     bool bRTL = SvtCJKOptions::IsCJKFontEnabled() || SvtCTLOptions::IsCTLFontEnabled();
171 
172     // create sequence of print UI options
173     // (5 options are not available for Writer-Web)
174     const int nRTLOpts = bRTL ? 1 : 0;
175     const int nNumProps = nRTLOpts + (bWeb ? 15 : 19);
176     m_aUIProperties.resize( nNumProps);
177     int nIdx = 0;
178 
179     // load the writer PrinterOptions into the custom tab
180     m_aUIProperties[nIdx].Name = "OptionsUIFile";
181     m_aUIProperties[nIdx++].Value <<= u"modules/swriter/ui/printeroptions.ui"_ustr;
182 
183     // create "writer" section (new tab page in dialog)
184     SvtModuleOptions aModOpt;
185     OUString aAppGroupname( SwResId( STR_PRINTOPTUI_PRODUCTNAME) );
186     aAppGroupname = aAppGroupname.replaceFirst( "%s", aModOpt.GetModuleName( SvtModuleOptions::EModule::WRITER ) );
187     m_aUIProperties[ nIdx++ ].Value = setGroupControlOpt(u"tabcontrol-page2"_ustr, aAppGroupname, u".HelpID:vcl:PrintDialog:TabPage:AppPage"_ustr);
188 
189     // create sub section for Contents
190     m_aUIProperties[ nIdx++ ].Value = setSubgroupControlOpt(u"contents"_ustr, SwResId( STR_PRINTOPTUI_CONTENTS), OUString());
191 
192     // create a bool option for background
193     bool bDefaultVal = rDefaultPrintData.IsPrintPageBackground();
194     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"pagebackground"_ustr, SwResId( STR_PRINTOPTUI_PAGE_BACKGROUND),
195                                                         u".HelpID:vcl:PrintDialog:PrintPageBackground:CheckBox"_ustr,
196                                                         u"PrintPageBackground"_ustr,
197                                                         bDefaultVal);
198 
199     // create a bool option for pictures/graphics AND OLE and drawing objects as well
200     bDefaultVal = rDefaultPrintData.IsPrintGraphic();
201     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"pictures"_ustr, SwResId( STR_PRINTOPTUI_PICTURES),
202                                                         u".HelpID:vcl:PrintDialog:PrintPicturesAndObjects:CheckBox"_ustr,
203                                                         u"PrintPicturesAndObjects"_ustr,
204                                                          bDefaultVal);
205     if (!bWeb)
206     {
207         // create a bool option for hidden text
208         bDefaultVal = rDefaultPrintData.IsPrintHiddenText();
209         m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"hiddentext"_ustr, SwResId( STR_PRINTOPTUI_HIDDEN),
210                                                             u".HelpID:vcl:PrintDialog:PrintHiddenText:CheckBox"_ustr,
211                                                             u"PrintHiddenText"_ustr,
212                                                             bDefaultVal);
213 
214         // create a bool option for place holder
215         bDefaultVal = rDefaultPrintData.IsPrintTextPlaceholder();
216         m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"placeholders"_ustr, SwResId( STR_PRINTOPTUI_TEXT_PLACEHOLDERS),
217                                                             u".HelpID:vcl:PrintDialog:PrintTextPlaceholder:CheckBox"_ustr,
218                                                             u"PrintTextPlaceholder"_ustr,
219                                                             bDefaultVal);
220     }
221 
222     // create a bool option for controls
223     bDefaultVal = rDefaultPrintData.IsPrintControl();
224     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"formcontrols"_ustr, SwResId( STR_PRINTOPTUI_FORM_CONTROLS),
225                                                         u".HelpID:vcl:PrintDialog:PrintControls:CheckBox"_ustr,
226                                                         u"PrintControls"_ustr,
227                                                         bDefaultVal);
228 
229     // create sub section for Color
230     m_aUIProperties[ nIdx++ ].Value = setSubgroupControlOpt(u"color"_ustr, SwResId( STR_PRINTOPTUI_COLOR), OUString());
231 
232     // create a bool option for printing text with black font color
233     bDefaultVal = rDefaultPrintData.IsPrintBlackFont();
234     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"textinblack"_ustr, SwResId( STR_PRINTOPTUI_PRINT_BLACK),
235                                                         u".HelpID:vcl:PrintDialog:PrintBlackFonts:CheckBox"_ustr,
236                                                         u"PrintBlackFonts"_ustr,
237                                                         bDefaultVal);
238 
239     if (!bWeb)
240     {
241         // create subgroup for misc options
242         m_aUIProperties[ nIdx++ ].Value = setSubgroupControlOpt(u"pages"_ustr, SwResId( STR_PRINTOPTUI_PAGES_TEXT), OUString());
243 
244         // create a bool option for printing automatically inserted blank pages
245         bDefaultVal = rDefaultPrintData.IsPrintEmptyPages();
246         m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"autoblankpages"_ustr, SwResId( STR_PRINTOPTUI_PRINT_BLANK),
247                                                             u".HelpID:vcl:PrintDialog:PrintEmptyPages:CheckBox"_ustr,
248                                                             u"PrintEmptyPages"_ustr,
249                                                             bDefaultVal);
250     }
251 
252     // create a bool option for paper tray
253     bDefaultVal = rDefaultPrintData.IsPaperFromSetup();
254     vcl::PrinterOptionsHelper::UIControlOptions aPaperTrayOpt;
255     aPaperTrayOpt.maGroupHint = "OptionsPageOptGroup";
256     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"printpaperfromsetup"_ustr, SwResId( STR_PRINTOPTUI_ONLY_PAPER),
257                                                         u".HelpID:vcl:PrintDialog:PrintPaperFromSetup:CheckBox"_ustr,
258                                                         u"PrintPaperFromSetup"_ustr,
259                                                         bDefaultVal,
260                                                         aPaperTrayOpt);
261 
262     // print range selection
263     vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
264     aPrintRangeOpt.maGroupHint = "PrintRange";
265     aPrintRangeOpt.mbInternalOnly = true;
266     m_aUIProperties[nIdx++].Value = setSubgroupControlOpt( u"printrange"_ustr,
267                                                           SwResId( STR_PRINTOPTUI_PAGES_TEXT ),
268                                                           OUString(),
269                                                           aPrintRangeOpt );
270 
271     // create a choice for the content to create
272     static constexpr OUString aPrintRangeName( u"PrintContent"_ustr );
273     uno::Sequence< OUString > aChoices{ SwResId( STR_PRINTOPTUI_PRINTALLPAGES ),
274                                         SwResId( STR_PRINTOPTUI_PRINTPAGES ),
275                                         SwResId( STR_PRINTOPTUI_PRINTSELECTION ) };
276     uno::Sequence< sal_Bool > aChoicesDisabled{ false, false, !bHasSelection };
277     uno::Sequence< OUString > aHelpIds{ u".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0"_ustr,
278                                         u".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1"_ustr,
279                                         u".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2"_ustr };
280     uno::Sequence< OUString > aWidgetIds{ u"rbAllPages"_ustr, u"rbRangePages"_ustr, u"rbRangeSelection"_ustr };
281     m_aUIProperties[nIdx++].Value = setChoiceRadiosControlOpt(aWidgetIds, OUString(),
282                                                         aHelpIds, aPrintRangeName,
283                                                         aChoices, 0 /* always default to 'All pages' */,
284                                                         aChoicesDisabled);
285 
286     // show an Edit dependent on "Pages" selected
287     vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, true );
288     m_aUIProperties[nIdx++].Value = setEditControlOpt(u"pagerange"_ustr, OUString(),
289                                                       u".HelpID:vcl:PrintDialog:PageRange:Edit"_ustr,
290                                                       u"PageRange"_ustr,
291                                                       OUString::number( nCurrentPage ) /* set text box to current page number */,
292                                                       aPageRangeOpt);
293 
294     vcl::PrinterOptionsHelper::UIControlOptions aEvenOddOpt(aPrintRangeName, -1, true);
295     m_aUIProperties[ nIdx++ ].Value = setChoiceListControlOpt(u"evenoddbox"_ustr,
296                                                            OUString(),
297                                                            uno::Sequence<OUString>(),
298                                                            u"EvenOdd"_ustr,
299                                                            uno::Sequence<OUString>(),
300                                                            0,
301                                                            uno::Sequence< sal_Bool >(),
302                                                            aEvenOddOpt);
303 
304     // create a list box for notes content
305     const SwPostItMode nPrintPostIts = rDefaultPrintData.GetPrintPostIts();
306     aChoices = { SwResId( STR_PRINTOPTUI_NONE),
307                  SwResId( STR_PRINTOPTUI_COMMENTS_ONLY),
308                  SwResId( STR_PRINTOPTUI_PLACE_END),
309                  SwResId( STR_PRINTOPTUI_PLACE_PAGE),
310                  SwResId( STR_PRINTOPTUI_PLACE_MARGINS) };
311     aHelpIds = { u".HelpID:vcl:PrintDialog:PrintAnnotationMode:FixedText"_ustr,
312                  u".HelpID:vcl:PrintDialog:PrintAnnotationMode:ListBox"_ustr };
313     vcl::PrinterOptionsHelper::UIControlOptions aAnnotOpt( u"PrintProspect"_ustr, 0, false );
314     aAnnotOpt.mbEnabled = bHasPostIts;
315     m_aUIProperties[ nIdx++ ].Value = setChoiceListControlOpt(u"writercomments"_ustr,
316                                                            SwResId( STR_PRINTOPTUI_COMMENTS),
317                                                            aHelpIds,
318                                                            u"PrintAnnotationMode"_ustr,
319                                                            aChoices,
320                                                            bHasPostIts ? static_cast<sal_uInt16>(nPrintPostIts) : 0,
321                                                            uno::Sequence< sal_Bool >(),
322                                                            aAnnotOpt);
323 
324     // create subsection for Page settings
325     vcl::PrinterOptionsHelper::UIControlOptions aPageSetOpt;
326     aPageSetOpt.maGroupHint = "LayoutPage";
327 
328     // create a bool option for brochure
329     bDefaultVal = rDefaultPrintData.IsPrintProspect();
330     static constexpr OUString aBrochurePropertyName( u"PrintProspect"_ustr );
331     m_aUIProperties[ nIdx++ ].Value = setBoolControlOpt(u"brochure"_ustr, SwResId( STR_PRINTOPTUI_BROCHURE),
332                                                         u".HelpID:vcl:PrintDialog:PrintProspect:CheckBox"_ustr,
333                                                         aBrochurePropertyName,
334                                                         bDefaultVal,
335                                                         aPageSetOpt);
336 
337     if (bRTL)
338     {
339         // create a bool option for brochure RTL dependent on brochure
340         uno::Sequence< OUString > aBRTLChoices{ SwResId( STR_PRINTOPTUI_LEFT_SCRIPT),
341                                                 SwResId( STR_PRINTOPTUI_RIGHT_SCRIPT) };
342         vcl::PrinterOptionsHelper::UIControlOptions aBrochureRTLOpt( aBrochurePropertyName, -1, true );
343         uno::Sequence<OUString> aBRTLHelpIds { u".HelpID:vcl:PrintDialog:PrintProspectRTL:ListBox"_ustr };
344         aBrochureRTLOpt.maGroupHint = "LayoutPage";
345         // RTL brochure choices
346         //      0 : left-to-right
347         //      1 : right-to-left
348         const sal_Int16 nBRTLChoice = rDefaultPrintData.IsPrintProspectRTL() ? 1 : 0;
349         m_aUIProperties[ nIdx++ ].Value = setChoiceListControlOpt(u"scriptdirection"_ustr,
350                                                                OUString(),
351                                                                aBRTLHelpIds,
352                                                                u"PrintProspectRTL"_ustr,
353                                                                aBRTLChoices,
354                                                                nBRTLChoice,
355                                                                uno::Sequence< sal_Bool >(),
356                                                                aBrochureRTLOpt);
357     }
358 
359     assert(nIdx == nNumProps);
360 }
361 
~SwPrintUIOptions()362 SwPrintUIOptions::~SwPrintUIOptions()
363 {
364 }
365 
IsPrintLeftPages() const366 bool SwPrintUIOptions::IsPrintLeftPages() const
367 {
368     // take care of different property names for the option.
369     // for compatibility the old name should win (may still be used for PDF export or via Uno API)
370 
371     // 0: left and right pages
372     // 1: left pages only
373     // 2: right pages only
374     sal_Int64 nEOPages = getIntValue( "EvenOdd", 0 /* default: all */ );
375     bool bRes = nEOPages != 1;
376     bRes = getBoolValue( "EvenOdd", bRes /* <- default value if property is not found */ );
377     return bRes;
378 }
379 
IsPrintRightPages() const380 bool SwPrintUIOptions::IsPrintRightPages() const
381 {
382     // take care of different property names for the option.
383     // for compatibility the old name should win (may still be used for PDF export or via Uno API)
384 
385     sal_Int64 nEOPages = getIntValue( "EvenOdd", 0 /* default: all */ );
386     bool bRes = nEOPages != 2;
387     bRes = getBoolValue( "EvenOdd", bRes /* <- default value if property is not found */ );
388     return bRes;
389 }
390 
IsPrintEmptyPages(bool bIsPDFExport) const391 bool SwPrintUIOptions::IsPrintEmptyPages( bool bIsPDFExport ) const
392 {
393     // take care of different property names for the option.
394 
395     bool bRes = bIsPDFExport ?
396             !getBoolValue( "IsSkipEmptyPages", true ) :
397             getBoolValue( "PrintEmptyPages", true );
398     return bRes;
399 }
400 
IsPrintGraphics() const401 bool SwPrintUIOptions::IsPrintGraphics() const
402 {
403     // take care of different property names for the option.
404     // for compatibility the old name should win (may still be used for PDF export or via Uno API)
405 
406     bool bRes = getBoolValue( "PrintPicturesAndObjects", true );
407     bRes = getBoolValue( "PrintGraphics", bRes );
408     return bRes;
409 }
410 
processPropertiesAndCheckFormat(const uno::Sequence<beans::PropertyValue> & i_rNewProp)411 bool SwPrintUIOptions::processPropertiesAndCheckFormat( const uno::Sequence< beans::PropertyValue >& i_rNewProp )
412 {
413     bool bChanged = processProperties( i_rNewProp );
414 
415     uno::Reference< awt::XDevice >  xRenderDevice;
416     uno::Any aVal( getValue( u"RenderDevice"_ustr ) );
417     aVal >>= xRenderDevice;
418 
419     VclPtr< OutputDevice > pOut;
420     if (xRenderDevice.is())
421     {
422         VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() );
423         if (pDevice)
424             pOut = pDevice->GetOutputDevice();
425     }
426     bChanged = bChanged || (pOut.get() != m_pLast.get());
427     if( pOut )
428         m_pLast = pOut;
429 
430     return bChanged;
431 }
432 
433 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
434