android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / doc / DocumentDeviceManager.cxx
blobb90474082c92d61d65a4003b78688268ea1c8476
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <DocumentDeviceManager.hxx>
22 #include <memory>
23 #include <utility>
25 #include <doc.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>
39 #include <cmdid.h>
40 #include <drawdoc.hxx>
41 #include <wdocsh.hxx>
42 #include <prtopt.hxx>
43 #include <viewsh.hxx>
44 #include <rootfrm.hxx>
45 #include <viewopt.hxx>
46 #include <swwait.hxx>
47 #include <fntcache.hxx>
49 class SwDocShell;
50 class SwWait;
52 namespace sw {
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 )
60 pRet = mpPrt;
61 else
62 pRet = &CreatePrinter_();
64 return pRet;
67 void DocumentDeviceManager::setPrinter(/*[in]*/ SfxPrinter *pP,/*[in]*/ bool bDeleteOld,/*[in]*/ bool bCallPrtDataChanged )
69 assert ( !pP || !pP->isDisposed() );
70 if ( pP != mpPrt )
72 if ( bDeleteOld )
73 mpPrt.disposeAndClear();
74 mpPrt = pP;
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#
78 if ( mpPrt )
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) )
93 PrtDataChanged();
96 VirtualDevice* DocumentDeviceManager::getVirtualDevice(/*[in]*/ bool bCreate ) const
98 VirtualDevice* pRet = nullptr;
99 if ( !bCreate || mpVirDev )
100 pRet = mpVirDev;
101 else
102 pRet = &CreateVirtualDevice_();
104 assert ( !pRet || !pRet->isDisposed() );
106 return pRet;
109 void DocumentDeviceManager::setVirtualDevice(/*[in]*/ VirtualDevice* pVd )
111 assert ( !pVd->isDisposed() );
113 if ( mpVirDev.get() != pVd )
115 mpVirDev.disposeAndClear();
116 mpVirDev = pVd;
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 );
135 else
137 pRet = getVirtualDevice( bCreate );
140 assert ( !pRet || !pRet->isDisposed() );
142 return pRet;
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 )
149 return;
151 if ( bNewVirtual )
153 VirtualDevice* pMyVirDev = getVirtualDevice( true );
154 if ( !bNewHiRes )
155 pMyVirDev->SetReferenceDevice( VirtualDevice::RefDevMode::Dpi600 );
156 else
157 pMyVirDev->SetReferenceDevice( VirtualDevice::RefDevMode::MSO1 );
159 if( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
160 m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pMyVirDev );
162 else
164 // #i41075#
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 );
177 PrtDataChanged();
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;
191 if ( mpPrt )
193 if ( mpPrt->GetName() == rJobSetup.GetPrinterName() )
195 if ( mpPrt->GetJobSetup() != rJobSetup )
197 mpPrt->SetJobSetup( rJobSetup );
198 bDataChanged = true;
201 else
202 mpPrt.disposeAndClear();
205 if( !mpPrt )
207 //The ItemSet is deleted by Sfx!
208 auto pSet = std::make_unique<SfxItemSetFixed<
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 );
216 else
218 mpPrt = p;
219 bDataChanged = true;
222 if ( bDataChanged && !m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE) )
223 PrtDataChanged();
226 const SwPrintData & DocumentDeviceManager::getPrintData() const
228 if(!mpPrtData)
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 SwPrintOptions aPrintOptions( bWeb );
240 *pThis->mpPrtData = aPrintOptions;
242 assert(mpPrtData && "this will always be set by now");
243 return *mpPrtData;
246 void DocumentDeviceManager::setPrintData(/*[in]*/ const SwPrintData& rPrtData )
248 if(!mpPrtData)
249 mpPrtData.reset(new SwPrintData);
250 *mpPrtData = rPrtData;
253 DocumentDeviceManager::~DocumentDeviceManager()
255 mpPrtData.reset();
256 mpVirDev.disposeAndClear();
257 mpPrt.disposeAndClear();
260 VirtualDevice& DocumentDeviceManager::CreateVirtualDevice_() const
262 #ifdef IOS
263 VclPtr<VirtualDevice> pNewVir = VclPtr<VirtualDevice>::Create(DeviceFormat::GRAYSCALE);
264 #else
265 VclPtr<VirtualDevice> pNewVir = VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA);
266 #endif
268 pNewVir->SetReferenceDevice( VirtualDevice::RefDevMode::MSO1 );
270 // #i60945# External leading compatibility for unix systems.
271 if ( m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING ) )
272 pNewVir->Compat_ZeroExtleadBug();
274 MapMode aMapMode( pNewVir->GetMapMode() );
275 aMapMode.SetMapUnit( MapUnit::MapTwip );
276 pNewVir->SetMapMode( aMapMode );
278 const_cast<DocumentDeviceManager*>(this)->setVirtualDevice( pNewVir );
279 return *mpVirDev;
282 SfxPrinter& DocumentDeviceManager::CreatePrinter_() const
284 OSL_ENSURE( ! mpPrt, "Do not call CreatePrinter_(), call getPrinter() instead" );
286 // We create a default SfxPrinter.
287 // The ItemSet is deleted by Sfx!
288 auto pSet = std::make_unique<SfxItemSetFixed<
289 SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
290 SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
291 SID_HTML_MODE, SID_HTML_MODE,
292 FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER>>(m_rDoc.GetAttrPool());
294 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( std::move(pSet) );
296 // assign PrintData to newly created printer
297 const SwPrintData& rPrtData = getPrintData();
298 SwAddPrinterItem aAddPrinterItem(rPrtData);
299 SfxItemSet aOptions(pNewPrt->GetOptions());
300 aOptions.Put(aAddPrinterItem);
301 pNewPrt->SetOptions(aOptions);
303 const_cast<DocumentDeviceManager*>(this)->setPrinter( pNewPrt, true, true );
304 return *mpPrt;
307 void DocumentDeviceManager::PrtDataChanged()
309 // If you change this, also modify InJobSetup in Sw3io if appropriate.
311 // #i41075#
312 OSL_ENSURE( m_rDoc.getIDocumentSettingAccess().get(DocumentSettingId::USE_VIRTUAL_DEVICE) ||
313 nullptr != getPrinter( false ), "PrtDataChanged will be called recursively!" );
314 SwRootFrame* pTmpRoot = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
315 std::optional<SwWait> oWait;
316 bool bEndAction = false;
318 if( m_rDoc.GetDocShell() )
319 m_rDoc.GetDocShell()->UpdateFontList();
321 bool bDraw = true;
322 if ( pTmpRoot )
324 SwViewShell *pSh = m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
325 if( pSh &&
326 (!pSh->GetViewOptions()->getBrowseMode() ||
327 pSh->GetViewOptions()->IsPrtFormat()) )
329 if ( m_rDoc.GetDocShell() )
330 oWait.emplace( *m_rDoc.GetDocShell(), true );
332 pTmpRoot->StartAllAction();
333 bEndAction = true;
335 bDraw = false;
336 if( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
338 m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING) );
339 m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( getReferenceDevice( false ) );
342 pFntCache->Flush();
344 for(SwRootFrame* aLayout : m_rDoc.GetAllLayouts())
345 aLayout->InvalidateAllContent(SwInvalidateFlags::Size);
347 for(SwViewShell& rShell : pSh->GetRingContainer())
348 rShell.InitPrt(getPrinter(false));
351 if ( bDraw && m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
353 const bool bTmpAddExtLeading = m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING);
354 if ( bTmpAddExtLeading != m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->IsAddExtLeading() )
355 m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( bTmpAddExtLeading );
357 OutputDevice* pOutDev = getReferenceDevice( false );
358 if ( pOutDev != m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetRefDevice() )
359 m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pOutDev );
362 m_rDoc.PrtOLENotify( true );
364 if ( bEndAction )
365 pTmpRoot->EndAllAction();
370 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */