1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <tools/debug.hxx>
24 #include <tools/resary.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/vcompat.hxx>
28 #include <vcl/unohelp.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/wrkwin.hxx>
31 #include <vcl/virdev.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/gdimtf.hxx>
34 #include <vcl/metaact.hxx>
35 #include <vcl/print.hxx>
37 #include <salinst.hxx>
39 #include <salptype.hxx>
47 #include <comphelper/processfactory.hxx>
49 #include "com/sun/star/beans/XPropertySet.hpp"
50 #include "com/sun/star/configuration/theDefaultProvider.hpp"
51 #include "com/sun/star/container/XNameAccess.hpp"
52 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
54 using namespace com::sun::star::uno
;
55 using namespace com::sun::star::lang
;
56 using namespace com::sun::star::beans
;
57 using namespace com::sun::star::container
;
58 using namespace com::sun::star::configuration
;
60 int nImplSysDialog
= 0;
64 static Paper
ImplGetPaperFormat( long nWidth100thMM
, long nHeight100thMM
)
66 PaperInfo
aInfo(nWidth100thMM
, nHeight100thMM
);
68 return aInfo
.getPaper();
71 static const PaperInfo
& ImplGetEmptyPaper()
73 static PaperInfo
aInfo(PAPER_USER
);
79 void ImplUpdateJobSetupPaper( JobSetup
& rJobSetup
)
81 const ImplJobSetup
* pConstData
= rJobSetup
.ImplGetConstData();
83 if ( !pConstData
->mnPaperWidth
|| !pConstData
->mnPaperHeight
)
85 if ( pConstData
->mePaperFormat
!= PAPER_USER
)
87 ImplJobSetup
* pData
= rJobSetup
.ImplGetData();
88 PaperInfo
aInfo(pConstData
->mePaperFormat
);
89 pData
->mnPaperWidth
= aInfo
.getWidth();
90 pData
->mnPaperHeight
= aInfo
.getHeight();
93 else if ( pConstData
->mePaperFormat
== PAPER_USER
)
95 Paper ePaper
= ImplGetPaperFormat( pConstData
->mnPaperWidth
, pConstData
->mnPaperHeight
);
96 if ( ePaper
!= PAPER_USER
)
97 rJobSetup
.ImplGetData()->mePaperFormat
= ePaper
;
102 PrinterOptions::PrinterOptions() :
103 mbReduceTransparency( sal_False
),
104 meReducedTransparencyMode( PRINTER_TRANSPARENCY_AUTO
),
105 mbReduceGradients( sal_False
),
106 meReducedGradientsMode( PRINTER_GRADIENT_STRIPES
),
107 mnReducedGradientStepCount( 64 ),
108 mbReduceBitmaps( sal_False
),
109 meReducedBitmapMode( PRINTER_BITMAP_NORMAL
),
110 mnReducedBitmapResolution( 200 ),
111 mbReducedBitmapsIncludeTransparency( sal_True
),
112 mbConvertToGreyscales( sal_False
),
113 mbPDFAsStandardPrintJobFormat( sal_False
)
118 PrinterOptions::~PrinterOptions()
122 #define PROPERTYNAME_REDUCETRANSPARENCY OUString("ReduceTransparency")
123 #define PROPERTYNAME_REDUCEDTRANSPARENCYMODE OUString("ReducedTransparencyMode")
124 #define PROPERTYNAME_REDUCEGRADIENTS OUString("ReduceGradients")
125 #define PROPERTYNAME_REDUCEDGRADIENTMODE OUString("ReducedGradientMode")
126 #define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT OUString("ReducedGradientStepCount")
127 #define PROPERTYNAME_REDUCEBITMAPS OUString("ReduceBitmaps")
128 #define PROPERTYNAME_REDUCEDBITMAPMODE OUString("ReducedBitmapMode")
129 #define PROPERTYNAME_REDUCEDBITMAPRESOLUTION OUString("ReducedBitmapResolution")
130 #define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY OUString("ReducedBitmapIncludesTransparency")
131 #define PROPERTYNAME_CONVERTTOGREYSCALES OUString("ConvertToGreyscales")
132 #define PROPERTYNAME_PDFASSTANDARDPRINTJOBFORMAT OUString("PDFAsStandardPrintJobFormat")
134 bool PrinterOptions::ReadFromConfig( bool i_bFile
)
136 bool bSuccess
= false;
137 // save old state in case something goes wrong
138 PrinterOptions
aOldValues( *this );
140 // get the configuration service
141 Reference
< XMultiServiceFactory
> xConfigProvider
;
142 Reference
< XNameAccess
> xConfigAccess
;
145 // get service provider
146 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
147 // create configuration hierachical access name
150 xConfigProvider
= theDefaultProvider::get( xContext
);
152 Sequence
< Any
> aArgs(1);
154 aVal
.Name
= "nodepath";
156 aVal
.Value
<<= OUString( "/org.openoffice.Office.Common/Print/Option/File" );
158 aVal
.Value
<<= OUString( "/org.openoffice.Office.Common/Print/Option/Printer" );
159 aArgs
.getArray()[0] <<= aVal
;
160 xConfigAccess
= Reference
< XNameAccess
>(
161 xConfigProvider
->createInstanceWithArguments(
162 OUString( "com.sun.star.configuration.ConfigurationAccess" ), aArgs
),
164 if( xConfigAccess
.is() )
166 Reference
< XPropertySet
> xSet( xConfigAccess
, UNO_QUERY
);
169 sal_Int32 nValue
= 0;
171 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY
) >>= bValue
)
172 SetReduceTransparency( bValue
);
173 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE
) >>= nValue
)
174 SetReducedTransparencyMode( (PrinterTransparencyMode
)nValue
);
175 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS
) >>= bValue
)
176 SetReduceGradients( bValue
);
177 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE
) >>= nValue
)
178 SetReducedGradientMode( (PrinterGradientMode
)nValue
);
179 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT
) >>= nValue
)
180 SetReducedGradientStepCount( (sal_uInt16
)nValue
);
181 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS
) >>= bValue
)
182 SetReduceBitmaps( bValue
);
183 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE
) >>= nValue
)
184 SetReducedBitmapMode( (PrinterBitmapMode
)nValue
);
185 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION
) >>= nValue
)
186 SetReducedBitmapResolution( (sal_uInt16
)nValue
);
187 if( xSet
->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY
) >>= bValue
)
188 SetReducedBitmapIncludesTransparency( bValue
);
189 if( xSet
->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES
) >>= bValue
)
190 SetConvertToGreyscales( bValue
);
191 if( xSet
->getPropertyValue(PROPERTYNAME_PDFASSTANDARDPRINTJOBFORMAT
) >>= bValue
)
192 SetPDFAsStandardPrintJobFormat( bValue
);
198 catch( const Exception
& )
202 catch( const WrappedTargetException
& )
211 void Printer::SetPrinterOptions( const PrinterOptions
& i_rOptions
)
213 *mpPrinterOptions
= i_rOptions
;
217 QueueInfo::QueueInfo()
224 QueueInfo::QueueInfo( const QueueInfo
& rInfo
) :
225 maPrinterName( rInfo
.maPrinterName
),
226 maDriver( rInfo
.maDriver
),
227 maLocation( rInfo
.maLocation
),
228 maComment( rInfo
.maComment
),
229 mnStatus( rInfo
.mnStatus
),
230 mnJobs( rInfo
.mnJobs
)
235 QueueInfo::~QueueInfo()
240 bool QueueInfo::operator==( const QueueInfo
& rInfo
) const
243 maPrinterName
== rInfo
.maPrinterName
&&
244 maDriver
== rInfo
.maDriver
&&
245 maLocation
== rInfo
.maLocation
&&
246 maComment
== rInfo
.maComment
&&
247 mnStatus
== rInfo
.mnStatus
&&
248 mnJobs
== rInfo
.mnJobs
;
252 SvStream
& operator<<( SvStream
& rOStream
, const QueueInfo
& rInfo
)
254 VersionCompat
aCompat( rOStream
, STREAM_WRITE
, 1 );
256 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rOStream
, rInfo
.maPrinterName
, RTL_TEXTENCODING_UTF8
);
257 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rOStream
, rInfo
.maDriver
, RTL_TEXTENCODING_UTF8
);
258 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rOStream
, rInfo
.maLocation
, RTL_TEXTENCODING_UTF8
);
259 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(rOStream
, rInfo
.maComment
, RTL_TEXTENCODING_UTF8
);
260 rOStream
<< rInfo
.mnStatus
;
261 rOStream
<< rInfo
.mnJobs
;
267 SvStream
& operator>>( SvStream
& rIStream
, QueueInfo
& rInfo
)
269 VersionCompat
aCompat( rIStream
, STREAM_READ
);
271 rInfo
.maPrinterName
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rIStream
, RTL_TEXTENCODING_UTF8
);
272 rInfo
.maDriver
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rIStream
, RTL_TEXTENCODING_UTF8
);
273 rInfo
.maLocation
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rIStream
, RTL_TEXTENCODING_UTF8
);
274 rInfo
.maComment
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(rIStream
, RTL_TEXTENCODING_UTF8
);
275 rIStream
>> rInfo
.mnStatus
;
276 rIStream
>> rInfo
.mnJobs
;
282 SalPrinterQueueInfo::SalPrinterQueueInfo()
285 mnJobs
= QUEUE_JOBS_DONTKNOW
;
290 SalPrinterQueueInfo::~SalPrinterQueueInfo()
295 ImplPrnQueueList::~ImplPrnQueueList()
297 ImplSVData
* pSVData
= ImplGetSVData();
298 for( unsigned int i
= 0; i
< m_aQueueInfos
.size(); i
++ )
300 delete m_aQueueInfos
[i
].mpQueueInfo
;
301 pSVData
->mpDefInst
->DeletePrinterQueueInfo( m_aQueueInfos
[i
].mpSalQueueInfo
);
306 void ImplPrnQueueList::Add( SalPrinterQueueInfo
* pData
)
308 boost::unordered_map
< OUString
, sal_Int32
, OUStringHash
>::iterator it
=
309 m_aNameToIndex
.find( pData
->maPrinterName
);
310 if( it
== m_aNameToIndex
.end() )
312 m_aNameToIndex
[ pData
->maPrinterName
] = m_aQueueInfos
.size();
313 m_aQueueInfos
.push_back( ImplPrnQueueData() );
314 m_aQueueInfos
.back().mpQueueInfo
= NULL
;
315 m_aQueueInfos
.back().mpSalQueueInfo
= pData
;
316 m_aPrinterList
.push_back( pData
->maPrinterName
);
318 else // this should not happen, but ...
320 ImplPrnQueueData
& rData
= m_aQueueInfos
[ it
->second
];
321 delete rData
.mpQueueInfo
;
322 rData
.mpQueueInfo
= NULL
;
323 ImplGetSVData()->mpDefInst
->DeletePrinterQueueInfo( rData
.mpSalQueueInfo
);
324 rData
.mpSalQueueInfo
= pData
;
329 ImplPrnQueueData
* ImplPrnQueueList::Get( const OUString
& rPrinter
)
331 ImplPrnQueueData
* pData
= NULL
;
332 boost::unordered_map
<OUString
,sal_Int32
,OUStringHash
>::iterator it
=
333 m_aNameToIndex
.find( rPrinter
);
334 if( it
!= m_aNameToIndex
.end() )
335 pData
= &m_aQueueInfos
[it
->second
];
340 static void ImplInitPrnQueueList()
342 ImplSVData
* pSVData
= ImplGetSVData();
344 pSVData
->maGDIData
.mpPrinterQueueList
= new ImplPrnQueueList
;
346 static const char* pEnv
= getenv( "SAL_DISABLE_PRINTERLIST" );
347 if( !pEnv
|| !*pEnv
)
348 pSVData
->mpDefInst
->GetPrinterQueueInfo( pSVData
->maGDIData
.mpPrinterQueueList
);
352 void ImplDeletePrnQueueList()
354 ImplSVData
* pSVData
= ImplGetSVData();
355 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
360 pSVData
->maGDIData
.mpPrinterQueueList
= NULL
;
365 const std::vector
<OUString
>& Printer::GetPrinterQueues()
367 ImplSVData
* pSVData
= ImplGetSVData();
368 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
369 ImplInitPrnQueueList();
370 return pSVData
->maGDIData
.mpPrinterQueueList
->m_aPrinterList
;
373 const QueueInfo
* Printer::GetQueueInfo( const OUString
& rPrinterName
, bool bStatusUpdate
)
375 ImplSVData
* pSVData
= ImplGetSVData();
377 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
378 ImplInitPrnQueueList();
380 ImplPrnQueueData
* pInfo
= pSVData
->maGDIData
.mpPrinterQueueList
->Get( rPrinterName
);
383 if( !pInfo
->mpQueueInfo
|| bStatusUpdate
)
384 pSVData
->mpDefInst
->GetPrinterQueueState( pInfo
->mpSalQueueInfo
);
386 if ( !pInfo
->mpQueueInfo
)
387 pInfo
->mpQueueInfo
= new QueueInfo
;
389 pInfo
->mpQueueInfo
->maPrinterName
= pInfo
->mpSalQueueInfo
->maPrinterName
;
390 pInfo
->mpQueueInfo
->maDriver
= pInfo
->mpSalQueueInfo
->maDriver
;
391 pInfo
->mpQueueInfo
->maLocation
= pInfo
->mpSalQueueInfo
->maLocation
;
392 pInfo
->mpQueueInfo
->maComment
= pInfo
->mpSalQueueInfo
->maComment
;
393 pInfo
->mpQueueInfo
->mnStatus
= pInfo
->mpSalQueueInfo
->mnStatus
;
394 pInfo
->mpQueueInfo
->mnJobs
= pInfo
->mpSalQueueInfo
->mnJobs
;
395 return pInfo
->mpQueueInfo
;
401 OUString
Printer::GetDefaultPrinterName()
403 static const char* pEnv
= getenv( "SAL_DISABLE_DEFAULTPRINTER" );
404 if( !pEnv
|| !*pEnv
)
406 ImplSVData
* pSVData
= ImplGetSVData();
408 return pSVData
->mpDefInst
->GetDefaultPrinter();
414 void Printer::ImplInitData()
416 mbDevOutput
= sal_False
;
417 meOutDevType
= OUTDEV_PRINTER
;
418 mbDefPrinter
= sal_False
;
424 mbCollateCopy
= sal_False
;
425 mbPrinting
= sal_False
;
426 mbJobActive
= sal_False
;
427 mbPrintFile
= sal_False
;
428 mbInPrintPage
= sal_False
;
429 mbNewJobSetup
= sal_False
;
430 mpInfoPrinter
= NULL
;
433 mbIsQueuePrinter
= sal_False
;
434 mpPrinterOptions
= new PrinterOptions
;
436 // Add printer to the list
437 ImplSVData
* pSVData
= ImplGetSVData();
438 mpNext
= pSVData
->maGDIData
.mpFirstPrinter
;
441 mpNext
->mpPrev
= this;
443 pSVData
->maGDIData
.mpLastPrinter
= this;
444 pSVData
->maGDIData
.mpFirstPrinter
= this;
448 void Printer::ImplInit( SalPrinterQueueInfo
* pInfo
)
450 ImplSVData
* pSVData
= ImplGetSVData();
451 // #i74084# update info for this specific SalPrinterQueueInfo
452 pSVData
->mpDefInst
->GetPrinterQueueState( pInfo
);
454 // Test whether the driver actually matches the JobSetup
455 ImplJobSetup
* pJobSetup
= maJobSetup
.ImplGetData();
457 if ( pJobSetup
->mpDriverData
)
459 if ( (pJobSetup
->maPrinterName
!= pInfo
->maPrinterName
) ||
460 (pJobSetup
->maDriver
!= pInfo
->maDriver
) )
462 rtl_freeMemory( pJobSetup
->mpDriverData
);
463 pJobSetup
->mpDriverData
= NULL
;
464 pJobSetup
->mnDriverDataLen
= 0;
468 // Remember printer name
469 maPrinterName
= pInfo
->maPrinterName
;
470 maDriver
= pInfo
->maDriver
;
472 // Add printer name to JobSetup
473 pJobSetup
->maPrinterName
= maPrinterName
;
474 pJobSetup
->maDriver
= maDriver
;
476 mpInfoPrinter
= pSVData
->mpDefInst
->CreateInfoPrinter( pInfo
, pJobSetup
);
478 mpJobGraphics
= NULL
;
479 ImplUpdateJobSetupPaper( maJobSetup
);
481 if ( !mpInfoPrinter
)
483 ImplInitDisplay( NULL
);
487 // we need a graphics
488 if ( !ImplGetGraphics() )
490 ImplInitDisplay( NULL
);
495 ImplUpdatePageData();
496 mpFontList
= new ImplDevFontList();
497 mpFontCache
= new ImplFontCache( sal_True
);
498 mpGraphics
->GetDevFontList( mpFontList
);
502 void Printer::ImplInitDisplay( const Window
* pWindow
)
504 ImplSVData
* pSVData
= ImplGetSVData();
506 mpInfoPrinter
= NULL
;
508 mpJobGraphics
= NULL
;
511 mpDisplayDev
= new VirtualDevice( *pWindow
);
513 mpDisplayDev
= new VirtualDevice();
514 mpFontList
= pSVData
->maGDIData
.mpScreenFontList
;
515 mpFontCache
= pSVData
->maGDIData
.mpScreenFontCache
;
516 mnDPIX
= mpDisplayDev
->mnDPIX
;
517 mnDPIY
= mpDisplayDev
->mnDPIY
;
521 SalPrinterQueueInfo
* Printer::ImplGetQueueInfo( const OUString
& rPrinterName
,
522 const OUString
* pDriver
)
524 ImplSVData
* pSVData
= ImplGetSVData();
525 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
526 ImplInitPrnQueueList();
528 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
529 if ( pPrnList
&& pPrnList
->m_aQueueInfos
.size() )
531 // first search for the printer name driectly
532 ImplPrnQueueData
* pInfo
= pPrnList
->Get( rPrinterName
);
534 return pInfo
->mpSalQueueInfo
;
536 // then search case insensitive
537 for( unsigned int i
= 0; i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
539 if( pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
->maPrinterName
.equalsIgnoreAsciiCase( rPrinterName
) )
540 return pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
;
543 // then search for driver name
546 for( unsigned int i
= 0; i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
548 if( pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
->maDriver
== *pDriver
)
549 return pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
;
553 // then the default printer
554 pInfo
= pPrnList
->Get( GetDefaultPrinterName() );
556 return pInfo
->mpSalQueueInfo
;
558 // last chance: the first available printer
559 return pPrnList
->m_aQueueInfos
[0].mpSalQueueInfo
;
566 void Printer::ImplUpdatePageData()
568 // we need a graphics
569 if ( !ImplGetGraphics() )
572 mpGraphics
->GetResolution( mnDPIX
, mnDPIY
);
573 mpInfoPrinter
->GetPageInfo( maJobSetup
.ImplGetConstData(),
574 mnOutWidth
, mnOutHeight
,
575 maPageOffset
.X(), maPageOffset
.Y(),
576 maPaperSize
.Width(), maPaperSize
.Height() );
580 void Printer::ImplUpdateFontList()
582 ImplUpdateFontData( sal_True
);
589 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( GetDefaultPrinterName(), NULL
);
593 if ( !IsDisplayPrinter() )
594 mbDefPrinter
= sal_True
;
597 ImplInitDisplay( NULL
);
601 Printer::Printer( const JobSetup
& rJobSetup
) :
602 maJobSetup( rJobSetup
)
605 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rJobSetup
.mpData
->maPrinterName
,
606 &rJobSetup
.mpData
->maDriver
);
610 SetJobSetup( rJobSetup
);
614 ImplInitDisplay( NULL
);
615 maJobSetup
= JobSetup();
620 Printer::Printer( const QueueInfo
& rQueueInfo
)
623 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rQueueInfo
.GetPrinterName(),
624 &rQueueInfo
.GetDriver() );
628 ImplInitDisplay( NULL
);
632 Printer::Printer( const OUString
& rPrinterName
)
635 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rPrinterName
, NULL
);
639 ImplInitDisplay( NULL
);
645 DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
646 DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
648 delete mpPrinterOptions
;
650 ImplReleaseGraphics();
652 ImplGetSVData()->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
657 // OutputDevice Dtor is tryig the same thing; that why we need to set
658 // the FontEntry to NULL here
659 // TODO: consolidate duplicate cleanup by Printer and OutputDevice
662 mpFontCache
->Release( mpFontEntry
);
665 if ( mpGetDevFontList
)
667 delete mpGetDevFontList
;
668 mpGetDevFontList
= NULL
;
670 if ( mpGetDevSizeList
)
672 delete mpGetDevSizeList
;
673 mpGetDevSizeList
= NULL
;
677 // font list deleted by OutputDevice dtor
680 // Add printer from the list
681 ImplSVData
* pSVData
= ImplGetSVData();
683 mpPrev
->mpNext
= mpNext
;
685 pSVData
->maGDIData
.mpFirstPrinter
= mpNext
;
687 mpNext
->mpPrev
= mpPrev
;
689 pSVData
->maGDIData
.mpLastPrinter
= mpPrev
;
692 sal_uLong
Printer::GetCapabilities( sal_uInt16 nType
) const
694 if ( IsDisplayPrinter() )
698 return mpInfoPrinter
->GetCapabilities( maJobSetup
.ImplGetConstData(), nType
);
704 sal_Bool
Printer::HasSupport( PrinterSupport eFeature
) const
708 case SUPPORT_SET_ORIENTATION
:
709 return (sal_Bool
)GetCapabilities( PRINTER_CAPABILITIES_SETORIENTATION
);
710 case SUPPORT_SET_PAPERBIN
:
711 return (sal_Bool
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERBIN
);
712 case SUPPORT_SET_PAPERSIZE
:
713 return (sal_Bool
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERSIZE
);
714 case SUPPORT_SET_PAPER
:
715 return (sal_Bool
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPER
);
717 return (GetCapabilities( PRINTER_CAPABILITIES_COPIES
) != 0);
718 case SUPPORT_COLLATECOPY
:
719 return (GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES
) != 0);
720 case SUPPORT_SETUPDIALOG
:
721 return (sal_Bool
)GetCapabilities( PRINTER_CAPABILITIES_SUPPORTDIALOG
);
723 return (sal_Bool
) GetCapabilities( PRINTER_CAPABILITIES_FAX
);
725 return (sal_Bool
) GetCapabilities( PRINTER_CAPABILITIES_PDF
);
732 sal_Bool
Printer::SetJobSetup( const JobSetup
& rSetup
)
734 if ( IsDisplayPrinter() || mbInPrintPage
)
737 JobSetup aJobSetup
= rSetup
;
739 ImplReleaseGraphics();
740 if ( mpInfoPrinter
->SetPrinterData( aJobSetup
.ImplGetData() ) )
742 ImplUpdateJobSetupPaper( aJobSetup
);
743 mbNewJobSetup
= sal_True
;
744 maJobSetup
= aJobSetup
;
745 ImplUpdatePageData();
746 ImplUpdateFontList();
755 sal_Bool
Printer::Setup( Window
* pWindow
)
757 if ( IsDisplayPrinter() )
760 if ( IsJobActive() || IsPrinting() )
763 JobSetup aJobSetup
= maJobSetup
;
766 pWindow
= ImplGetDefaultWindow();
770 pFrame
= pWindow
->ImplGetFrame();
771 ImplReleaseGraphics();
772 ImplSVData
* pSVData
= ImplGetSVData();
773 pSVData
->maAppData
.mnModalMode
++;
775 sal_Bool bSetup
= mpInfoPrinter
->Setup( pFrame
, aJobSetup
.ImplGetData() );
776 pSVData
->maAppData
.mnModalMode
--;
780 ImplUpdateJobSetupPaper( aJobSetup
);
781 mbNewJobSetup
= sal_True
;
782 maJobSetup
= aJobSetup
;
783 ImplUpdatePageData();
784 ImplUpdateFontList();
791 sal_Bool
Printer::SetPrinterProps( const Printer
* pPrinter
)
793 if ( IsJobActive() || IsPrinting() )
796 ImplSVData
* pSVData
= ImplGetSVData();
798 mbDefPrinter
= pPrinter
->mbDefPrinter
;
799 maPrintFile
= pPrinter
->maPrintFile
;
800 mbPrintFile
= pPrinter
->mbPrintFile
;
801 mnCopyCount
= pPrinter
->mnCopyCount
;
802 mbCollateCopy
= pPrinter
->mbCollateCopy
;
803 mnPageQueueSize
= pPrinter
->mnPageQueueSize
;
804 *mpPrinterOptions
= *pPrinter
->mpPrinterOptions
;
806 if ( pPrinter
->IsDisplayPrinter() )
808 // Destroy old printer
809 if ( !IsDisplayPrinter() )
811 ImplReleaseGraphics();
812 pSVData
->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
815 mpFontCache
->Release( mpFontEntry
);
818 if ( mpGetDevFontList
)
820 delete mpGetDevFontList
;
821 mpGetDevFontList
= NULL
;
823 if ( mpGetDevSizeList
)
825 delete mpGetDevSizeList
;
826 mpGetDevSizeList
= NULL
;
828 // clean up font list
834 mbInitFont
= sal_True
;
835 mbNewFont
= sal_True
;
836 mpInfoPrinter
= NULL
;
839 // Construct new printer
840 ImplInitDisplay( NULL
);
844 // Destroy old printer?
845 if ( GetName() != pPrinter
->GetName() )
847 ImplReleaseGraphics();
855 pSVData
->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
859 mpFontCache
->Release( mpFontEntry
);
862 if ( mpGetDevFontList
)
864 delete mpGetDevFontList
;
865 mpGetDevFontList
= NULL
;
867 if ( mpGetDevSizeList
)
869 delete mpGetDevSizeList
;
870 mpGetDevSizeList
= NULL
;
876 mbInitFont
= sal_True
;
877 mbNewFont
= sal_True
;
878 mpInfoPrinter
= NULL
;
881 // Construct new printer
882 OUString aDriver
= pPrinter
->GetDriverName();
883 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( pPrinter
->GetName(), &aDriver
);
887 SetJobSetup( pPrinter
->GetJobSetup() );
890 ImplInitDisplay( NULL
);
893 SetJobSetup( pPrinter
->GetJobSetup() );
899 sal_Bool
Printer::SetOrientation( Orientation eOrientation
)
904 if ( maJobSetup
.ImplGetConstData()->meOrientation
!= eOrientation
)
906 JobSetup aJobSetup
= maJobSetup
;
907 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
908 pSetupData
->meOrientation
= eOrientation
;
910 if ( IsDisplayPrinter() )
912 mbNewJobSetup
= sal_True
;
913 maJobSetup
= aJobSetup
;
917 ImplReleaseGraphics();
918 if ( mpInfoPrinter
->SetData( SAL_JOBSET_ORIENTATION
, pSetupData
) )
920 ImplUpdateJobSetupPaper( aJobSetup
);
921 mbNewJobSetup
= sal_True
;
922 maJobSetup
= aJobSetup
;
923 ImplUpdatePageData();
924 ImplUpdateFontList();
935 Orientation
Printer::GetOrientation() const
937 return maJobSetup
.ImplGetConstData()->meOrientation
;
941 sal_Bool
Printer::SetPaperBin( sal_uInt16 nPaperBin
)
946 if ( (maJobSetup
.ImplGetConstData()->mnPaperBin
!= nPaperBin
) &&
947 (nPaperBin
< GetPaperBinCount()) )
949 JobSetup aJobSetup
= maJobSetup
;
950 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
951 pSetupData
->mnPaperBin
= nPaperBin
;
953 if ( IsDisplayPrinter() )
955 mbNewJobSetup
= sal_True
;
956 maJobSetup
= aJobSetup
;
960 ImplReleaseGraphics();
961 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERBIN
, pSetupData
) )
963 ImplUpdateJobSetupPaper( aJobSetup
);
964 mbNewJobSetup
= sal_True
;
965 maJobSetup
= aJobSetup
;
966 ImplUpdatePageData();
967 ImplUpdateFontList();
978 sal_uInt16
Printer::GetPaperBin() const
980 return maJobSetup
.ImplGetConstData()->mnPaperBin
;
984 // Map user paper format to a available printer paper formats
985 void Printer::ImplFindPaperFormatForUserSize( JobSetup
& aJobSetup
, bool bMatchNearest
)
987 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
989 int nLandscapeAngle
= GetLandscapeAngle();
990 int nPaperCount
= GetPaperInfoCount();
993 PaperInfo
aInfo(pSetupData
->mnPaperWidth
, pSetupData
->mnPaperHeight
);
995 // Compare all paper formats and get the appropriate one
996 for ( int i
= 0; i
< nPaperCount
; i
++ )
998 const PaperInfo
& rPaperInfo
= GetPaperInfo( i
);
1000 if ( aInfo
.sloppyEqual(rPaperInfo
) )
1002 pSetupData
->mePaperFormat
= ImplGetPaperFormat( rPaperInfo
.getWidth(),
1003 rPaperInfo
.getHeight() );
1004 pSetupData
->meOrientation
= ORIENTATION_PORTRAIT
;
1010 // If the printer supports landscape orientation, check paper sizes again
1011 // with landscape orientation. This is necessary as a printer driver provides
1012 // all paper sizes with portrait orientation only!!
1013 if ( pSetupData
->mePaperFormat
== PAPER_USER
&&
1014 nLandscapeAngle
!= 0 &&
1015 HasSupport( SUPPORT_SET_ORIENTATION
))
1018 PaperInfo
aRotatedInfo(pSetupData
->mnPaperHeight
, pSetupData
->mnPaperWidth
);
1020 for ( int i
= 0; i
< nPaperCount
; i
++ )
1022 const PaperInfo
& rPaperInfo
= GetPaperInfo( i
);
1024 if ( aRotatedInfo
.sloppyEqual( rPaperInfo
) )
1026 pSetupData
->mePaperFormat
= ImplGetPaperFormat( rPaperInfo
.getWidth(),
1027 rPaperInfo
.getHeight() );
1028 pSetupData
->meOrientation
= ORIENTATION_LANDSCAPE
;
1035 if( ! bFound
&& bMatchNearest
)
1037 sal_Int64 nBestMatch
= SAL_MAX_INT64
;
1039 Orientation eBestOrientation
= ORIENTATION_PORTRAIT
;
1040 for( int i
= 0; i
< nPaperCount
; i
++ )
1042 const PaperInfo
& rPaperInfo
= GetPaperInfo( i
);
1044 // check portrait match
1045 sal_Int64 nDX
= pSetupData
->mnPaperWidth
- rPaperInfo
.getWidth();
1046 sal_Int64 nDY
= pSetupData
->mnPaperHeight
- rPaperInfo
.getHeight();
1047 sal_Int64 nMatch
= nDX
*nDX
+ nDY
*nDY
;
1048 if( nMatch
< nBestMatch
)
1050 nBestMatch
= nMatch
;
1052 eBestOrientation
= ORIENTATION_PORTRAIT
;
1055 // check landscape match
1056 nDX
= pSetupData
->mnPaperWidth
- rPaperInfo
.getHeight();
1057 nDY
= pSetupData
->mnPaperHeight
- rPaperInfo
.getWidth();
1058 nMatch
= nDX
*nDX
+ nDY
*nDY
;
1059 if( nMatch
< nBestMatch
)
1061 nBestMatch
= nMatch
;
1063 eBestOrientation
= ORIENTATION_LANDSCAPE
;
1066 const PaperInfo
& rBestInfo
= GetPaperInfo( nBestIndex
);
1067 pSetupData
->mePaperFormat
= ImplGetPaperFormat( rBestInfo
.getWidth(),
1068 rBestInfo
.getHeight() );
1069 pSetupData
->meOrientation
= eBestOrientation
;
1074 sal_Bool
Printer::SetPaper( Paper ePaper
)
1076 if ( mbInPrintPage
)
1079 if ( maJobSetup
.ImplGetConstData()->mePaperFormat
!= ePaper
)
1081 JobSetup aJobSetup
= maJobSetup
;
1082 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
1083 pSetupData
->mePaperFormat
= ePaper
;
1084 if ( ePaper
!= PAPER_USER
)
1086 PaperInfo
aInfo(ePaper
);
1087 pSetupData
->mnPaperWidth
= aInfo
.getWidth();
1088 pSetupData
->mnPaperHeight
= aInfo
.getHeight();
1091 if ( IsDisplayPrinter() )
1093 mbNewJobSetup
= sal_True
;
1094 maJobSetup
= aJobSetup
;
1098 ImplReleaseGraphics();
1099 if ( ePaper
== PAPER_USER
)
1100 ImplFindPaperFormatForUserSize( aJobSetup
, false );
1101 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERSIZE
|SAL_JOBSET_ORIENTATION
, pSetupData
) )
1103 ImplUpdateJobSetupPaper( aJobSetup
);
1104 mbNewJobSetup
= sal_True
;
1105 maJobSetup
= aJobSetup
;
1106 ImplUpdatePageData();
1107 ImplUpdateFontList();
1118 sal_Bool
Printer::SetPaperSizeUser( const Size
& rSize
)
1120 return SetPaperSizeUser( rSize
, false );
1123 sal_Bool
Printer::SetPaperSizeUser( const Size
& rSize
, bool bMatchNearest
)
1125 if ( mbInPrintPage
)
1128 Size aPixSize
= LogicToPixel( rSize
);
1129 Size aPageSize
= PixelToLogic( aPixSize
, MAP_100TH_MM
);
1130 if ( (maJobSetup
.ImplGetConstData()->mePaperFormat
!= PAPER_USER
) ||
1131 (maJobSetup
.ImplGetConstData()->mnPaperWidth
!= aPageSize
.Width()) ||
1132 (maJobSetup
.ImplGetConstData()->mnPaperHeight
!= aPageSize
.Height()) )
1134 JobSetup aJobSetup
= maJobSetup
;
1135 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
1136 pSetupData
->mePaperFormat
= PAPER_USER
;
1137 pSetupData
->mnPaperWidth
= aPageSize
.Width();
1138 pSetupData
->mnPaperHeight
= aPageSize
.Height();
1140 if ( IsDisplayPrinter() )
1142 mbNewJobSetup
= sal_True
;
1143 maJobSetup
= aJobSetup
;
1147 ImplReleaseGraphics();
1148 ImplFindPaperFormatForUserSize( aJobSetup
, bMatchNearest
);
1150 // Changing the paper size can also change the orientation!
1151 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERSIZE
|SAL_JOBSET_ORIENTATION
, pSetupData
) )
1153 ImplUpdateJobSetupPaper( aJobSetup
);
1154 mbNewJobSetup
= sal_True
;
1155 maJobSetup
= aJobSetup
;
1156 ImplUpdatePageData();
1157 ImplUpdateFontList();
1168 int Printer::GetPaperInfoCount() const
1170 if( ! mpInfoPrinter
)
1172 if( ! mpInfoPrinter
->m_bPapersInit
)
1173 mpInfoPrinter
->InitPaperFormats( maJobSetup
.ImplGetConstData() );
1174 return mpInfoPrinter
->m_aPaperFormats
.size();
1178 OUString
Printer::GetPaperName( Paper ePaper
)
1180 ImplSVData
* pSVData
= ImplGetSVData();
1181 if( ! pSVData
->mpPaperNames
)
1183 pSVData
->mpPaperNames
= new boost::unordered_map
< int, OUString
>();
1184 if( ImplGetResMgr() )
1186 ResStringArray
aPaperStrings( VclResId( RID_STR_PAPERNAMES
) );
1187 static const int PaperIndex
[] =
1189 PAPER_A0
, PAPER_A1
, PAPER_A2
, PAPER_A3
, PAPER_A4
, PAPER_A5
,
1190 PAPER_B4_ISO
, PAPER_B5_ISO
, PAPER_LETTER
, PAPER_LEGAL
, PAPER_TABLOID
,
1191 PAPER_USER
, PAPER_B6_ISO
, PAPER_ENV_C4
, PAPER_ENV_C5
, PAPER_ENV_C6
, PAPER_ENV_C65
,
1192 PAPER_ENV_DL
, PAPER_SLIDE_DIA
, PAPER_C
, PAPER_D
, PAPER_E
,
1193 PAPER_EXECUTIVE
, PAPER_FANFOLD_LEGAL_DE
, PAPER_ENV_MONARCH
, PAPER_ENV_PERSONAL
,
1194 PAPER_ENV_9
, PAPER_ENV_10
, PAPER_ENV_11
, PAPER_ENV_12
, PAPER_KAI16
,
1195 PAPER_KAI32
, PAPER_KAI32BIG
, PAPER_B4_JIS
, PAPER_B5_JIS
, PAPER_B6_JIS
,
1198 OSL_ENSURE( sal_uInt32(SAL_N_ELEMENTS(PaperIndex
)) == aPaperStrings
.Count(), "localized paper name count wrong" );
1199 for( int i
= 0; i
< int(SAL_N_ELEMENTS(PaperIndex
)); i
++ )
1200 (*pSVData
->mpPaperNames
)[PaperIndex
[i
]] = aPaperStrings
.GetString(i
);
1204 boost::unordered_map
<int,OUString
>::const_iterator it
= pSVData
->mpPaperNames
->find( (int)ePaper
);
1205 return (it
!= pSVData
->mpPaperNames
->end()) ? it
->second
: OUString();
1209 OUString
Printer::GetPaperName( bool i_bPaperUser
) const
1211 Size aPageSize
= PixelToLogic( GetPaperSizePixel(), MAP_100TH_MM
);
1212 Paper ePaper
= ImplGetPaperFormat( aPageSize
.Width(), aPageSize
.Height() );
1213 if( ePaper
== PAPER_USER
)
1214 ePaper
= ImplGetPaperFormat( aPageSize
.Height(), aPageSize
.Width() );
1215 return (ePaper
!= PAPER_USER
|| i_bPaperUser
) ? GetPaperName( ePaper
) : OUString();
1219 const PaperInfo
& Printer::GetPaperInfo( int nPaper
) const
1221 if( ! mpInfoPrinter
)
1222 return ImplGetEmptyPaper();
1223 if( ! mpInfoPrinter
->m_bPapersInit
)
1224 mpInfoPrinter
->InitPaperFormats( maJobSetup
.ImplGetConstData() );
1225 if( mpInfoPrinter
->m_aPaperFormats
.empty() || nPaper
< 0 || nPaper
>= int(mpInfoPrinter
->m_aPaperFormats
.size()) )
1226 return ImplGetEmptyPaper();
1227 return mpInfoPrinter
->m_aPaperFormats
[nPaper
];
1231 sal_Bool
Printer::SetDuplexMode( DuplexMode eDuplex
)
1233 if ( mbInPrintPage
)
1236 if ( maJobSetup
.ImplGetConstData()->meDuplexMode
!= eDuplex
)
1238 JobSetup aJobSetup
= maJobSetup
;
1239 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
1240 pSetupData
->meDuplexMode
= eDuplex
;
1242 if ( IsDisplayPrinter() )
1244 mbNewJobSetup
= sal_True
;
1245 maJobSetup
= aJobSetup
;
1249 ImplReleaseGraphics();
1250 if ( mpInfoPrinter
->SetData( SAL_JOBSET_DUPLEXMODE
, pSetupData
) )
1252 ImplUpdateJobSetupPaper( aJobSetup
);
1253 mbNewJobSetup
= sal_True
;
1254 maJobSetup
= aJobSetup
;
1255 ImplUpdatePageData();
1256 ImplUpdateFontList();
1267 int Printer::GetLandscapeAngle() const
1269 return mpInfoPrinter
? mpInfoPrinter
->GetLandscapeAngle( maJobSetup
.ImplGetConstData() ) : 900;
1273 Paper
Printer::GetPaper() const
1275 return maJobSetup
.ImplGetConstData()->mePaperFormat
;
1279 sal_uInt16
Printer::GetPaperBinCount() const
1281 if ( IsDisplayPrinter() )
1284 return (sal_uInt16
)mpInfoPrinter
->GetPaperBinCount( maJobSetup
.ImplGetConstData() );
1288 OUString
Printer::GetPaperBinName( sal_uInt16 nPaperBin
) const
1290 if ( IsDisplayPrinter() )
1293 if ( nPaperBin
< GetPaperBinCount() )
1294 return mpInfoPrinter
->GetPaperBinName( maJobSetup
.ImplGetConstData(), nPaperBin
);
1300 sal_Bool
Printer::SetCopyCount( sal_uInt16 nCopy
, sal_Bool bCollate
)
1302 mnCopyCount
= nCopy
;
1303 mbCollateCopy
= bCollate
;
1308 void Printer::Error()
1310 maErrorHdl
.Call( this );
1315 sal_uLong
Printer::ImplSalPrinterErrorCodeToVCL( sal_uLong nError
)
1317 sal_uLong nVCLError
;
1321 nVCLError
= PRINTER_OK
;
1323 case SAL_PRINTER_ERROR_ABORT
:
1324 nVCLError
= PRINTER_ABORT
;
1327 nVCLError
= PRINTER_GENERALERROR
;
1335 sal_Bool
Printer::EndJob()
1337 sal_Bool bRet
= sal_False
;
1338 if ( !IsJobActive() )
1341 DBG_ASSERT( !mbInPrintPage
, "Printer::EndJob() - StartPage() without EndPage() called" );
1343 mbJobActive
= sal_False
;
1347 ImplReleaseGraphics();
1351 mbPrinting
= sal_False
;
1353 maJobName
= OUString();
1355 mbDevOutput
= sal_False
;
1356 bRet
= mpPrinter
->EndJob();
1357 // FIXME: Do not destroy the printer asynchronously as Win95
1358 // can't handle destroying a printer object and printing
1360 ImplGetSVData()->mpDefInst
->DestroyPrinter( mpPrinter
);
1368 void Printer::ImplStartPage()
1370 if ( !IsJobActive() )
1375 SalGraphics
* pGraphics
= mpPrinter
->StartPage( maJobSetup
.ImplGetConstData(), mbNewJobSetup
);
1378 ImplReleaseGraphics();
1379 mpJobGraphics
= pGraphics
;
1381 mbDevOutput
= sal_True
;
1383 // PrintJob not aborted ???
1384 if ( IsJobActive() )
1386 mbInPrintPage
= sal_True
;
1394 void Printer::ImplEndPage()
1396 if ( !IsJobActive() )
1399 mbInPrintPage
= sal_False
;
1403 mpPrinter
->EndPage();
1404 ImplReleaseGraphics();
1405 mbDevOutput
= sal_False
;
1407 mpJobGraphics
= NULL
;
1408 mbNewJobSetup
= sal_False
;
1413 void Printer::updatePrinters()
1415 ImplSVData
* pSVData
= ImplGetSVData();
1416 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
1420 ImplPrnQueueList
* pNewList
= new ImplPrnQueueList
;
1421 pSVData
->mpDefInst
->GetPrinterQueueInfo( pNewList
);
1423 bool bChanged
= pPrnList
->m_aQueueInfos
.size() != pNewList
->m_aQueueInfos
.size();
1424 for( unsigned int i
= 0; ! bChanged
&& i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
1426 ImplPrnQueueData
& rInfo
= pPrnList
->m_aQueueInfos
[i
];
1427 ImplPrnQueueData
& rNewInfo
= pNewList
->m_aQueueInfos
[i
];
1428 if( ! rInfo
.mpSalQueueInfo
|| ! rNewInfo
.mpSalQueueInfo
|| // sanity check
1429 rInfo
.mpSalQueueInfo
->maPrinterName
!= rNewInfo
.mpSalQueueInfo
->maPrinterName
)
1436 ImplDeletePrnQueueList();
1437 pSVData
->maGDIData
.mpPrinterQueueList
= pNewList
;
1439 Application
* pApp
= GetpApp();
1442 DataChangedEvent
aDCEvt( DATACHANGED_PRINTER
);
1443 pApp
->DataChanged( aDCEvt
);
1444 pApp
->NotifyAllWindows( aDCEvt
);
1452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */