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 hierachical 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 ueberhaupt mit dem JobSetup uebereinstimmt
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 graphics
526 if ( !ImplGetGraphics() )
527 {
528 ImplInitDisplay( NULL );
529 return;
530 }
531
532 // Daten initialisieren
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 driectly
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 zerstoeren
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 zerstoeren?
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 protrait 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 Size aPixSize = LogicToPixel( rSize );
1228 Size aPageSize = PixelToLogic( aPixSize, MAP_100TH_MM );
1229 if ( (maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER) ||
1230 (maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width()) ||
1231 (maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height()) )
1232 {
1233 JobSetup aJobSetup = maJobSetup;
1234 ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1235 pSetupData->mePaperFormat = PAPER_USER;
1236 pSetupData->mnPaperWidth = aPageSize.Width();
1237 pSetupData->mnPaperHeight = aPageSize.Height();
1238
1239 if ( IsDisplayPrinter() )
1240 {
1241 mbNewJobSetup = sal_True;
1242 maJobSetup = aJobSetup;
1243 return sal_True;
1244 }
1245
1246 ImplReleaseGraphics();
1247 ImplFindPaperFormatForUserSize( aJobSetup, bMatchNearest );
1248
1249 // Changing the paper size can also change the orientation!
1250 if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
1251 {
1252 ImplUpdateJobSetupPaper( aJobSetup );
1253 mbNewJobSetup = sal_True;
1254 maJobSetup = aJobSetup;
1255 ImplUpdatePageData();
1256 ImplUpdateFontList();
1257 return sal_True;
1258 }
1259 else
1260 return sal_False;
1261 }
1262
1263 return sal_True;
1264 }
1265
1266 // -----------------------------------------------------------------------
1267
GetPaperInfoCount() const1268 int Printer::GetPaperInfoCount() const
1269 {
1270 if( ! mpInfoPrinter )
1271 return 0;
1272 if( ! mpInfoPrinter->m_bPapersInit )
1273 mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1274 return mpInfoPrinter->m_aPaperFormats.size();
1275 }
1276
1277 // -----------------------------------------------------------------------
1278
GetPaperName(Paper ePaper)1279 rtl::OUString Printer::GetPaperName( Paper ePaper )
1280 {
1281 ImplSVData* pSVData = ImplGetSVData();
1282 if( ! pSVData->mpPaperNames )
1283 {
1284 pSVData->mpPaperNames = new std::hash_map< int, rtl::OUString >();
1285 if( ImplGetResMgr() )
1286 {
1287 ResStringArray aPaperStrings( VclResId( RID_STR_PAPERNAMES ) );
1288 static const int PaperIndex[] =
1289 {
1290 PAPER_A0, PAPER_A1, PAPER_A2, PAPER_A3, PAPER_A4, PAPER_A5,
1291 PAPER_B4_ISO, PAPER_B5_ISO, PAPER_LETTER, PAPER_LEGAL, PAPER_TABLOID,
1292 PAPER_USER, PAPER_B6_ISO, PAPER_ENV_C4, PAPER_ENV_C5, PAPER_ENV_C6, PAPER_ENV_C65,
1293 PAPER_ENV_DL, PAPER_SLIDE_DIA, PAPER_SCREEN, PAPER_C, PAPER_D, PAPER_E,
1294 PAPER_EXECUTIVE, PAPER_FANFOLD_LEGAL_DE, PAPER_ENV_MONARCH, PAPER_ENV_PERSONAL,
1295 PAPER_ENV_9, PAPER_ENV_10, PAPER_ENV_11, PAPER_ENV_12, PAPER_KAI16,
1296 PAPER_KAI32, PAPER_KAI32BIG, PAPER_B4_JIS, PAPER_B5_JIS, PAPER_B6_JIS
1297 };
1298 OSL_ENSURE( sal_uInt32(sizeof(PaperIndex)/sizeof(PaperIndex[0])) == aPaperStrings.Count(), "localized paper name count wrong" );
1299 for( int i = 0; i < int(sizeof(PaperIndex)/sizeof(PaperIndex[0])); i++ )
1300 (*pSVData->mpPaperNames)[PaperIndex[i]] = aPaperStrings.GetString(i);
1301 }
1302 }
1303
1304 std::hash_map<int,rtl::OUString>::const_iterator it = pSVData->mpPaperNames->find( (int)ePaper );
1305 return (it != pSVData->mpPaperNames->end()) ? it->second : rtl::OUString();
1306 }
1307
1308 // -----------------------------------------------------------------------
1309
GetPaperName(bool i_bPaperUser) const1310 rtl::OUString Printer::GetPaperName( bool i_bPaperUser ) const
1311 {
1312 Size aPageSize = PixelToLogic( GetPaperSizePixel(), MAP_100TH_MM );
1313 Paper ePaper = ImplGetPaperFormat( aPageSize.Width(), aPageSize.Height() );
1314 if( ePaper == PAPER_USER )
1315 ePaper = ImplGetPaperFormat( aPageSize.Height(), aPageSize.Width() );
1316 return (ePaper != PAPER_USER || i_bPaperUser ) ? GetPaperName( ePaper ) : rtl::OUString();
1317 }
1318
1319 // -----------------------------------------------------------------------
1320
GetPaperInfo(int nPaper) const1321 const PaperInfo& Printer::GetPaperInfo( int nPaper ) const
1322 {
1323 if( ! mpInfoPrinter )
1324 return ImplGetEmptyPaper();
1325 if( ! mpInfoPrinter->m_bPapersInit )
1326 mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1327 if( mpInfoPrinter->m_aPaperFormats.empty() || nPaper < 0 || nPaper >= int(mpInfoPrinter->m_aPaperFormats.size()) )
1328 return ImplGetEmptyPaper();
1329 return mpInfoPrinter->m_aPaperFormats[nPaper];
1330 }
1331
1332 // -----------------------------------------------------------------------
1333
GetDuplexMode() const1334 DuplexMode Printer::GetDuplexMode() const
1335 {
1336 return maJobSetup.ImplGetConstData()->meDuplexMode;
1337 }
1338
1339 // -----------------------------------------------------------------------
1340
SetDuplexMode(DuplexMode eDuplex)1341 sal_Bool Printer::SetDuplexMode( DuplexMode eDuplex )
1342 {
1343 if ( mbInPrintPage )
1344 return sal_False;
1345
1346 if ( maJobSetup.ImplGetConstData()->meDuplexMode != eDuplex )
1347 {
1348 JobSetup aJobSetup = maJobSetup;
1349 ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1350 pSetupData->meDuplexMode = eDuplex;
1351
1352 if ( IsDisplayPrinter() )
1353 {
1354 mbNewJobSetup = sal_True;
1355 maJobSetup = aJobSetup;
1356 return sal_True;
1357 }
1358
1359 ImplReleaseGraphics();
1360 if ( mpInfoPrinter->SetData( SAL_JOBSET_DUPLEXMODE, pSetupData ) )
1361 {
1362 ImplUpdateJobSetupPaper( aJobSetup );
1363 mbNewJobSetup = sal_True;
1364 maJobSetup = aJobSetup;
1365 ImplUpdatePageData();
1366 ImplUpdateFontList();
1367 return sal_True;
1368 }
1369 else
1370 return sal_False;
1371 }
1372
1373 return sal_True;
1374 }
1375
1376 // -----------------------------------------------------------------------
1377
GetLandscapeAngle() const1378 int Printer::GetLandscapeAngle() const
1379 {
1380 return mpInfoPrinter ? mpInfoPrinter->GetLandscapeAngle( maJobSetup.ImplGetConstData() ) : 900;
1381 }
1382
1383 // -----------------------------------------------------------------------
1384
GetPaper() const1385 Paper Printer::GetPaper() const
1386 {
1387 return maJobSetup.ImplGetConstData()->mePaperFormat;
1388 }
1389
1390 // -----------------------------------------------------------------------
1391
GetPaperBinCount() const1392 sal_uInt16 Printer::GetPaperBinCount() const
1393 {
1394 if ( IsDisplayPrinter() )
1395 return 0;
1396
1397 return (sal_uInt16)mpInfoPrinter->GetPaperBinCount( maJobSetup.ImplGetConstData() );
1398 }
1399
1400 // -----------------------------------------------------------------------
1401
GetPaperBinName(sal_uInt16 nPaperBin) const1402 XubString Printer::GetPaperBinName( sal_uInt16 nPaperBin ) const
1403 {
1404 if ( IsDisplayPrinter() )
1405 return ImplGetSVEmptyStr();
1406
1407 if ( nPaperBin < GetPaperBinCount() )
1408 return mpInfoPrinter->GetPaperBinName( maJobSetup.ImplGetConstData(), nPaperBin );
1409 else
1410 return ImplGetSVEmptyStr();
1411 }
1412
1413 // -----------------------------------------------------------------------
1414
SetCopyCount(sal_uInt16 nCopy,sal_Bool bCollate)1415 sal_Bool Printer::SetCopyCount( sal_uInt16 nCopy, sal_Bool bCollate )
1416 {
1417 mnCopyCount = nCopy;
1418 mbCollateCopy = bCollate;
1419 return sal_True;
1420 }
1421
1422 // -----------------------------------------------------------------------
1423
Error()1424 void Printer::Error()
1425 {
1426 maErrorHdl.Call( this );
1427 }
1428
1429 // -----------------------------------------------------------------------
1430
1431
ImplSalPrinterErrorCodeToVCL(sal_uLong nError)1432 sal_uLong Printer::ImplSalPrinterErrorCodeToVCL( sal_uLong nError )
1433 {
1434 sal_uLong nVCLError;
1435 switch ( nError )
1436 {
1437 case 0:
1438 nVCLError = PRINTER_OK;
1439 break;
1440 case SAL_PRINTER_ERROR_ABORT:
1441 nVCLError = PRINTER_ABORT;
1442 break;
1443 default:
1444 nVCLError = PRINTER_GENERALERROR;
1445 break;
1446 }
1447
1448 return nVCLError;
1449 }
1450
1451 // -----------------------------------------------------------------------
1452
ImplEndPrint()1453 void Printer::ImplEndPrint()
1454 {
1455 mbPrinting = sal_False;
1456 mnCurPrintPage = 0;
1457 maJobName.Erase();
1458 }
1459
1460 // -----------------------------------------------------------------------
1461
IMPL_LINK(Printer,ImplDestroyPrinterAsync,void *,pSalPrinter)1462 IMPL_LINK( Printer, ImplDestroyPrinterAsync, void*, pSalPrinter )
1463 {
1464 SalPrinter* pPrinter = (SalPrinter*)pSalPrinter;
1465 ImplSVData* pSVData = ImplGetSVData();
1466 pSVData->mpDefInst->DestroyPrinter( pPrinter );
1467 return 0;
1468 }
1469
1470 // -----------------------------------------------------------------------
1471
EndJob()1472 sal_Bool Printer::EndJob()
1473 {
1474 sal_Bool bRet = sal_False;
1475 if ( !IsJobActive() )
1476 return bRet;
1477
1478 DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
1479
1480 mbJobActive = sal_False;
1481
1482 if ( mpPrinter )
1483 {
1484 ImplReleaseGraphics();
1485
1486 mnCurPage = 0;
1487
1488 bRet = sal_True;
1489
1490 mbPrinting = sal_False;
1491 mnCurPrintPage = 0;
1492 maJobName.Erase();
1493
1494 mbDevOutput = sal_False;
1495 bRet = mpPrinter->EndJob();
1496 // Hier den Drucker nicht asyncron zerstoeren, da es
1497 // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
1498 // und ein Druckerobjekt zerstoert wird
1499 ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
1500 mpPrinter = NULL;
1501 }
1502
1503 return bRet;
1504 }
1505
1506 // -----------------------------------------------------------------------
1507
AbortJob()1508 sal_Bool Printer::AbortJob()
1509 {
1510 // Wenn wir einen Queue-Printer haben, kann man diesen noch mit
1511 // AbortJob() abbrechen, solange dieser noch am Drucken ist
1512 if ( !IsJobActive() && !IsPrinting() )
1513 return sal_False;
1514
1515 mbJobActive = sal_False;
1516 mbInPrintPage = sal_False;
1517 mpJobGraphics = NULL;
1518
1519 if ( mpPrinter )
1520 {
1521 mbPrinting = sal_False;
1522 mnCurPage = 0;
1523 mnCurPrintPage = 0;
1524 maJobName.Erase();
1525
1526 ImplReleaseGraphics();
1527 mbDevOutput = sal_False;
1528 mpPrinter->AbortJob();
1529 Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
1530 mpPrinter = NULL;
1531
1532 return sal_True;
1533 }
1534
1535 return sal_False;
1536 }
1537
1538 // -----------------------------------------------------------------------
1539
ImplStartPage()1540 void Printer::ImplStartPage()
1541 {
1542 if ( !IsJobActive() )
1543 return;
1544
1545 if ( mpPrinter )
1546 {
1547 SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
1548 if ( pGraphics )
1549 {
1550 ImplReleaseGraphics();
1551 mpJobGraphics = pGraphics;
1552 }
1553 mbDevOutput = sal_True;
1554
1555 // PrintJob not aborted ???
1556 if ( IsJobActive() )
1557 {
1558 mbInPrintPage = sal_True;
1559 mnCurPage++;
1560 mnCurPrintPage++;
1561 }
1562 }
1563 }
1564
1565 // -----------------------------------------------------------------------
1566
ImplEndPage()1567 void Printer::ImplEndPage()
1568 {
1569 if ( !IsJobActive() )
1570 return;
1571
1572 mbInPrintPage = sal_False;
1573
1574 if ( mpPrinter )
1575 {
1576 mpPrinter->EndPage();
1577 ImplReleaseGraphics();
1578 mbDevOutput = sal_False;
1579
1580 mpJobGraphics = NULL;
1581 mbNewJobSetup = sal_False;
1582 }
1583 }
1584
1585 // -----------------------------------------------------------------------
1586
updatePrinters()1587 void Printer::updatePrinters()
1588 {
1589 ImplSVData* pSVData = ImplGetSVData();
1590 ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
1591
1592 if ( pPrnList )
1593 {
1594 ImplPrnQueueList* pNewList = new ImplPrnQueueList;
1595 pSVData->mpDefInst->GetPrinterQueueInfo( pNewList );
1596
1597 bool bChanged = pPrnList->m_aQueueInfos.size() != pNewList->m_aQueueInfos.size();
1598 for( unsigned int i = 0; ! bChanged && i < pPrnList->m_aQueueInfos.size(); i++ )
1599 {
1600 ImplPrnQueueData& rInfo = pPrnList->m_aQueueInfos[i];
1601 ImplPrnQueueData& rNewInfo = pNewList->m_aQueueInfos[i];
1602 if( ! rInfo.mpSalQueueInfo || ! rNewInfo.mpSalQueueInfo || // sanity check
1603 rInfo.mpSalQueueInfo->maPrinterName != rNewInfo.mpSalQueueInfo->maPrinterName )
1604 {
1605 bChanged = true;
1606 }
1607 }
1608 if( bChanged )
1609 {
1610 ImplDeletePrnQueueList();
1611 pSVData->maGDIData.mpPrinterQueueList = pNewList;
1612
1613 Application* pApp = GetpApp();
1614 if( pApp )
1615 {
1616 DataChangedEvent aDCEvt( DATACHANGED_PRINTER );
1617 pApp->DataChanged( aDCEvt );
1618 pApp->NotifyAllWindows( aDCEvt );
1619 }
1620 }
1621 else
1622 delete pNewList;
1623 }
1624 }
1625