Line data Source code
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 <DocumentDeviceManager.hxx>
21 :
22 : #include <IDocumentDeviceAccess.hxx>
23 : #include <doc.hxx>
24 : #include <DocumentSettingManager.hxx>
25 : #include <IDocumentDrawModelAccess.hxx>
26 : #include <IDocumentState.hxx>
27 : #include <IDocumentLayoutAccess.hxx>
28 : #include <sfx2/printer.hxx>
29 : #include <vcl/virdev.hxx>
30 : #include <vcl/outdev.hxx>
31 : #include <vcl/jobset.hxx>
32 : #include <printdata.hxx>
33 : #include <vcl/mapmod.hxx>
34 : #include <svl/itemset.hxx>
35 : #include <svx/svdmodel.hxx>
36 : #include <cmdid.h>
37 : #include <drawdoc.hxx>
38 : #include <wdocsh.hxx>
39 : #include <prtopt.hxx>
40 : #include <viewsh.hxx>
41 : #include <rootfrm.hxx>
42 : #include <viewopt.hxx>
43 : #include <swwait.hxx>
44 : #include <fntcache.hxx>
45 :
46 :
47 : class SwDocShell;
48 : class SwWait;
49 :
50 :
51 : namespace sw {
52 :
53 2958 : DocumentDeviceManager::DocumentDeviceManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ), mpPrt(0), mpVirDev(0), mpPrtData(0) {}
54 :
55 37631 : SfxPrinter* DocumentDeviceManager::getPrinter(/*[in]*/ bool bCreate ) const
56 : {
57 37631 : SfxPrinter* pRet = 0;
58 37631 : if ( !bCreate || mpPrt )
59 37608 : pRet = mpPrt;
60 : else
61 23 : pRet = &CreatePrinter_();
62 :
63 37631 : return pRet;
64 : }
65 :
66 47 : void DocumentDeviceManager::setPrinter(/*[in]*/ SfxPrinter *pP,/*[in]*/ bool bDeleteOld,/*[in]*/ bool bCallPrtDataChanged )
67 : {
68 : assert ( !pP || !pP->isDisposed() );
69 47 : if ( pP != mpPrt )
70 : {
71 46 : if ( bDeleteOld )
72 46 : mpPrt.disposeAndClear();
73 46 : mpPrt = pP;
74 :
75 : // our printer should always use TWIP. Don't rely on this being set in SwViewShell::InitPrt, there
76 : // are situations where this isn't called.
77 : // #i108712# / 2010-02-26 / frank.schoenheit@sun.com
78 46 : if ( mpPrt )
79 : {
80 46 : MapMode aMapMode( mpPrt->GetMapMode() );
81 46 : aMapMode.SetMapUnit( MAP_TWIP );
82 46 : mpPrt->SetMapMode( aMapMode );
83 : }
84 :
85 46 : if ( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() && !m_rDoc.GetDocumentSettingManager().get( DocumentSettingId::USE_VIRTUAL_DEVICE ) )
86 15 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( mpPrt );
87 : }
88 :
89 94 : if ( bCallPrtDataChanged &&
90 : // #i41075# Do not call PrtDataChanged() if we do not
91 : // use the printer for formatting:
92 47 : !m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE) )
93 15 : PrtDataChanged();
94 47 : }
95 :
96 2053526 : VirtualDevice* DocumentDeviceManager::getVirtualDevice(/*[in]*/ bool bCreate ) const
97 : {
98 2053526 : VirtualDevice* pRet = 0;
99 2053526 : if ( !bCreate || mpVirDev )
100 2050589 : pRet = mpVirDev;
101 : else
102 2937 : pRet = &CreateVirtualDevice_();
103 :
104 : assert ( !pRet || !pRet->isDisposed() );
105 :
106 2053526 : return pRet;
107 : }
108 :
109 2937 : void DocumentDeviceManager::setVirtualDevice(/*[in]*/ VirtualDevice* pVd,/*[in]*/ bool bDeleteOld, /*[in]*/ bool )
110 : {
111 : assert ( !pVd->isDisposed() );
112 :
113 2937 : if ( mpVirDev.get() != pVd )
114 : {
115 2937 : if ( bDeleteOld )
116 2937 : mpVirDev.disposeAndClear();
117 2937 : mpVirDev = pVd;
118 :
119 2937 : if ( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() && m_rDoc.GetDocumentSettingManager().get( DocumentSettingId::USE_VIRTUAL_DEVICE ) )
120 2937 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( mpVirDev );
121 : }
122 2937 : }
123 :
124 2068013 : OutputDevice* DocumentDeviceManager::getReferenceDevice(/*[in]*/ bool bCreate ) const
125 : {
126 2068013 : OutputDevice* pRet = 0;
127 2068013 : if ( !m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE) )
128 : {
129 14490 : pRet = getPrinter( bCreate );
130 :
131 14490 : if ( bCreate && !mpPrt->IsValid() )
132 : {
133 0 : pRet = getVirtualDevice( true );
134 : }
135 : }
136 : else
137 : {
138 2053523 : pRet = getVirtualDevice( bCreate );
139 : }
140 :
141 : assert ( !pRet || !pRet->isDisposed() );
142 :
143 2068013 : return pRet;
144 : }
145 :
146 285 : void DocumentDeviceManager::setReferenceDeviceType(/*[in]*/ bool bNewVirtual, /*[in]*/ bool bNewHiRes )
147 : {
148 555 : if ( m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE) != bNewVirtual ||
149 270 : m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_HIRES_VIRTUAL_DEVICE) != bNewHiRes )
150 : {
151 18 : if ( bNewVirtual )
152 : {
153 3 : VirtualDevice* pMyVirDev = getVirtualDevice( true );
154 3 : if ( !bNewHiRes )
155 3 : pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE06 );
156 : else
157 0 : pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
158 :
159 3 : if( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
160 3 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pMyVirDev );
161 : }
162 : else
163 : {
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 15 : SfxPrinter* pPrinter = getPrinter( true );
171 15 : if( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
172 15 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pPrinter );
173 : }
174 :
175 18 : m_rDoc.GetDocumentSettingManager().set(DocumentSettingId::USE_VIRTUAL_DEVICE, bNewVirtual );
176 18 : m_rDoc.GetDocumentSettingManager().set(DocumentSettingId::USE_HIRES_VIRTUAL_DEVICE, bNewHiRes );
177 18 : PrtDataChanged();
178 18 : m_rDoc.getIDocumentState().SetModified();
179 : }
180 285 : }
181 :
182 0 : const JobSetup* DocumentDeviceManager::getJobsetup() const
183 : {
184 0 : return mpPrt ? &mpPrt->GetJobSetup() : 0;
185 : }
186 :
187 0 : void DocumentDeviceManager::setJobsetup(/*[in]*/ const JobSetup &rJobSetup )
188 : {
189 0 : bool bCheckPageDescs = !mpPrt;
190 0 : bool bDataChanged = false;
191 :
192 0 : if ( mpPrt )
193 : {
194 0 : if ( mpPrt->GetName() == rJobSetup.GetPrinterName() )
195 : {
196 0 : if ( mpPrt->GetJobSetup() != rJobSetup )
197 : {
198 0 : mpPrt->SetJobSetup( rJobSetup );
199 0 : bDataChanged = true;
200 : }
201 : }
202 : else
203 0 : mpPrt.disposeAndClear();
204 : }
205 :
206 0 : if( !mpPrt )
207 : {
208 : //The ItemSet is deleted by Sfx!
209 0 : SfxItemSet *pSet = new SfxItemSet( m_rDoc.GetAttrPool(),
210 : FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
211 : SID_HTML_MODE, SID_HTML_MODE,
212 : SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
213 : SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
214 0 : 0 );
215 0 : VclPtr<SfxPrinter> p = VclPtr<SfxPrinter>::Create( pSet, rJobSetup );
216 0 : if ( bCheckPageDescs )
217 0 : setPrinter( p, true, true );
218 : else
219 : {
220 0 : mpPrt = p;
221 0 : bDataChanged = true;
222 0 : }
223 : }
224 0 : if ( bDataChanged && !m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::USE_VIRTUAL_DEVICE) )
225 0 : PrtDataChanged();
226 0 : }
227 :
228 6445 : const SwPrintData & DocumentDeviceManager::getPrintData() const
229 : {
230 6445 : if(!mpPrtData)
231 : {
232 284 : DocumentDeviceManager * pThis = const_cast< DocumentDeviceManager * >(this);
233 284 : pThis->mpPrtData = new SwPrintData;
234 :
235 : // SwPrintData should be initialized from the configuration,
236 : // the respective config item is implemented by SwPrintOptions which
237 : // is also derived from SwPrintData
238 284 : const SwDocShell *pDocSh = m_rDoc.GetDocShell();
239 : OSL_ENSURE( pDocSh, "pDocSh is 0, can't determine if this is a WebDoc or not" );
240 284 : bool bWeb = 0 != dynamic_cast< const SwWebDocShell * >(pDocSh);
241 284 : SwPrintOptions aPrintOptions( bWeb );
242 284 : *pThis->mpPrtData = aPrintOptions;
243 : }
244 6445 : return *mpPrtData;
245 : }
246 :
247 2668 : void DocumentDeviceManager::setPrintData(/*[in]*/ const SwPrintData& rPrtData )
248 : {
249 2668 : if(!mpPrtData)
250 2667 : mpPrtData = new SwPrintData;
251 2668 : *mpPrtData = rPrtData;
252 2668 : }
253 :
254 8847 : DocumentDeviceManager::~DocumentDeviceManager()
255 : {
256 2949 : delete mpPrtData;
257 2949 : mpVirDev.disposeAndClear();
258 2949 : mpPrt.disposeAndClear();
259 5898 : }
260 :
261 2937 : VirtualDevice& DocumentDeviceManager::CreateVirtualDevice_() const
262 : {
263 : #ifdef IOS
264 : VclPtr<VirtualDevice> pNewVir = VclPtr<VirtualDevice>::Create( 8 );
265 : #else
266 2937 : VclPtr<VirtualDevice> pNewVir = VclPtr<VirtualDevice>::Create( 1 );
267 : #endif
268 :
269 2937 : pNewVir->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
270 :
271 : // #i60945# External leading compatibility for unix systems.
272 2937 : if ( m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING ) )
273 10 : pNewVir->Compat_ZeroExtleadBug();
274 :
275 5874 : MapMode aMapMode( pNewVir->GetMapMode() );
276 2937 : aMapMode.SetMapUnit( MAP_TWIP );
277 2937 : pNewVir->SetMapMode( aMapMode );
278 :
279 2937 : const_cast<DocumentDeviceManager*>(this)->setVirtualDevice( pNewVir, true, true );
280 5874 : return *mpVirDev;
281 : }
282 :
283 23 : SfxPrinter& DocumentDeviceManager::CreatePrinter_() const
284 : {
285 : OSL_ENSURE( ! mpPrt, "Do not call CreatePrinter_(), call getPrinter() instead" );
286 :
287 : #if OSL_DEBUG_LEVEL > 1
288 : OSL_TRACE( "Printer will be created!" );
289 : #endif
290 :
291 : // We create a default SfxPrinter.
292 : // The ItemSet is deleted by Sfx!
293 23 : SfxItemSet *pSet = new SfxItemSet( m_rDoc.GetAttrPool(),
294 : FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
295 : SID_HTML_MODE, SID_HTML_MODE,
296 : SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
297 : SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
298 23 : 0 );
299 :
300 23 : VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pSet );
301 23 : const_cast<DocumentDeviceManager*>(this)->setPrinter( pNewPrt, true, true );
302 23 : return *mpPrt.get();
303 : }
304 :
305 33 : void DocumentDeviceManager::PrtDataChanged()
306 : {
307 : // If you change this, also modify InJobSetup in Sw3io if appropriate.
308 :
309 : // #i41075#
310 : OSL_ENSURE( m_rDoc.getIDocumentSettingAccess().get(DocumentSettingId::USE_VIRTUAL_DEVICE) ||
311 : 0 != getPrinter( false ), "PrtDataChanged will be called recursively!" );
312 33 : SwRootFrm* pTmpRoot = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
313 33 : boost::scoped_ptr<SwWait> pWait;
314 33 : bool bEndAction = false;
315 :
316 33 : if( m_rDoc.GetDocShell() )
317 33 : m_rDoc.GetDocShell()->UpdateFontList();
318 :
319 33 : bool bDraw = true;
320 33 : if ( pTmpRoot )
321 : {
322 1 : SwViewShell *pSh = m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
323 3 : if( pSh &&
324 1 : (!pSh->GetViewOptions()->getBrowseMode() ||
325 0 : pSh->GetViewOptions()->IsPrtFormat()) )
326 : {
327 1 : if ( m_rDoc.GetDocShell() )
328 1 : pWait.reset(new SwWait( *m_rDoc.GetDocShell(), true ));
329 :
330 1 : pTmpRoot->StartAllAction();
331 1 : bEndAction = true;
332 :
333 1 : bDraw = false;
334 1 : if( m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
335 : {
336 1 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING) );
337 1 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( getReferenceDevice( false ) );
338 : }
339 :
340 1 : pFntCache->Flush();
341 :
342 1 : std::set<SwRootFrm*> aAllLayouts = m_rDoc.GetAllLayouts();
343 1 : std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllContent), INV_SIZE));
344 :
345 2 : for(SwViewShell& rShell : pSh->GetRingContainer())
346 2 : rShell.InitPrt(getPrinter(false));
347 : }
348 : }
349 33 : if ( bDraw && m_rDoc.getIDocumentDrawModelAccess().GetDrawModel() )
350 : {
351 32 : const bool bTmpAddExtLeading = m_rDoc.GetDocumentSettingManager().get(DocumentSettingId::ADD_EXT_LEADING);
352 32 : if ( bTmpAddExtLeading != m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->IsAddExtLeading() )
353 9 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetAddExtLeading( bTmpAddExtLeading );
354 :
355 32 : OutputDevice* pOutDev = getReferenceDevice( false );
356 32 : if ( pOutDev != m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetRefDevice() )
357 0 : m_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->SetRefDevice( pOutDev );
358 : }
359 :
360 33 : m_rDoc.PrtOLENotify( true );
361 :
362 33 : if ( bEndAction )
363 1 : pTmpRoot->EndAllAction();
364 33 : }
365 :
366 177 : }
367 :
368 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|