xref: /trunk/main/vcl/source/gdi/print.cxx (revision 635e0213)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #define ENABLE_BYTESTRING_STREAM_OPERATORS
28 #include <list>
29 
30 #include <tools/debug.hxx>
31 #include <tools/resary.hxx>
32 #include <tools/stream.hxx>
33 #include <tools/vcompat.hxx>
34 
35 #include <vcl/unohelp.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/wrkwin.hxx>
38 #include <vcl/virdev.hxx>
39 #include <vcl/window.hxx>
40 #include <vcl/gdimtf.hxx>
41 #include <vcl/metaact.hxx>
42 #include <vcl/print.hxx>
43 
44 #include <salinst.hxx>
45 #include <salgdi.hxx>
46 #include <salptype.hxx>
47 #include <salprn.hxx>
48 #include <svdata.hxx>
49 #include <svids.hrc>
50 #include <jobset.h>
51 #include <outdev.h>
52 #include <print.h>
53 
54 #include <comphelper/processfactory.hxx>
55 
56 #include "com/sun/star/beans/XPropertySet.hpp"
57 #include "com/sun/star/container/XNameAccess.hpp"
58 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
59 
60 using namespace com::sun::star::uno;
61 using namespace com::sun::star::lang;
62 using namespace com::sun::star::beans;
63 using namespace com::sun::star::container;
64 
65 int nImplSysDialog = 0;
66 
67 // =======================================================================
68 
69 namespace
70 {
ImplGetPaperFormat(long nWidth100thMM,long nHeight100thMM)71     static Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM )
72     {
73         PaperInfo aInfo(nWidth100thMM, nHeight100thMM);
74         aInfo.doSloppyFit();
75         return aInfo.getPaper();
76     }
77 
78 // -----------------------------------------------------------------------
79 
ImplGetEmptyPaper()80     static const PaperInfo& ImplGetEmptyPaper()
81     {
82         static PaperInfo aInfo(PAPER_USER);
83         return aInfo;
84     }
85 }
86 
87 // =======================================================================
88 
ImplUpdateJobSetupPaper(JobSetup & rJobSetup)89 void ImplUpdateJobSetupPaper( JobSetup& rJobSetup )
90 {
91 	const ImplJobSetup* pConstData = rJobSetup.ImplGetConstData();
92 
93 	if ( !pConstData->mnPaperWidth || !pConstData->mnPaperHeight )
94 	{
95 		if ( pConstData->mePaperFormat != PAPER_USER )
96 		{
97 			ImplJobSetup* pData  = rJobSetup.ImplGetData();
98 			PaperInfo aInfo(pConstData->mePaperFormat);
99 			pData->mnPaperWidth  = aInfo.getWidth();
100 			pData->mnPaperHeight = aInfo.getHeight();
101 		}
102 	}
103 	else if ( pConstData->mePaperFormat == PAPER_USER )
104 	{
105 		Paper ePaper = ImplGetPaperFormat( pConstData->mnPaperWidth, pConstData->mnPaperHeight );
106 		if ( ePaper != PAPER_USER )
107 			rJobSetup.ImplGetData()->mePaperFormat = ePaper;
108 	}
109 }
110 
111 // ------------------
112 // - PrinterOptions -
113 // ------------------
114 
PrinterOptions()115 PrinterOptions::PrinterOptions() :
116     mbReduceTransparency( sal_False ),
117     meReducedTransparencyMode( PRINTER_TRANSPARENCY_AUTO ),
118     mbReduceGradients( sal_False ),
119     meReducedGradientsMode( PRINTER_GRADIENT_STRIPES ),
120     mnReducedGradientStepCount( 64 ),
121     mbReduceBitmaps( sal_False ),
122     meReducedBitmapMode( PRINTER_BITMAP_NORMAL ),
123     mnReducedBitmapResolution( 200 ),
124     mbReducedBitmapsIncludeTransparency( sal_True ),
125     mbConvertToGreyscales( sal_False )
126 {
127 }
128 
129 // -----------------------------------------------------------------------
130 
~PrinterOptions()131 PrinterOptions::~PrinterOptions()
132 {
133 }
134 
135 #define PROPERTYNAME_REDUCETRANSPARENCY			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceTransparency"))
136 #define PROPERTYNAME_REDUCEDTRANSPARENCYMODE		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedTransparencyMode"))
137 #define PROPERTYNAME_REDUCEGRADIENTS			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceGradients"))
138 #define PROPERTYNAME_REDUCEDGRADIENTMODE		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientMode"))
139 #define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientStepCount"))
140 #define PROPERTYNAME_REDUCEBITMAPS			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceBitmaps"))
141 #define PROPERTYNAME_REDUCEDBITMAPMODE			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapMode"))
142 #define PROPERTYNAME_REDUCEDBITMAPRESOLUTION		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapResolution"))
143 #define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY	rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapIncludesTransparency"))
144 #define PROPERTYNAME_CONVERTTOGREYSCALES		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConvertToGreyscales"))
145 
ReadFromConfig(bool i_bFile)146 bool PrinterOptions::ReadFromConfig( bool i_bFile )
147 {
148     bool bSuccess = false;
149     // save old state in case something goes wrong
150     PrinterOptions aOldValues( *this );
151 
152     // get the configuration service
153     Reference< XMultiServiceFactory > xConfigProvider;
154     Reference< XNameAccess > xConfigAccess;
155     try
156     {
157         // get service provider
158         Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
159         // create configuration hierarchical access name
160         if( xSMgr.is() )
161         {
162             try
163             {
164                 xConfigProvider = Reference< XMultiServiceFactory >(
165                         xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
166                                         "com.sun.star.configuration.ConfigurationProvider" ))),
167                         UNO_QUERY );
168                 if( xConfigProvider.is() )
169                 {
170                     Sequence< Any > aArgs(1);
171                     PropertyValue aVal;
172                     aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
173                     if( i_bFile )
174                         aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Print/Option/File" ) );
175                     else
176                         aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Print/Option/Printer" ) );
177                     aArgs.getArray()[0] <<= aVal;
178                     xConfigAccess = Reference< XNameAccess >(
179                             xConfigProvider->createInstanceWithArguments(
180                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )), aArgs ),
181                                 UNO_QUERY );
182                     if( xConfigAccess.is() )
183                     {
184                         Reference< XPropertySet > xSet( xConfigAccess, UNO_QUERY );
185                         if( xSet.is() )
186                         {
187                             sal_Int32 nValue = 0;
188                             sal_Bool  bValue = 0;
189                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bValue )
190                                 SetReduceTransparency( bValue );
191                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nValue )
192                                 SetReducedTransparencyMode( (PrinterTransparencyMode)nValue );
193                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bValue )
194                                 SetReduceGradients( bValue );
195                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nValue )
196                                 SetReducedGradientMode( (PrinterGradientMode)nValue );
197                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nValue )
198                                 SetReducedGradientStepCount( (sal_uInt16)nValue );
199                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bValue )
200                                 SetReduceBitmaps( bValue );
201                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nValue )
202                                 SetReducedBitmapMode( (PrinterBitmapMode)nValue );
203                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nValue )
204                                 SetReducedBitmapResolution( (sal_uInt16)nValue );
205                             if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bValue )
206                                 SetReducedBitmapIncludesTransparency( bValue );
207                             if( xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bValue )
208                                 SetConvertToGreyscales( bValue );
209 
210                             bSuccess = true;
211                         }
212                     }
213                 }
214             }
215             catch( Exception& )
216             {
217             }
218         }
219     }
220     catch( WrappedTargetException& )
221     {
222     }
223 
224     if( ! bSuccess )
225         *this = aOldValues;
226     return bSuccess;
227 }
228 
SetPrinterOptions(const PrinterOptions & i_rOptions)229 void Printer::SetPrinterOptions( const PrinterOptions& i_rOptions )
230 {
231     *mpPrinterOptions = i_rOptions;
232 }
233 
234 // -------------
235 // - QueueInfo -
236 // -------------
237 
QueueInfo()238 QueueInfo::QueueInfo()
239 {
240 	mnStatus	= 0;
241 	mnJobs		= 0;
242 }
243 
244 // -----------------------------------------------------------------------
245 
QueueInfo(const QueueInfo & rInfo)246 QueueInfo::QueueInfo( const QueueInfo& rInfo ) :
247 	maPrinterName( rInfo.maPrinterName ),
248 	maDriver( rInfo.maDriver ),
249 	maLocation( rInfo.maLocation ),
250 	maComment( rInfo.maComment ),
251 	mnStatus( rInfo.mnStatus ),
252 	mnJobs( rInfo.mnJobs )
253 {
254 }
255 
256 // -----------------------------------------------------------------------
257 
~QueueInfo()258 QueueInfo::~QueueInfo()
259 {
260 }
261 
262 // -----------------------------------------------------------------------
263 
operator ==(const QueueInfo & rInfo) const264 bool QueueInfo::operator==( const QueueInfo& rInfo ) const
265 {
266 	return
267 		maPrinterName		== rInfo.maPrinterName		&&
268 		maDriver		== rInfo.maDriver		&&
269 		maLocation		== rInfo.maLocation		&&
270 		maComment		== rInfo.maComment		&&
271 		mnStatus		== rInfo.mnStatus		&&
272 		mnJobs			== rInfo.mnJobs;
273 }
274 
275 // -----------------------------------------------------------------------
276 
operator <<(SvStream & rOStream,const QueueInfo & rInfo)277 SvStream& operator<<( SvStream& rOStream, const QueueInfo& rInfo )
278 {
279 	VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
280 
281 	rOStream.WriteByteString( rInfo.maPrinterName, RTL_TEXTENCODING_UTF8 );
282 	rOStream.WriteByteString( rInfo.maDriver, RTL_TEXTENCODING_UTF8 );
283 	rOStream.WriteByteString( rInfo.maLocation, RTL_TEXTENCODING_UTF8 );
284 	rOStream.WriteByteString( rInfo.maComment, RTL_TEXTENCODING_UTF8 );
285 	rOStream << rInfo.mnStatus;
286 	rOStream << rInfo.mnJobs;
287 
288 	return rOStream;
289 }
290 
291 // -----------------------------------------------------------------------
292 
operator >>(SvStream & rIStream,QueueInfo & rInfo)293 SvStream& operator>>( SvStream& rIStream, QueueInfo& rInfo )
294 {
295 	VersionCompat aCompat( rIStream, STREAM_READ );
296 
297 	rIStream.ReadByteString( rInfo.maPrinterName, RTL_TEXTENCODING_UTF8 );
298 	rIStream.ReadByteString( rInfo.maDriver, RTL_TEXTENCODING_UTF8 );
299 	rIStream.ReadByteString( rInfo.maLocation, RTL_TEXTENCODING_UTF8 );
300 	rIStream.ReadByteString( rInfo.maComment, RTL_TEXTENCODING_UTF8 );
301 	rIStream >> rInfo.mnStatus;
302 	rIStream >> rInfo.mnJobs;
303 
304 	return rIStream;
305 }
306 
307 // =======================================================================
308 
SalPrinterQueueInfo()309 SalPrinterQueueInfo::SalPrinterQueueInfo()
310 {
311 	mnStatus	= 0;
312 	mnJobs		= QUEUE_JOBS_DONTKNOW;
313 	mpSysData	= NULL;
314 }
315 
316 // -----------------------------------------------------------------------
317 
~SalPrinterQueueInfo()318 SalPrinterQueueInfo::~SalPrinterQueueInfo()
319 {
320 }
321 
322 // -----------------------------------------------------------------------
323 
~ImplPrnQueueList()324 ImplPrnQueueList::~ImplPrnQueueList()
325 {
326 	ImplSVData* 		pSVData = ImplGetSVData();
327     for( unsigned int i = 0; i < m_aQueueInfos.size(); i++ )
328     {
329         delete m_aQueueInfos[i].mpQueueInfo;
330         pSVData->mpDefInst->DeletePrinterQueueInfo( m_aQueueInfos[i].mpSalQueueInfo );
331     }
332 }
333 
334 // -----------------------------------------------------------------------
335 
Add(SalPrinterQueueInfo * pData)336 void ImplPrnQueueList::Add( SalPrinterQueueInfo* pData )
337 {
338     std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash >::iterator it =
339         m_aNameToIndex.find( pData->maPrinterName );
340     if( it == m_aNameToIndex.end() )
341     {
342         m_aNameToIndex[ pData->maPrinterName ] = m_aQueueInfos.size();
343         m_aQueueInfos.push_back( ImplPrnQueueData() );
344         m_aQueueInfos.back().mpQueueInfo = NULL;
345         m_aQueueInfos.back().mpSalQueueInfo = pData;
346         m_aPrinterList.push_back( pData->maPrinterName );
347     }
348     else // this should not happen, but ...
349     {
350         ImplPrnQueueData& rData = m_aQueueInfos[ it->second ];
351         delete rData.mpQueueInfo;
352         rData.mpQueueInfo = NULL;
353         ImplGetSVData()->mpDefInst->DeletePrinterQueueInfo( rData.mpSalQueueInfo );
354         rData.mpSalQueueInfo = pData;
355     }
356 }
357 
358 // -----------------------------------------------------------------------
359 
Get(const rtl::OUString & rPrinter)360 ImplPrnQueueData* ImplPrnQueueList::Get( const rtl::OUString& rPrinter )
361 {
362     ImplPrnQueueData* pData = NULL;
363     std::hash_map<rtl::OUString,sal_Int32,rtl::OUStringHash>::iterator it =
364         m_aNameToIndex.find( rPrinter );
365     if( it != m_aNameToIndex.end() )
366         pData = &m_aQueueInfos[it->second];
367     return pData;
368 }
369 
370 // =======================================================================
371 
ImplInitPrnQueueList()372 static void ImplInitPrnQueueList()
373 {
374 	ImplSVData* pSVData = ImplGetSVData();
375 
376 	pSVData->maGDIData.mpPrinterQueueList = new ImplPrnQueueList;
377 
378     static const char* pEnv = getenv( "SAL_DISABLE_PRINTERLIST" );
379     if( !pEnv || !*pEnv )
380         pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
381 }
382 
383 // -----------------------------------------------------------------------
384 
ImplDeletePrnQueueList()385 void ImplDeletePrnQueueList()
386 {
387 	ImplSVData* 		pSVData = ImplGetSVData();
388 	ImplPrnQueueList*	pPrnList = pSVData->maGDIData.mpPrinterQueueList;
389 
390 	if ( pPrnList )
391 	{
392 		delete pPrnList;
393 		pSVData->maGDIData.mpPrinterQueueList = NULL;
394 	}
395 }
396 
397 // -----------------------------------------------------------------------
398 
GetPrinterQueues()399 const std::vector<rtl::OUString>& Printer::GetPrinterQueues()
400 {
401 	ImplSVData* 		pSVData = ImplGetSVData();
402 	if ( !pSVData->maGDIData.mpPrinterQueueList )
403 		ImplInitPrnQueueList();
404 	return pSVData->maGDIData.mpPrinterQueueList->m_aPrinterList;
405 }
406 
407 // -----------------------------------------------------------------------
GetQueueInfo(const String & rPrinterName,bool bStatusUpdate)408 const QueueInfo* Printer::GetQueueInfo( const String& rPrinterName, bool bStatusUpdate )
409 {
410 	ImplSVData* pSVData = ImplGetSVData();
411 
412 	if ( !pSVData->maGDIData.mpPrinterQueueList )
413 		ImplInitPrnQueueList();
414 
415     ImplPrnQueueData* pInfo = pSVData->maGDIData.mpPrinterQueueList->Get( rPrinterName );
416     if( pInfo )
417     {
418         if( !pInfo->mpQueueInfo || bStatusUpdate )
419             pSVData->mpDefInst->GetPrinterQueueState( pInfo->mpSalQueueInfo );
420 
421         if ( !pInfo->mpQueueInfo )
422             pInfo->mpQueueInfo = new QueueInfo;
423 
424         pInfo->mpQueueInfo->maPrinterName	= pInfo->mpSalQueueInfo->maPrinterName;
425         pInfo->mpQueueInfo->maDriver		= pInfo->mpSalQueueInfo->maDriver;
426         pInfo->mpQueueInfo->maLocation		= pInfo->mpSalQueueInfo->maLocation;
427         pInfo->mpQueueInfo->maComment		= pInfo->mpSalQueueInfo->maComment;
428         pInfo->mpQueueInfo->mnStatus		= pInfo->mpSalQueueInfo->mnStatus;
429         pInfo->mpQueueInfo->mnJobs		= pInfo->mpSalQueueInfo->mnJobs;
430         return pInfo->mpQueueInfo;
431     }
432     return NULL;
433 }
434 
435 // -----------------------------------------------------------------------
436 
GetDefaultPrinterName()437 XubString Printer::GetDefaultPrinterName()
438 {
439     static const char* pEnv = getenv( "SAL_DISABLE_DEFAULTPRINTER" );
440     if( !pEnv || !*pEnv )
441     {
442         ImplSVData* pSVData = ImplGetSVData();
443 
444         return pSVData->mpDefInst->GetDefaultPrinter();
445     }
446     return XubString();
447 }
448 
449 // =======================================================================
450 
ImplInitData()451 void Printer::ImplInitData()
452 {
453 	mbDevOutput		= sal_False;
454 	meOutDevType		= OUTDEV_PRINTER;
455 	mbDefPrinter		= sal_False;
456 	mnError			= 0;
457 	mnCurPage		= 0;
458 	mnCurPrintPage		= 0;
459 	mnPageQueueSize		= 0;
460 	mnCopyCount		= 1;
461 	mbCollateCopy		= sal_False;
462 	mbPrinting		= sal_False;
463 	mbJobActive		= sal_False;
464 	mbPrintFile		= sal_False;
465 	mbInPrintPage		= sal_False;
466 	mbNewJobSetup		= sal_False;
467 	mpInfoPrinter		= NULL;
468 	mpPrinter		= NULL;
469 	mpDisplayDev		= NULL;
470 	mbIsQueuePrinter	= sal_False;
471 	mpPrinterOptions	= new PrinterOptions;
472 
473 	// Printer in die Liste eintragen
474 	ImplSVData* pSVData = ImplGetSVData();
475 	mpNext = pSVData->maGDIData.mpFirstPrinter;
476 	mpPrev = NULL;
477 	if ( mpNext )
478 		mpNext->mpPrev = this;
479 	else
480 		pSVData->maGDIData.mpLastPrinter = this;
481 	pSVData->maGDIData.mpFirstPrinter = this;
482 }
483 
484 // -----------------------------------------------------------------------
485 
ImplInit(SalPrinterQueueInfo * pInfo)486 void Printer::ImplInit( SalPrinterQueueInfo* pInfo )
487 {
488 	ImplSVData* pSVData = ImplGetSVData();
489 	// #i74084# update info for this specific SalPrinterQueueInfo
490 	pSVData->mpDefInst->GetPrinterQueueState( pInfo );
491 
492 	// Testen, ob Treiber überhaupt mit dem JobSetup übereinstimmt
493 	ImplJobSetup* pJobSetup = maJobSetup.ImplGetData();
494 
495 	if ( pJobSetup->mpDriverData )
496 	{
497 		if ( (pJobSetup->maPrinterName != pInfo->maPrinterName) ||
498 			 (pJobSetup->maDriver != pInfo->maDriver) )
499 		{
500 			rtl_freeMemory( pJobSetup->mpDriverData );
501 			pJobSetup->mpDriverData = NULL;
502 			pJobSetup->mnDriverDataLen = 0;
503 		}
504 	}
505 
506 	// Printernamen merken
507 	maPrinterName = pInfo->maPrinterName;
508 	maDriver = pInfo->maDriver;
509 
510 	// In JobSetup den Printernamen eintragen
511 	pJobSetup->maPrinterName = maPrinterName;
512 	pJobSetup->maDriver = maDriver;
513 
514 	mpInfoPrinter	= pSVData->mpDefInst->CreateInfoPrinter( pInfo, pJobSetup );
515 	mpPrinter	= NULL;
516 	mpJobGraphics	= NULL;
517 	ImplUpdateJobSetupPaper( maJobSetup );
518 
519 	if ( !mpInfoPrinter )
520 	{
521 		ImplInitDisplay( NULL );
522 		return;
523 	}
524 
525 	// we need a graphic
526 	if ( !ImplGetGraphics() )
527 	{
528 		ImplInitDisplay( NULL );
529 		return;
530 	}
531 
532 	// initialize data
533 	ImplUpdatePageData();
534 	mpFontList = new ImplDevFontList();
535 	mpFontCache = new ImplFontCache( sal_True );
536 	mpGraphics->GetDevFontList( mpFontList );
537 }
538 
539 // -----------------------------------------------------------------------
540 
ImplInitDisplay(const Window * pWindow)541 void Printer::ImplInitDisplay( const Window* pWindow )
542 {
543 	ImplSVData* pSVData = ImplGetSVData();
544 
545 	mpInfoPrinter		= NULL;
546 	mpPrinter			= NULL;
547 	mpJobGraphics		= NULL;
548 
549 	if ( pWindow )
550 		mpDisplayDev = new VirtualDevice( *pWindow );
551 	else
552 		mpDisplayDev = new VirtualDevice();
553 	mpFontList			= pSVData->maGDIData.mpScreenFontList;
554 	mpFontCache 		= pSVData->maGDIData.mpScreenFontCache;
555 	mnDPIX				= mpDisplayDev->mnDPIX;
556 	mnDPIY				= mpDisplayDev->mnDPIY;
557 }
558 
559 // -----------------------------------------------------------------------
560 
ImplGetQueueInfo(const XubString & rPrinterName,const XubString * pDriver)561 SalPrinterQueueInfo* Printer::ImplGetQueueInfo( const XubString& rPrinterName,
562 												const XubString* pDriver )
563 {
564 	ImplSVData* pSVData = ImplGetSVData();
565 	if ( !pSVData->maGDIData.mpPrinterQueueList )
566 		ImplInitPrnQueueList();
567 
568 	ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
569 	if ( pPrnList && pPrnList->m_aQueueInfos.size() )
570 	{
571 		// first search for the printer name directly
572 		ImplPrnQueueData* pInfo = pPrnList->Get( rPrinterName );
573 		if( pInfo )
574 			return pInfo->mpSalQueueInfo;
575 
576 		// then search case insensitive
577         for( unsigned int i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
578         {
579             if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maPrinterName.EqualsIgnoreCaseAscii( rPrinterName ) )
580                 return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
581 		}
582 
583 		// then search for driver name
584 		if ( pDriver )
585 		{
586             for( unsigned int i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
587             {
588                 if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maDriver == *pDriver )
589                     return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
590             }
591 		}
592 
593 		// then the default printer
594 		pInfo = pPrnList->Get( GetDefaultPrinterName() );
595         if( pInfo )
596             return pInfo->mpSalQueueInfo;
597 
598         // last chance: the first available printer
599         return pPrnList->m_aQueueInfos[0].mpSalQueueInfo;
600 	}
601 
602 	return NULL;
603 }
604 
605 // -----------------------------------------------------------------------
606 
ImplUpdatePageData()607 void Printer::ImplUpdatePageData()
608 {
609 	// we need a graphics
610 	if ( !ImplGetGraphics() )
611 		return;
612 
613 	mpGraphics->GetResolution( mnDPIX, mnDPIY );
614 	mpInfoPrinter->GetPageInfo( maJobSetup.ImplGetConstData(),
615 								mnOutWidth, mnOutHeight,
616 								maPageOffset.X(), maPageOffset.Y(),
617 								maPaperSize.Width(), maPaperSize.Height() );
618     static const char* pDebugOffset = getenv( "SAL_DBG_PAGEOFFSET" );
619     if( pDebugOffset )
620     {
621         rtl::OString aLine( pDebugOffset );
622         sal_Int32 nIndex = 0;
623         rtl::OString aToken( aLine.getToken( 0, ',', nIndex ) );
624         sal_Int32 nLeft = aToken.toInt32();
625         sal_Int32 nTop = nLeft;
626         if( nIndex > 0 )
627         {
628             aToken = aLine.getToken( 0, ',', nIndex );
629             nTop = aToken.toInt32();
630         }
631         maPageOffset = LogicToPixel( Point( static_cast<long>(nLeft),
632                                             static_cast<long>(nTop) ),
633                                      MapMode( MAP_100TH_MM )
634                                      );
635         mnOutWidth = maPaperSize.Width() - 2*maPageOffset.X();
636         mnOutWidth = maPaperSize.Width() - 2*maPageOffset.Y();
637     }
638 }
639 
640 // -----------------------------------------------------------------------
641 
ImplUpdateFontList()642 void Printer::ImplUpdateFontList()
643 {
644 	ImplUpdateFontData( sal_True );
645 }
646 
647 // -----------------------------------------------------------------------
648 
Printer()649 Printer::Printer()
650 {
651 	ImplInitData();
652 	SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( GetDefaultPrinterName(), NULL );
653 	if ( pInfo )
654 	{
655 		ImplInit( pInfo );
656 		if ( !IsDisplayPrinter() )
657 			mbDefPrinter = sal_True;
658 	}
659 	else
660 		ImplInitDisplay( NULL );
661 }
662 
663 // -----------------------------------------------------------------------
664 
Printer(const Window * pWindow)665 Printer::Printer( const Window* pWindow )
666 {
667 	ImplInitData();
668 	ImplInitDisplay( pWindow );
669 }
670 
671 // -----------------------------------------------------------------------
672 
Printer(const JobSetup & rJobSetup)673 Printer::Printer( const JobSetup& rJobSetup ) :
674 	maJobSetup( rJobSetup )
675 {
676 	ImplInitData();
677 	SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rJobSetup.mpData->maPrinterName,
678 												   &rJobSetup.mpData->maDriver );
679 	if ( pInfo )
680 	{
681 		ImplInit( pInfo );
682 		SetJobSetup( rJobSetup );
683 	}
684 	else
685 	{
686 		ImplInitDisplay( NULL );
687 		maJobSetup = JobSetup();
688 	}
689 }
690 
691 // -----------------------------------------------------------------------
692 
Printer(const QueueInfo & rQueueInfo)693 Printer::Printer( const QueueInfo& rQueueInfo )
694 {
695 	ImplInitData();
696 	SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rQueueInfo.GetPrinterName(),
697 												   &rQueueInfo.GetDriver() );
698 	if ( pInfo )
699 		ImplInit( pInfo );
700 	else
701 		ImplInitDisplay( NULL );
702 }
703 
704 // -----------------------------------------------------------------------
705 
Printer(const XubString & rPrinterName)706 Printer::Printer( const XubString& rPrinterName )
707 {
708 	ImplInitData();
709 	SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rPrinterName, NULL );
710 	if ( pInfo )
711 		ImplInit( pInfo );
712 	else
713 		ImplInitDisplay( NULL );
714 }
715 
716 // -----------------------------------------------------------------------
717 
~Printer()718 Printer::~Printer()
719 {
720 	DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
721 	DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
722 
723     delete mpPrinterOptions;
724 
725 	ImplReleaseGraphics();
726 	if ( mpInfoPrinter )
727 		ImplGetSVData()->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
728 	if ( mpDisplayDev )
729 		delete mpDisplayDev;
730 	else
731 	{
732 		// OutputDevice-Dtor versucht das gleiche, deshalb muss hier
733 		// der FontEntry auch auf NULL gesetzt werden
734         // TODO: consolidate duplicate cleanup by Printer and OutputDevice
735 		if ( mpFontEntry )
736 		{
737 			mpFontCache->Release( mpFontEntry );
738 			mpFontEntry = NULL;
739 		}
740 		if ( mpGetDevFontList )
741 		{
742 			delete mpGetDevFontList;
743 			mpGetDevFontList = NULL;
744 		}
745 		if ( mpGetDevSizeList )
746 		{
747 			delete mpGetDevSizeList;
748 			mpGetDevSizeList = NULL;
749 		}
750 		delete mpFontCache;
751         mpFontCache = NULL;
752         // font list deleted by OutputDevice dtor
753 	}
754 
755 	// Printer aus der Liste eintragen
756 	ImplSVData* pSVData = ImplGetSVData();
757 	if ( mpPrev )
758 		mpPrev->mpNext = mpNext;
759 	else
760 		pSVData->maGDIData.mpFirstPrinter = mpNext;
761 	if ( mpNext )
762 		mpNext->mpPrev = mpPrev;
763 	else
764 		pSVData->maGDIData.mpLastPrinter = mpPrev;
765 }
766 
767 // -----------------------------------------------------------------------
Compat_OldPrinterMetrics(bool bSet)768 void Printer::Compat_OldPrinterMetrics( bool bSet )
769 {
770     // propagate flag
771     if( mpInfoPrinter )
772         mpInfoPrinter->m_bCompatMetrics = bSet;
773 
774     // get new font data
775     ImplUpdateFontData( sal_True );
776 }
777 
778 // -----------------------------------------------------------------------
779 
GetCapabilities(sal_uInt16 nType) const780 sal_uLong Printer::GetCapabilities( sal_uInt16 nType ) const
781 {
782 	if ( IsDisplayPrinter() )
783 		return sal_False;
784 
785     if( mpInfoPrinter )
786 	    return mpInfoPrinter->GetCapabilities( maJobSetup.ImplGetConstData(), nType );
787     else
788         return sal_False;
789 }
790 
791 // -----------------------------------------------------------------------
792 
HasSupport(PrinterSupport eFeature) const793 sal_Bool Printer::HasSupport( PrinterSupport eFeature ) const
794 {
795 	switch ( eFeature )
796 	{
797 		case SUPPORT_SET_ORIENTATION:
798 			return (sal_Bool)GetCapabilities( PRINTER_CAPABILITIES_SETORIENTATION );
799 		case SUPPORT_SET_PAPERBIN:
800 			return (sal_Bool)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERBIN );
801 		case SUPPORT_SET_PAPERSIZE:
802 			return (sal_Bool)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERSIZE );
803 		case SUPPORT_SET_PAPER:
804 			return (sal_Bool)GetCapabilities( PRINTER_CAPABILITIES_SETPAPER );
805 		case SUPPORT_COPY:
806 			return (GetCapabilities( PRINTER_CAPABILITIES_COPIES ) != 0);
807 		case SUPPORT_COLLATECOPY:
808 			return (GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES ) != 0);
809 		case SUPPORT_SETUPDIALOG:
810 			return (sal_Bool)GetCapabilities( PRINTER_CAPABILITIES_SUPPORTDIALOG );
811 		case SUPPORT_FAX:
812 			return (sal_Bool) GetCapabilities( PRINTER_CAPABILITIES_FAX );
813 		case SUPPORT_PDF:
814 			return (sal_Bool) GetCapabilities( PRINTER_CAPABILITIES_PDF );
815 	}
816 
817 	return sal_True;
818 }
819 
820 // -----------------------------------------------------------------------
821 
SetJobSetup(const JobSetup & rSetup)822 sal_Bool Printer::SetJobSetup( const JobSetup& rSetup )
823 {
824 	if ( IsDisplayPrinter() || mbInPrintPage )
825 		return sal_False;
826 
827 	JobSetup aJobSetup = rSetup;
828 
829 	ImplReleaseGraphics();
830 	if ( mpInfoPrinter->SetPrinterData( aJobSetup.ImplGetData() ) )
831 	{
832 		ImplUpdateJobSetupPaper( aJobSetup );
833 		mbNewJobSetup = sal_True;
834 		maJobSetup = aJobSetup;
835 		ImplUpdatePageData();
836 		ImplUpdateFontList();
837 		return sal_True;
838 	}
839 
840 	return sal_False;
841 }
842 
843 // -----------------------------------------------------------------------
844 
845 
Setup(Window * pWindow)846 sal_Bool Printer::Setup( Window* pWindow )
847 {
848 	if ( IsDisplayPrinter() )
849 		return sal_False;
850 
851 	if ( IsJobActive() || IsPrinting() )
852 		return sal_False;
853 
854 	JobSetup aJobSetup = maJobSetup;
855 	SalFrame* pFrame;
856 	if ( !pWindow )
857         pWindow = ImplGetDefaultWindow();
858     if( !pWindow )
859         return sal_False;
860 
861     pFrame = pWindow->ImplGetFrame();
862 	ImplReleaseGraphics();
863 	ImplSVData* pSVData = ImplGetSVData();
864 	pSVData->maAppData.mnModalMode++;
865 	nImplSysDialog++;
866 	sal_Bool bSetup = mpInfoPrinter->Setup( pFrame, aJobSetup.ImplGetData() );
867 	pSVData->maAppData.mnModalMode--;
868 	nImplSysDialog--;
869 	if ( bSetup )
870 	{
871 		ImplUpdateJobSetupPaper( aJobSetup );
872 		mbNewJobSetup = sal_True;
873 		maJobSetup = aJobSetup;
874 		ImplUpdatePageData();
875 		ImplUpdateFontList();
876 		return sal_True;
877 	}
878 	return sal_False;
879 }
880 
881 // -----------------------------------------------------------------------
882 
SetPrinterProps(const Printer * pPrinter)883 sal_Bool Printer::SetPrinterProps( const Printer* pPrinter )
884 {
885 	if ( IsJobActive() || IsPrinting() )
886 		return sal_False;
887 
888 	ImplSVData* pSVData = ImplGetSVData();
889 
890 	mbDefPrinter	    = pPrinter->mbDefPrinter;
891 	maPrintFile 	    = pPrinter->maPrintFile;
892 	mbPrintFile 	    = pPrinter->mbPrintFile;
893 	mnCopyCount 	    = pPrinter->mnCopyCount;
894 	mbCollateCopy	    = pPrinter->mbCollateCopy;
895 	mnPageQueueSize     = pPrinter->mnPageQueueSize;
896     *mpPrinterOptions   = *pPrinter->mpPrinterOptions;
897 
898 	if ( pPrinter->IsDisplayPrinter() )
899 	{
900 		// Alten Printer zerstören
901 		if ( !IsDisplayPrinter() )
902 		{
903 			ImplReleaseGraphics();
904 			pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
905 			if ( mpFontEntry )
906 			{
907 				mpFontCache->Release( mpFontEntry );
908 				mpFontEntry = NULL;
909 			}
910 			if ( mpGetDevFontList )
911 			{
912 				delete mpGetDevFontList;
913 				mpGetDevFontList = NULL;
914 			}
915 			if ( mpGetDevSizeList )
916 			{
917 				delete mpGetDevSizeList;
918 				mpGetDevSizeList = NULL;
919 			}
920             // clean up font list
921 			delete mpFontCache;
922 			delete mpFontList;
923 			mpFontCache = NULL;
924 			mpFontList = NULL;
925 
926 			mbInitFont = sal_True;
927 			mbNewFont = sal_True;
928 			mpInfoPrinter = NULL;
929 		}
930 
931 		// Neuen Printer bauen
932 		ImplInitDisplay( NULL );
933 		return sal_True;
934 	}
935 
936 	// Alten Printer zerstören?
937 	if ( GetName() != pPrinter->GetName() )
938 	{
939 		ImplReleaseGraphics();
940 		if ( mpDisplayDev )
941 		{
942 			delete mpDisplayDev;
943 			mpDisplayDev = NULL;
944 		}
945 		else
946 		{
947 			pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
948 
949 			if ( mpFontEntry )
950 			{
951 				mpFontCache->Release( mpFontEntry );
952 				mpFontEntry = NULL;
953 			}
954 			if ( mpGetDevFontList )
955 			{
956 				delete mpGetDevFontList;
957 				mpGetDevFontList = NULL;
958 			}
959 			if ( mpGetDevSizeList )
960 			{
961 				delete mpGetDevSizeList;
962 				mpGetDevSizeList = NULL;
963 			}
964 			delete mpFontCache;
965 			delete mpFontList;
966 			mpFontCache = NULL;
967 			mpFontList = NULL;
968 			mbInitFont = sal_True;
969 			mbNewFont = sal_True;
970 			mpInfoPrinter = NULL;
971 		}
972 
973 		// Neuen Printer bauen
974 		XubString aDriver = pPrinter->GetDriverName();
975 		SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( pPrinter->GetName(), &aDriver );
976 		if ( pInfo )
977 		{
978 			ImplInit( pInfo );
979 			SetJobSetup( pPrinter->GetJobSetup() );
980 		}
981 		else
982 			ImplInitDisplay( NULL );
983 	}
984 	else
985 		SetJobSetup( pPrinter->GetJobSetup() );
986 
987 	return sal_False;
988 }
989 
990 // -----------------------------------------------------------------------
991 
SetOrientation(Orientation eOrientation)992 sal_Bool Printer::SetOrientation( Orientation eOrientation )
993 {
994 	if ( mbInPrintPage )
995 		return sal_False;
996 
997 	if ( maJobSetup.ImplGetConstData()->meOrientation != eOrientation )
998 	{
999 		JobSetup		aJobSetup = maJobSetup;
1000 		ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1001 		pSetupData->meOrientation = eOrientation;
1002 
1003 		if ( IsDisplayPrinter() )
1004 		{
1005 			mbNewJobSetup = sal_True;
1006 			maJobSetup = aJobSetup;
1007 			return sal_True;
1008 		}
1009 
1010 		ImplReleaseGraphics();
1011 		if ( mpInfoPrinter->SetData( SAL_JOBSET_ORIENTATION, pSetupData ) )
1012 		{
1013 			ImplUpdateJobSetupPaper( aJobSetup );
1014 			mbNewJobSetup = sal_True;
1015 			maJobSetup = aJobSetup;
1016 			ImplUpdatePageData();
1017 			ImplUpdateFontList();
1018 			return sal_True;
1019 		}
1020 		else
1021 			return sal_False;
1022 	}
1023 
1024 	return sal_True;
1025 }
1026 
1027 // -----------------------------------------------------------------------
1028 
GetOrientation() const1029 Orientation Printer::GetOrientation() const
1030 {
1031 	return maJobSetup.ImplGetConstData()->meOrientation;
1032 }
1033 
1034 // -----------------------------------------------------------------------
1035 
SetPaperBin(sal_uInt16 nPaperBin)1036 sal_Bool Printer::SetPaperBin( sal_uInt16 nPaperBin )
1037 {
1038 	if ( mbInPrintPage )
1039 		return sal_False;
1040 
1041 	if ( (maJobSetup.ImplGetConstData()->mnPaperBin != nPaperBin) &&
1042 		 (nPaperBin < GetPaperBinCount()) )
1043 	{
1044 		JobSetup		aJobSetup = maJobSetup;
1045 		ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1046 		pSetupData->mnPaperBin = nPaperBin;
1047 
1048 		if ( IsDisplayPrinter() )
1049 		{
1050 			mbNewJobSetup = sal_True;
1051 			maJobSetup = aJobSetup;
1052 			return sal_True;
1053 		}
1054 
1055 		ImplReleaseGraphics();
1056 		if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERBIN, pSetupData ) )
1057 		{
1058 			ImplUpdateJobSetupPaper( aJobSetup );
1059 			mbNewJobSetup = sal_True;
1060 			maJobSetup = aJobSetup;
1061 			ImplUpdatePageData();
1062 			ImplUpdateFontList();
1063 			return sal_True;
1064 		}
1065 		else
1066 			return sal_False;
1067 	}
1068 
1069 	return sal_True;
1070 }
1071 
1072 // -----------------------------------------------------------------------
1073 
GetPaperBin() const1074 sal_uInt16 Printer::GetPaperBin() const
1075 {
1076 	return maJobSetup.ImplGetConstData()->mnPaperBin;
1077 }
1078 
1079 // -----------------------------------------------------------------------
1080 
1081 // Map user paper format to a available printer paper formats
ImplFindPaperFormatForUserSize(JobSetup & aJobSetup,bool bMatchNearest)1082 void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup, bool bMatchNearest )
1083 {
1084 	ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1085 
1086 	int		nLandscapeAngle	= GetLandscapeAngle();
1087 	int		nPaperCount		= GetPaperInfoCount();
1088     bool    bFound = false;
1089 
1090     PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight);
1091 
1092 	// Alle Papierformate vergleichen und ein passendes raussuchen
1093 	for ( int i = 0; i < nPaperCount; i++ )
1094 	{
1095 		const PaperInfo& rPaperInfo = GetPaperInfo( i );
1096 
1097 		if ( aInfo.sloppyEqual(rPaperInfo) )
1098 		{
1099 			pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
1100 															rPaperInfo.getHeight() );
1101             pSetupData->meOrientation = ORIENTATION_PORTRAIT;
1102             bFound = true;
1103 			break;
1104 		}
1105 	}
1106 
1107 	// If the printer supports landscape orientation, check paper sizes again
1108 	// with landscape orientation. This is necessary as a printer driver provides
1109 	// all paper sizes with portrait orientation only!
1110 	if ( pSetupData->mePaperFormat == PAPER_USER &&
1111 		 nLandscapeAngle != 0 &&
1112 		 HasSupport( SUPPORT_SET_ORIENTATION ))
1113 	{
1114 
1115         PaperInfo aRotatedInfo(pSetupData->mnPaperHeight, pSetupData->mnPaperWidth);
1116 
1117 		for ( int i = 0; i < nPaperCount; i++ )
1118 		{
1119 			const PaperInfo& rPaperInfo = GetPaperInfo( i );
1120 
1121 			if ( aRotatedInfo.sloppyEqual( rPaperInfo ) )
1122 			{
1123 				pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
1124 																rPaperInfo.getHeight() );
1125                 pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
1126                 bFound = true;
1127 				break;
1128 			}
1129 		}
1130 	}
1131 
1132     if( ! bFound && bMatchNearest )
1133     {
1134          sal_Int64 nBestMatch = SAL_MAX_INT64;
1135          int nBestIndex = 0;
1136          Orientation eBestOrientation = ORIENTATION_PORTRAIT;
1137          for( int i = 0; i < nPaperCount; i++ )
1138          {
1139              const PaperInfo& rPaperInfo = GetPaperInfo( i );
1140 
1141              // check portrait match
1142              sal_Int64 nDX = pSetupData->mnPaperWidth - rPaperInfo.getWidth();
1143              sal_Int64 nDY = pSetupData->mnPaperHeight - rPaperInfo.getHeight();
1144              sal_Int64 nMatch = nDX*nDX + nDY*nDY;
1145              if( nMatch < nBestMatch )
1146              {
1147                  nBestMatch = nMatch;
1148                  nBestIndex = i;
1149                  eBestOrientation = ORIENTATION_PORTRAIT;
1150              }
1151 
1152              // check landscape match
1153              nDX = pSetupData->mnPaperWidth - rPaperInfo.getHeight();
1154              nDY = pSetupData->mnPaperHeight - rPaperInfo.getWidth();
1155              nMatch = nDX*nDX + nDY*nDY;
1156              if( nMatch < nBestMatch )
1157              {
1158                  nBestMatch = nMatch;
1159                  nBestIndex = i;
1160                  eBestOrientation = ORIENTATION_LANDSCAPE;
1161              }
1162          }
1163          const PaperInfo& rBestInfo = GetPaperInfo( nBestIndex );
1164          pSetupData->mePaperFormat = ImplGetPaperFormat( rBestInfo.getWidth(),
1165                                                          rBestInfo.getHeight() );
1166          pSetupData->meOrientation = eBestOrientation;
1167     }
1168 }
1169 
1170 // -----------------------------------------------------------------------
1171 
SetPaper(Paper ePaper)1172 sal_Bool Printer::SetPaper( Paper ePaper )
1173 {
1174 	if ( mbInPrintPage )
1175 		return sal_False;
1176 
1177 	if ( maJobSetup.ImplGetConstData()->mePaperFormat != ePaper )
1178 	{
1179 		JobSetup		aJobSetup = maJobSetup;
1180 		ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1181 		pSetupData->mePaperFormat = ePaper;
1182 		if ( ePaper != PAPER_USER )
1183 		{
1184             PaperInfo aInfo(ePaper);
1185 			pSetupData->mnPaperWidth  = aInfo.getWidth();
1186 			pSetupData->mnPaperHeight = aInfo.getHeight();
1187 		}
1188 
1189 		if ( IsDisplayPrinter() )
1190 		{
1191 			mbNewJobSetup = sal_True;
1192 			maJobSetup = aJobSetup;
1193 			return sal_True;
1194 		}
1195 
1196 		ImplReleaseGraphics();
1197 		if ( ePaper == PAPER_USER )
1198 			ImplFindPaperFormatForUserSize( aJobSetup, false );
1199 		if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
1200 		{
1201 			ImplUpdateJobSetupPaper( aJobSetup );
1202 			mbNewJobSetup = sal_True;
1203 			maJobSetup = aJobSetup;
1204 			ImplUpdatePageData();
1205 			ImplUpdateFontList();
1206 			return sal_True;
1207 		}
1208 		else
1209 			return sal_False;
1210 	}
1211 
1212 	return sal_True;
1213 }
1214 
1215 // -----------------------------------------------------------------------
1216 
SetPaperSizeUser(const Size & rSize)1217 sal_Bool Printer::SetPaperSizeUser( const Size& rSize )
1218 {
1219     return SetPaperSizeUser( rSize, false );
1220 }
1221 
SetPaperSizeUser(const Size & rSize,bool bMatchNearest)1222 sal_Bool Printer::SetPaperSizeUser( const Size& rSize, bool bMatchNearest )
1223 {
1224 	if ( mbInPrintPage )
1225 		return sal_False;
1226 
1227     const Size aPixSize = LogicToPixel( rSize );
1228     const Size aPageSize = PixelToLogic( aPixSize, MAP_100TH_MM );
1229     bool bNeedToChange(maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width() ||
1230         maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height());
1231 
1232     if(!bNeedToChange)
1233     {
1234         // #122984# only need to change when Paper is different from PAPER_USER and
1235         // the mapped Paper which will created below in the call to ImplFindPaperFormatForUserSize
1236         // and will replace maJobSetup.ImplGetConstData()->mePaperFormat. This leads to
1237         // unnecessary JobSetups, e.g. when printing a multi-page fax, but also with
1238         // normal print
1239         const Paper aPaper = ImplGetPaperFormat(aPageSize.Width(), aPageSize.Height());
1240 
1241         bNeedToChange = maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER &&
1242             maJobSetup.ImplGetConstData()->mePaperFormat != aPaper;
1243     }
1244 
1245     if(bNeedToChange)
1246 	{
1247 		JobSetup		aJobSetup = maJobSetup;
1248 		ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1249 		pSetupData->mePaperFormat	= PAPER_USER;
1250 		pSetupData->mnPaperWidth	= aPageSize.Width();
1251 		pSetupData->mnPaperHeight	= aPageSize.Height();
1252 
1253 		if ( IsDisplayPrinter() )
1254 		{
1255 			mbNewJobSetup = sal_True;
1256 			maJobSetup = aJobSetup;
1257 			return sal_True;
1258 		}
1259 
1260 		ImplReleaseGraphics();
1261 		ImplFindPaperFormatForUserSize( aJobSetup, bMatchNearest );
1262 
1263 		// Changing the paper size can also change the orientation!
1264 		if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
1265 		{
1266 			ImplUpdateJobSetupPaper( aJobSetup );
1267 			mbNewJobSetup = sal_True;
1268 			maJobSetup = aJobSetup;
1269 			ImplUpdatePageData();
1270 			ImplUpdateFontList();
1271 			return sal_True;
1272 		}
1273 		else
1274 			return sal_False;
1275 	}
1276 
1277 	return sal_True;
1278 }
1279 
1280 // -----------------------------------------------------------------------
1281 
GetPaperInfoCount() const1282 int Printer::GetPaperInfoCount() const
1283 {
1284     if( ! mpInfoPrinter )
1285         return 0;
1286     if( ! mpInfoPrinter->m_bPapersInit )
1287         mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1288     return mpInfoPrinter->m_aPaperFormats.size();
1289 }
1290 
1291 // -----------------------------------------------------------------------
1292 
GetPaperName(Paper ePaper)1293 rtl::OUString Printer::GetPaperName( Paper ePaper )
1294 {
1295 	ImplSVData* pSVData = ImplGetSVData();
1296 	if( ! pSVData->mpPaperNames )
1297 	{
1298 		pSVData->mpPaperNames = new std::hash_map< int, rtl::OUString >();
1299 		if( ImplGetResMgr() )
1300 		{
1301 			ResStringArray aPaperStrings( VclResId( RID_STR_PAPERNAMES ) );
1302 			static const int PaperIndex[] =
1303 			{
1304 				PAPER_A0, PAPER_A1, PAPER_A2, PAPER_A3, PAPER_A4, PAPER_A5,
1305 				PAPER_B4_ISO, PAPER_B5_ISO, PAPER_LETTER, PAPER_LEGAL, PAPER_TABLOID,
1306 				PAPER_USER, PAPER_B6_ISO, PAPER_ENV_C4, PAPER_ENV_C5, PAPER_ENV_C6, PAPER_ENV_C65,
1307 				PAPER_ENV_DL, PAPER_SLIDE_DIA, PAPER_SCREEN_4_BY_3, PAPER_SCREEN_16_BY_9, PAPER_SCREEN_16_BY_10,
1308 				PAPER_C, PAPER_D, PAPER_E, PAPER_EXECUTIVE, PAPER_FANFOLD_LEGAL_DE, PAPER_ENV_MONARCH,
1309 				PAPER_ENV_PERSONAL, PAPER_ENV_9, PAPER_ENV_10, PAPER_ENV_11, PAPER_ENV_12, PAPER_KAI16,
1310 				PAPER_KAI32, PAPER_KAI32BIG, PAPER_B4_JIS, PAPER_B5_JIS, PAPER_B6_JIS
1311 			};
1312 			OSL_ENSURE( sal_uInt32(sizeof(PaperIndex)/sizeof(PaperIndex[0])) == aPaperStrings.Count(), "localized paper name count wrong" );
1313 			for( int i = 0; i < int(sizeof(PaperIndex)/sizeof(PaperIndex[0])); i++ )
1314 			(*pSVData->mpPaperNames)[PaperIndex[i]] = aPaperStrings.GetString(i);
1315 		}
1316 	}
1317 
1318 	std::hash_map<int,rtl::OUString>::const_iterator it = pSVData->mpPaperNames->find( (int)ePaper );
1319 	return (it != pSVData->mpPaperNames->end()) ? it->second : rtl::OUString();
1320 }
1321 
1322 // -----------------------------------------------------------------------
1323 
GetPaperName(bool i_bPaperUser) const1324 rtl::OUString Printer::GetPaperName( bool i_bPaperUser ) const
1325 {
1326 	Size  aPageSize = PixelToLogic( GetPaperSizePixel(), MAP_100TH_MM );
1327 	Paper ePaper    = ImplGetPaperFormat( aPageSize.Width(), aPageSize.Height() );
1328 	if( ePaper == PAPER_USER )
1329 	    ePaper = ImplGetPaperFormat( aPageSize.Height(), aPageSize.Width() );
1330 	return (ePaper != PAPER_USER || i_bPaperUser ) ? GetPaperName( ePaper ) : rtl::OUString();
1331 }
1332 
1333 // -----------------------------------------------------------------------
1334 
GetPaperInfo(int nPaper) const1335 const PaperInfo& Printer::GetPaperInfo( int nPaper ) const
1336 {
1337 	if( ! mpInfoPrinter )
1338 		return ImplGetEmptyPaper();
1339 	if( ! mpInfoPrinter->m_bPapersInit )
1340 		mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1341 	if( mpInfoPrinter->m_aPaperFormats.empty() || nPaper < 0 || nPaper >= int(mpInfoPrinter->m_aPaperFormats.size()) )
1342 		return ImplGetEmptyPaper();
1343 	return mpInfoPrinter->m_aPaperFormats[nPaper];
1344 }
1345 
1346 // -----------------------------------------------------------------------
1347 
GetDuplexMode() const1348 DuplexMode Printer::GetDuplexMode() const
1349 {
1350 	return maJobSetup.ImplGetConstData()->meDuplexMode;
1351 }
1352 
1353 // -----------------------------------------------------------------------
1354 
SetDuplexMode(DuplexMode eDuplex)1355 sal_Bool Printer::SetDuplexMode( DuplexMode eDuplex )
1356 {
1357 	if ( mbInPrintPage )
1358 		return sal_False;
1359 
1360 	if ( maJobSetup.ImplGetConstData()->meDuplexMode != eDuplex )
1361 	{
1362 		JobSetup		aJobSetup = maJobSetup;
1363 		ImplJobSetup*	pSetupData = aJobSetup.ImplGetData();
1364 		pSetupData->meDuplexMode = eDuplex;
1365 
1366 		if ( IsDisplayPrinter() )
1367 		{
1368 			mbNewJobSetup = sal_True;
1369 			maJobSetup = aJobSetup;
1370 			return sal_True;
1371 		}
1372 
1373 		ImplReleaseGraphics();
1374 		if ( mpInfoPrinter->SetData( SAL_JOBSET_DUPLEXMODE, pSetupData ) )
1375 		{
1376 			ImplUpdateJobSetupPaper( aJobSetup );
1377 			mbNewJobSetup = sal_True;
1378 			maJobSetup = aJobSetup;
1379 			ImplUpdatePageData();
1380 			ImplUpdateFontList();
1381 			return sal_True;
1382 		}
1383 		else
1384 			return sal_False;
1385 	}
1386 
1387 	return sal_True;
1388 }
1389 
1390 // -----------------------------------------------------------------------
1391 
GetLandscapeAngle() const1392 int Printer::GetLandscapeAngle() const
1393 {
1394 	return mpInfoPrinter ? mpInfoPrinter->GetLandscapeAngle( maJobSetup.ImplGetConstData() ) : 900;
1395 }
1396 
1397 // -----------------------------------------------------------------------
1398 
GetPaper() const1399 Paper Printer::GetPaper() const
1400 {
1401 	return maJobSetup.ImplGetConstData()->mePaperFormat;
1402 }
1403 
1404 // -----------------------------------------------------------------------
1405 
GetPaperBinCount() const1406 sal_uInt16 Printer::GetPaperBinCount() const
1407 {
1408 	if ( IsDisplayPrinter() )
1409 		return 0;
1410 
1411 	return (sal_uInt16)mpInfoPrinter->GetPaperBinCount( maJobSetup.ImplGetConstData() );
1412 }
1413 
1414 // -----------------------------------------------------------------------
1415 
GetPaperBinName(sal_uInt16 nPaperBin) const1416 XubString Printer::GetPaperBinName( sal_uInt16 nPaperBin ) const
1417 {
1418 	if ( IsDisplayPrinter() )
1419 		return ImplGetSVEmptyStr();
1420 
1421 	if ( nPaperBin < GetPaperBinCount() )
1422 		return mpInfoPrinter->GetPaperBinName( maJobSetup.ImplGetConstData(), nPaperBin );
1423 	else
1424 		return ImplGetSVEmptyStr();
1425 }
1426 
1427 // -----------------------------------------------------------------------
1428 
SetCopyCount(sal_uInt16 nCopy,sal_Bool bCollate)1429 sal_Bool Printer::SetCopyCount( sal_uInt16 nCopy, sal_Bool bCollate )
1430 {
1431 	mnCopyCount = nCopy;
1432 	mbCollateCopy = bCollate;
1433 	return sal_True;
1434 }
1435 
1436 // -----------------------------------------------------------------------
1437 
Error()1438 void Printer::Error()
1439 {
1440 	maErrorHdl.Call( this );
1441 }
1442 
1443 // -----------------------------------------------------------------------
1444 
1445 
ImplSalPrinterErrorCodeToVCL(sal_uLong nError)1446 sal_uLong Printer::ImplSalPrinterErrorCodeToVCL( sal_uLong nError )
1447 {
1448 	sal_uLong nVCLError;
1449 	switch ( nError )
1450 	{
1451 		case 0:
1452 			nVCLError = PRINTER_OK;
1453 			break;
1454 		case SAL_PRINTER_ERROR_ABORT:
1455 			nVCLError = PRINTER_ABORT;
1456 			break;
1457 		default:
1458 			nVCLError = PRINTER_GENERALERROR;
1459 			break;
1460 	}
1461 
1462 	return nVCLError;
1463 }
1464 
1465 // -----------------------------------------------------------------------
1466 
ImplEndPrint()1467 void Printer::ImplEndPrint()
1468 {
1469 	mbPrinting		= sal_False;
1470 	mnCurPrintPage	= 0;
1471 	maJobName.Erase();
1472 }
1473 
1474 // -----------------------------------------------------------------------
1475 
IMPL_LINK(Printer,ImplDestroyPrinterAsync,void *,pSalPrinter)1476 IMPL_LINK( Printer, ImplDestroyPrinterAsync, void*, pSalPrinter )
1477 {
1478 	SalPrinter* pPrinter = (SalPrinter*)pSalPrinter;
1479 	ImplSVData* pSVData = ImplGetSVData();
1480 	pSVData->mpDefInst->DestroyPrinter( pPrinter );
1481 	return 0;
1482 }
1483 
1484 // -----------------------------------------------------------------------
1485 
EndJob()1486 sal_Bool Printer::EndJob()
1487 {
1488 	sal_Bool bRet = sal_False;
1489 	if ( !IsJobActive() )
1490 		return bRet;
1491 
1492 	DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
1493 
1494 	mbJobActive = sal_False;
1495 
1496 	if ( mpPrinter )
1497 	{
1498 		ImplReleaseGraphics();
1499 
1500 		mnCurPage = 0;
1501 
1502 		bRet = sal_True;
1503 
1504         mbPrinting		= sal_False;
1505         mnCurPrintPage	= 0;
1506         maJobName.Erase();
1507 
1508         mbDevOutput = sal_False;
1509         bRet = mpPrinter->EndJob();
1510         // Hier den Drucker nicht asyncron zerstören, da es
1511         // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
1512         // und ein Druckerobjekt zerstört wird
1513         ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
1514         mpPrinter = NULL;
1515 	}
1516 
1517 	return bRet;
1518 }
1519 
1520 // -----------------------------------------------------------------------
1521 
AbortJob()1522 sal_Bool Printer::AbortJob()
1523 {
1524 	// Wenn wir einen Queue-Printer haben, kann man diesen noch mit
1525 	// AbortJob() abbrechen, solange dieser noch am Drucken ist
1526 	if ( !IsJobActive() && !IsPrinting() )
1527 		return sal_False;
1528 
1529 	mbJobActive	= sal_False;
1530 	mbInPrintPage	= sal_False;
1531 	mpJobGraphics	= NULL;
1532 
1533 	if ( mpPrinter )
1534 	{
1535 		mbPrinting		= sal_False;
1536 		mnCurPage		= 0;
1537 		mnCurPrintPage		= 0;
1538 		maJobName.Erase();
1539 
1540         ImplReleaseGraphics();
1541         mbDevOutput = sal_False;
1542         mpPrinter->AbortJob();
1543         Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
1544         mpPrinter = NULL;
1545 
1546 		return sal_True;
1547 	}
1548 
1549 	return sal_False;
1550 }
1551 
1552 // -----------------------------------------------------------------------
1553 
ImplStartPage()1554 void Printer::ImplStartPage()
1555 {
1556 	if ( !IsJobActive() )
1557 		return;
1558 
1559 	if ( mpPrinter )
1560 	{
1561         SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
1562         if ( pGraphics )
1563         {
1564             ImplReleaseGraphics();
1565             mpJobGraphics = pGraphics;
1566         }
1567         mbDevOutput = sal_True;
1568 
1569 		// PrintJob not aborted ???
1570 		if ( IsJobActive() )
1571 		{
1572 			mbInPrintPage = sal_True;
1573 			mnCurPage++;
1574             mnCurPrintPage++;
1575 		}
1576 	}
1577 }
1578 
1579 // -----------------------------------------------------------------------
1580 
ImplEndPage()1581 void Printer::ImplEndPage()
1582 {
1583 	if ( !IsJobActive() )
1584 		return;
1585 
1586 	mbInPrintPage = sal_False;
1587 
1588 	if ( mpPrinter )
1589 	{
1590         mpPrinter->EndPage();
1591         ImplReleaseGraphics();
1592         mbDevOutput = sal_False;
1593 
1594 		mpJobGraphics = NULL;
1595 		mbNewJobSetup = sal_False;
1596 	}
1597 }
1598 
1599 // -----------------------------------------------------------------------
1600 
updatePrinters()1601 void Printer::updatePrinters()
1602 {
1603 	ImplSVData* 		pSVData = ImplGetSVData();
1604 	ImplPrnQueueList*	pPrnList = pSVData->maGDIData.mpPrinterQueueList;
1605 
1606 	if ( pPrnList )
1607 	{
1608         ImplPrnQueueList* pNewList = new ImplPrnQueueList;
1609         pSVData->mpDefInst->GetPrinterQueueInfo( pNewList );
1610 
1611         bool bChanged = pPrnList->m_aQueueInfos.size() != pNewList->m_aQueueInfos.size();
1612         for( unsigned int i = 0; ! bChanged && i < pPrnList->m_aQueueInfos.size(); i++ )
1613         {
1614             ImplPrnQueueData& rInfo     = pPrnList->m_aQueueInfos[i];
1615             ImplPrnQueueData& rNewInfo  = pNewList->m_aQueueInfos[i];
1616             if( ! rInfo.mpSalQueueInfo || ! rNewInfo.mpSalQueueInfo || // sanity check
1617                 rInfo.mpSalQueueInfo->maPrinterName != rNewInfo.mpSalQueueInfo->maPrinterName )
1618             {
1619                 bChanged = true;
1620             }
1621 		}
1622         if( bChanged )
1623         {
1624             ImplDeletePrnQueueList();
1625             pSVData->maGDIData.mpPrinterQueueList = pNewList;
1626 
1627             Application* pApp = GetpApp();
1628             if( pApp )
1629             {
1630                 DataChangedEvent aDCEvt( DATACHANGED_PRINTER );
1631                 pApp->DataChanged( aDCEvt );
1632                 pApp->NotifyAllWindows( aDCEvt );
1633             }
1634         }
1635         else
1636             delete pNewList;
1637 	}
1638 }
1639