1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <DocumentDeviceManager.hxx>
26 #include <DocumentSettingManager.hxx>
27 #include <IDocumentDrawModelAccess.hxx>
28 #include <IDocumentState.hxx>
29 #include <IDocumentLayoutAccess.hxx>
30 #include <osl/diagnose.h>
31 #include <sfx2/printer.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/outdev.hxx>
34 #include <vcl/jobset.hxx>
35 #include <printdata.hxx>
36 #include <vcl/mapmod.hxx>
37 #include <svl/itemset.hxx>
38 #include <cfgitems.hxx>
40 #include <drawdoc.hxx>
44 #include <rootfrm.hxx>
45 #include <viewopt.hxx>
47 #include <fntcache.hxx>
54 DocumentDeviceManager::DocumentDeviceManager( SwDoc
& i_rSwdoc
) : m_rDoc( i_rSwdoc
), mpPrt(nullptr), mpVirDev(nullptr) {}
56 SfxPrinter
* DocumentDeviceManager::getPrinter(/*[in]*/ bool bCreate
) const
58 SfxPrinter
* pRet
= nullptr;
59 if ( !bCreate
|| mpPrt
)
62 pRet
= &CreatePrinter_();
67 void DocumentDeviceManager::setPrinter(/*[in]*/ SfxPrinter
*pP
,/*[in]*/ bool bDeleteOld
,/*[in]*/ bool bCallPrtDataChanged
)
69 assert ( !pP
|| !pP
->isDisposed() );
73 mpPrt
.disposeAndClear();
76 // our printer should always use TWIP. Don't rely on this being set in SwViewShell::InitPrt, there
77 // are situations where this isn't called. #i108712#
80 MapMode
aMapMode( mpPrt
->GetMapMode() );
81 aMapMode
.SetMapUnit( MapUnit::MapTwip
);
82 mpPrt
->SetMapMode( aMapMode
);
85 if ( m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() && !m_rDoc
.GetDocumentSettingManager().get( DocumentSettingId::USE_VIRTUAL_DEVICE
) )
86 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( mpPrt
);
89 if ( bCallPrtDataChanged
&&
90 // #i41075# Do not call PrtDataChanged() if we do not
91 // use the printer for formatting:
92 !m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE
) )
96 VirtualDevice
* DocumentDeviceManager::getVirtualDevice(/*[in]*/ bool bCreate
) const
98 VirtualDevice
* pRet
= nullptr;
99 if ( !bCreate
|| mpVirDev
)
102 pRet
= &CreateVirtualDevice_();
104 assert ( !pRet
|| !pRet
->isDisposed() );
109 void DocumentDeviceManager::setVirtualDevice(/*[in]*/ VirtualDevice
* pVd
)
111 assert ( !pVd
->isDisposed() );
113 if ( mpVirDev
.get() != pVd
)
115 mpVirDev
.disposeAndClear();
118 if ( m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() && m_rDoc
.GetDocumentSettingManager().get( DocumentSettingId::USE_VIRTUAL_DEVICE
) )
119 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( mpVirDev
);
123 OutputDevice
* DocumentDeviceManager::getReferenceDevice(/*[in]*/ bool bCreate
) const
125 OutputDevice
* pRet
= nullptr;
126 if ( !m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE
) )
128 pRet
= getPrinter( bCreate
);
130 if ( bCreate
&& !mpPrt
->IsValid() )
132 pRet
= getVirtualDevice( true );
137 pRet
= getVirtualDevice( bCreate
);
140 assert ( !pRet
|| !pRet
->isDisposed() );
145 void DocumentDeviceManager::setReferenceDeviceType(/*[in]*/ bool bNewVirtual
, /*[in]*/ bool bNewHiRes
)
147 if ( m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE
) == bNewVirtual
&&
148 m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::USE_HIRES_VIRTUAL_DEVICE
) == bNewHiRes
)
153 VirtualDevice
* pMyVirDev
= getVirtualDevice( true );
155 pMyVirDev
->SetReferenceDevice( VirtualDevice::RefDevMode::Dpi600
);
157 pMyVirDev
->SetReferenceDevice( VirtualDevice::RefDevMode::MSO1
);
159 if( m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() )
160 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pMyVirDev
);
165 // We have to take care that a printer exists before calling
166 // PrtDataChanged() in order to prevent that PrtDataChanged()
167 // triggers this funny situation:
168 // getReferenceDevice()->getPrinter()->CreatePrinter_()
169 // ->setPrinter()-> PrtDataChanged()
170 SfxPrinter
* pPrinter
= getPrinter( true );
171 if( m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() )
172 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pPrinter
);
175 m_rDoc
.GetDocumentSettingManager().set(DocumentSettingId::USE_VIRTUAL_DEVICE
, bNewVirtual
);
176 m_rDoc
.GetDocumentSettingManager().set(DocumentSettingId::USE_HIRES_VIRTUAL_DEVICE
, bNewHiRes
);
178 m_rDoc
.getIDocumentState().SetModified();
181 const JobSetup
* DocumentDeviceManager::getJobsetup() const
183 return mpPrt
? &mpPrt
->GetJobSetup() : nullptr;
186 void DocumentDeviceManager::setJobsetup(/*[in]*/ const JobSetup
&rJobSetup
)
188 bool bCheckPageDescs
= !mpPrt
;
189 bool bDataChanged
= false;
193 if ( mpPrt
->GetName() == rJobSetup
.GetPrinterName() )
195 if ( mpPrt
->GetJobSetup() != rJobSetup
)
197 mpPrt
->SetJobSetup( rJobSetup
);
202 mpPrt
.disposeAndClear();
207 //The ItemSet is deleted by Sfx!
208 auto pSet
= std::make_unique
<SfxItemSet
>(SfxItemSet::makeFixedSfxItemSet
<
209 SID_PRINTER_NOTFOUND_WARN
, SID_PRINTER_NOTFOUND_WARN
,
210 SID_PRINTER_CHANGESTODOC
, SID_PRINTER_CHANGESTODOC
,
211 SID_HTML_MODE
, SID_HTML_MODE
,
212 FN_PARAM_ADDPRINTER
, FN_PARAM_ADDPRINTER
>(m_rDoc
.GetAttrPool()));
213 VclPtr
<SfxPrinter
> p
= VclPtr
<SfxPrinter
>::Create( std::move(pSet
), rJobSetup
);
214 if ( bCheckPageDescs
)
215 setPrinter( p
, true, true );
218 mpPrt
= std::move(p
);
222 if ( bDataChanged
&& !m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE
) )
226 const SwPrintData
& DocumentDeviceManager::getPrintData() const
230 DocumentDeviceManager
* pThis
= const_cast< DocumentDeviceManager
* >(this);
231 pThis
->mpPrtData
.reset(new SwPrintData
);
233 // SwPrintData should be initialized from the configuration,
234 // the respective config item is implemented by SwPrintOptions which
235 // is also derived from SwPrintData
236 const SwDocShell
*pDocSh
= m_rDoc
.GetDocShell();
237 OSL_ENSURE( pDocSh
, "pDocSh is 0, can't determine if this is a WebDoc or not" );
238 bool bWeb
= dynamic_cast< const SwWebDocShell
* >(pDocSh
) != nullptr;
239 *pThis
->mpPrtData
= SwPrintOptions(bWeb
);
241 assert(mpPrtData
&& "this will always be set by now");
245 void DocumentDeviceManager::setPrintData(/*[in]*/ const SwPrintData
& rPrtData
)
248 mpPrtData
.reset(new SwPrintData
);
249 *mpPrtData
= rPrtData
;
252 DocumentDeviceManager::~DocumentDeviceManager()
255 mpVirDev
.disposeAndClear();
256 mpPrt
.disposeAndClear();
259 VirtualDevice
& DocumentDeviceManager::CreateVirtualDevice_() const
262 VclPtr
<VirtualDevice
> pNewVir
= VclPtr
<VirtualDevice
>::Create(DeviceFormat::GRAYSCALE
);
264 VclPtr
<VirtualDevice
> pNewVir
= VclPtr
<VirtualDevice
>::Create(DeviceFormat::WITHOUT_ALPHA
);
267 pNewVir
->SetReferenceDevice( VirtualDevice::RefDevMode::MSO1
);
269 // #i60945# External leading compatibility for unix systems.
270 if ( m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING
) )
271 pNewVir
->Compat_ZeroExtleadBug();
273 MapMode
aMapMode( pNewVir
->GetMapMode() );
274 aMapMode
.SetMapUnit( MapUnit::MapTwip
);
275 pNewVir
->SetMapMode( aMapMode
);
277 const_cast<DocumentDeviceManager
*>(this)->setVirtualDevice( pNewVir
);
281 SfxPrinter
& DocumentDeviceManager::CreatePrinter_() const
283 OSL_ENSURE( ! mpPrt
, "Do not call CreatePrinter_(), call getPrinter() instead" );
285 // We create a default SfxPrinter.
286 // The ItemSet is deleted by Sfx!
287 auto pSet
= std::make_unique
<SfxItemSet
>(SfxItemSet::makeFixedSfxItemSet
<
288 SID_PRINTER_NOTFOUND_WARN
, SID_PRINTER_NOTFOUND_WARN
,
289 SID_PRINTER_CHANGESTODOC
, SID_PRINTER_CHANGESTODOC
,
290 SID_HTML_MODE
, SID_HTML_MODE
,
291 FN_PARAM_ADDPRINTER
, FN_PARAM_ADDPRINTER
>(m_rDoc
.GetAttrPool()));
292 VclPtr
<SfxPrinter
> pNewPrt
= VclPtr
<SfxPrinter
>::Create( std::move(pSet
) );
294 // assign PrintData to newly created printer
295 const SwPrintData
& rPrtData
= getPrintData();
296 SwAddPrinterItem
aAddPrinterItem(rPrtData
);
297 SfxItemSet
aOptions(pNewPrt
->GetOptions());
298 aOptions
.Put(aAddPrinterItem
);
299 pNewPrt
->SetOptions(aOptions
);
301 const_cast<DocumentDeviceManager
*>(this)->setPrinter( pNewPrt
, true, true );
305 void DocumentDeviceManager::PrtDataChanged()
307 // If you change this, also modify InJobSetup in Sw3io if appropriate.
310 OSL_ENSURE( m_rDoc
.getIDocumentSettingAccess().get(DocumentSettingId::USE_VIRTUAL_DEVICE
) ||
311 nullptr != getPrinter( false ), "PrtDataChanged will be called recursively!" );
312 SwRootFrame
* pTmpRoot
= m_rDoc
.getIDocumentLayoutAccess().GetCurrentLayout();
313 std::optional
<SwWait
> oWait
;
314 bool bEndAction
= false;
316 if( m_rDoc
.GetDocShell() )
317 m_rDoc
.GetDocShell()->UpdateFontList();
322 SwViewShell
*pSh
= m_rDoc
.getIDocumentLayoutAccess().GetCurrentViewShell();
324 (!pSh
->GetViewOptions()->getBrowseMode() ||
325 pSh
->GetViewOptions()->IsPrtFormat()) )
327 if ( m_rDoc
.GetDocShell() )
328 oWait
.emplace( *m_rDoc
.GetDocShell(), true );
330 pTmpRoot
->StartAllAction();
334 if( m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() )
336 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING
) );
337 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( getReferenceDevice( false ) );
342 for(SwRootFrame
* aLayout
: m_rDoc
.GetAllLayouts())
343 aLayout
->InvalidateAllContent(SwInvalidateFlags::Size
);
345 for(SwViewShell
& rShell
: pSh
->GetRingContainer())
346 rShell
.InitPrt(getPrinter(false));
349 if ( bDraw
&& m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel() )
351 const bool bTmpAddExtLeading
= m_rDoc
.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING
);
352 if ( bTmpAddExtLeading
!= m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->IsAddExtLeading() )
353 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( bTmpAddExtLeading
);
355 OutputDevice
* pOutDev
= getReferenceDevice( false );
356 if ( pOutDev
!= m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->GetRefDevice() )
357 m_rDoc
.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pOutDev
);
360 m_rDoc
.PrtOLENotify( true );
363 pTmpRoot
->EndAllAction();
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */