1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: print.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #define _SPOOLPRINTER_EXT
35 #define _RMPRINTER_EXT
36 #define ENABLE_BYTESTRING_STREAM_OPERATORS
42 #include <vcl/salinst.hxx>
43 #include <vcl/salgdi.hxx>
44 #include <vcl/salptype.hxx>
45 #include <vcl/salprn.hxx>
47 #include <vcl/unohelp.hxx>
48 #include <tools/debug.hxx>
49 #include <tools/stream.hxx>
50 #include <tools/vcompat.hxx>
51 #include <vcl/svdata.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/wrkwin.hxx>
54 #include <vcl/jobset.h>
55 #include <vcl/outdev.h>
56 #include <vcl/virdev.hxx>
57 #include <vcl/window.hxx>
58 #include <vcl/print.h>
59 #include <vcl/gdimtf.hxx>
60 #include <vcl/metaact.hxx>
61 #include <vcl/impprn.hxx>
62 #include <vcl/print.hxx>
64 #include <comphelper/processfactory.hxx>
66 using namespace com::sun::star::uno
;
67 using namespace com::sun::star::lang
;
69 int nImplSysDialog
= 0;
71 // =======================================================================
75 static Paper
ImplGetPaperFormat( long nWidth100thMM
, long nHeight100thMM
)
77 PaperInfo
aInfo(nWidth100thMM
, nHeight100thMM
);
79 return aInfo
.getPaper();
82 // -----------------------------------------------------------------------
84 static const PaperInfo
& ImplGetEmptyPaper()
86 static PaperInfo
aInfo(PAPER_USER
);
91 // =======================================================================
93 void ImplUpdateJobSetupPaper( JobSetup
& rJobSetup
)
95 const ImplJobSetup
* pConstData
= rJobSetup
.ImplGetConstData();
97 if ( !pConstData
->mnPaperWidth
|| !pConstData
->mnPaperHeight
)
99 if ( pConstData
->mePaperFormat
!= PAPER_USER
)
101 ImplJobSetup
* pData
= rJobSetup
.ImplGetData();
102 PaperInfo
aInfo(pConstData
->mePaperFormat
);
103 pData
->mnPaperWidth
= aInfo
.getWidth();
104 pData
->mnPaperHeight
= aInfo
.getHeight();
107 else if ( pConstData
->mePaperFormat
== PAPER_USER
)
109 Paper ePaper
= ImplGetPaperFormat( pConstData
->mnPaperWidth
, pConstData
->mnPaperHeight
);
110 if ( ePaper
!= PAPER_USER
)
111 rJobSetup
.ImplGetData()->mePaperFormat
= ePaper
;
115 // ------------------
116 // - PrinterOptions -
117 // ------------------
119 PrinterOptions::PrinterOptions() :
120 mbReduceTransparency( FALSE
),
121 meReducedTransparencyMode( PRINTER_TRANSPARENCY_AUTO
),
122 mbReduceGradients( FALSE
),
123 meReducedGradientsMode( PRINTER_GRADIENT_STRIPES
),
124 mnReducedGradientStepCount( 64 ),
125 mbReduceBitmaps( FALSE
),
126 meReducedBitmapMode( PRINTER_BITMAP_NORMAL
),
127 mnReducedBitmapResolution( 200 ),
128 mbReducedBitmapsIncludeTransparency( TRUE
),
129 mbConvertToGreyscales( FALSE
)
133 // -----------------------------------------------------------------------
135 PrinterOptions::~PrinterOptions()
143 QueueInfo::QueueInfo()
149 // -----------------------------------------------------------------------
151 QueueInfo::QueueInfo( const QueueInfo
& rInfo
) :
152 maPrinterName( rInfo
.maPrinterName
),
153 maDriver( rInfo
.maDriver
),
154 maLocation( rInfo
.maLocation
),
155 maComment( rInfo
.maComment
),
156 mnStatus( rInfo
.mnStatus
),
157 mnJobs( rInfo
.mnJobs
)
161 // -----------------------------------------------------------------------
163 QueueInfo::~QueueInfo()
167 // -----------------------------------------------------------------------
169 bool QueueInfo::operator==( const QueueInfo
& rInfo
) const
172 maPrinterName
== rInfo
.maPrinterName
&&
173 maDriver
== rInfo
.maDriver
&&
174 maLocation
== rInfo
.maLocation
&&
175 maComment
== rInfo
.maComment
&&
176 mnStatus
== rInfo
.mnStatus
&&
177 mnJobs
== rInfo
.mnJobs
;
180 // -----------------------------------------------------------------------
182 SvStream
& operator<<( SvStream
& rOStream
, const QueueInfo
& rInfo
)
184 VersionCompat
aCompat( rOStream
, STREAM_WRITE
, 1 );
186 rOStream
.WriteByteString( rInfo
.maPrinterName
, RTL_TEXTENCODING_UTF8
);
187 rOStream
.WriteByteString( rInfo
.maDriver
, RTL_TEXTENCODING_UTF8
);
188 rOStream
.WriteByteString( rInfo
.maLocation
, RTL_TEXTENCODING_UTF8
);
189 rOStream
.WriteByteString( rInfo
.maComment
, RTL_TEXTENCODING_UTF8
);
190 rOStream
<< rInfo
.mnStatus
;
191 rOStream
<< rInfo
.mnJobs
;
196 // -----------------------------------------------------------------------
198 SvStream
& operator>>( SvStream
& rIStream
, QueueInfo
& rInfo
)
200 VersionCompat
aCompat( rIStream
, STREAM_READ
);
202 rIStream
.ReadByteString( rInfo
.maPrinterName
, RTL_TEXTENCODING_UTF8
);
203 rIStream
.ReadByteString( rInfo
.maDriver
, RTL_TEXTENCODING_UTF8
);
204 rIStream
.ReadByteString( rInfo
.maLocation
, RTL_TEXTENCODING_UTF8
);
205 rIStream
.ReadByteString( rInfo
.maComment
, RTL_TEXTENCODING_UTF8
);
206 rIStream
>> rInfo
.mnStatus
;
207 rIStream
>> rInfo
.mnJobs
;
212 // =======================================================================
214 SalPrinterQueueInfo::SalPrinterQueueInfo()
217 mnJobs
= QUEUE_JOBS_DONTKNOW
;
221 // -----------------------------------------------------------------------
223 SalPrinterQueueInfo::~SalPrinterQueueInfo()
227 // -----------------------------------------------------------------------
229 ImplPrnQueueList::~ImplPrnQueueList()
231 ImplSVData
* pSVData
= ImplGetSVData();
232 for( unsigned int i
= 0; i
< m_aQueueInfos
.size(); i
++ )
234 delete m_aQueueInfos
[i
].mpQueueInfo
;
235 pSVData
->mpDefInst
->DeletePrinterQueueInfo( m_aQueueInfos
[i
].mpSalQueueInfo
);
239 // -----------------------------------------------------------------------
241 void ImplPrnQueueList::Add( SalPrinterQueueInfo
* pData
)
243 std::hash_map
< rtl::OUString
, sal_Int32
, rtl::OUStringHash
>::iterator it
=
244 m_aNameToIndex
.find( pData
->maPrinterName
);
245 if( it
== m_aNameToIndex
.end() )
247 m_aNameToIndex
[ pData
->maPrinterName
] = m_aQueueInfos
.size();
248 m_aQueueInfos
.push_back( ImplPrnQueueData() );
249 m_aQueueInfos
.back().mpQueueInfo
= NULL
;
250 m_aQueueInfos
.back().mpSalQueueInfo
= pData
;
251 m_aPrinterList
.push_back( pData
->maPrinterName
);
253 else // this should not happen, but ...
255 ImplPrnQueueData
& rData
= m_aQueueInfos
[ it
->second
];
256 delete rData
.mpQueueInfo
;
257 rData
.mpQueueInfo
= NULL
;
258 ImplGetSVData()->mpDefInst
->DeletePrinterQueueInfo( rData
.mpSalQueueInfo
);
259 rData
.mpSalQueueInfo
= pData
;
263 // -----------------------------------------------------------------------
265 ImplPrnQueueData
* ImplPrnQueueList::Get( const rtl::OUString
& rPrinter
)
267 ImplPrnQueueData
* pData
= NULL
;
268 std::hash_map
<rtl::OUString
,sal_Int32
,rtl::OUStringHash
>::iterator it
=
269 m_aNameToIndex
.find( rPrinter
);
270 if( it
!= m_aNameToIndex
.end() )
271 pData
= &m_aQueueInfos
[it
->second
];
275 // =======================================================================
277 static void ImplInitPrnQueueList()
279 ImplSVData
* pSVData
= ImplGetSVData();
281 pSVData
->maGDIData
.mpPrinterQueueList
= new ImplPrnQueueList
;
283 pSVData
->mpDefInst
->GetPrinterQueueInfo( pSVData
->maGDIData
.mpPrinterQueueList
);
286 // -----------------------------------------------------------------------
288 void ImplDeletePrnQueueList()
290 ImplSVData
* pSVData
= ImplGetSVData();
291 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
296 pSVData
->maGDIData
.mpPrinterQueueList
= NULL
;
300 // -----------------------------------------------------------------------
302 const std::vector
<rtl::OUString
>& Printer::GetPrinterQueues()
304 ImplSVData
* pSVData
= ImplGetSVData();
305 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
306 ImplInitPrnQueueList();
307 return pSVData
->maGDIData
.mpPrinterQueueList
->m_aPrinterList
;
310 // -----------------------------------------------------------------------
311 const QueueInfo
* Printer::GetQueueInfo( const String
& rPrinterName
, bool bStatusUpdate
)
313 ImplSVData
* pSVData
= ImplGetSVData();
315 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
316 ImplInitPrnQueueList();
318 ImplPrnQueueData
* pInfo
= pSVData
->maGDIData
.mpPrinterQueueList
->Get( rPrinterName
);
321 if( !pInfo
->mpQueueInfo
|| bStatusUpdate
)
322 pSVData
->mpDefInst
->GetPrinterQueueState( pInfo
->mpSalQueueInfo
);
324 if ( !pInfo
->mpQueueInfo
)
325 pInfo
->mpQueueInfo
= new QueueInfo
;
327 pInfo
->mpQueueInfo
->maPrinterName
= pInfo
->mpSalQueueInfo
->maPrinterName
;
328 pInfo
->mpQueueInfo
->maDriver
= pInfo
->mpSalQueueInfo
->maDriver
;
329 pInfo
->mpQueueInfo
->maLocation
= pInfo
->mpSalQueueInfo
->maLocation
;
330 pInfo
->mpQueueInfo
->maComment
= pInfo
->mpSalQueueInfo
->maComment
;
331 pInfo
->mpQueueInfo
->mnStatus
= pInfo
->mpSalQueueInfo
->mnStatus
;
332 pInfo
->mpQueueInfo
->mnJobs
= pInfo
->mpSalQueueInfo
->mnJobs
;
333 return pInfo
->mpQueueInfo
;
338 // -----------------------------------------------------------------------
340 XubString
Printer::GetDefaultPrinterName()
342 ImplSVData
* pSVData
= ImplGetSVData();
344 return pSVData
->mpDefInst
->GetDefaultPrinter();
347 // =======================================================================
349 void Printer::ImplInitData()
351 mpPrinterData
= new ImplPrivatePrinterData();
353 meOutDevType
= OUTDEV_PRINTER
;
354 mbDefPrinter
= FALSE
;
360 mbCollateCopy
= FALSE
;
364 mbInPrintPage
= FALSE
;
365 mbNewJobSetup
= FALSE
;
366 mpInfoPrinter
= NULL
;
371 mbIsQueuePrinter
= FALSE
;
372 mpPrinterOptions
= new PrinterOptions
;
374 // Printer in die Liste eintragen
375 ImplSVData
* pSVData
= ImplGetSVData();
376 mpNext
= pSVData
->maGDIData
.mpFirstPrinter
;
379 mpNext
->mpPrev
= this;
381 pSVData
->maGDIData
.mpLastPrinter
= this;
382 pSVData
->maGDIData
.mpFirstPrinter
= this;
385 // -----------------------------------------------------------------------
387 void Printer::ImplInit( SalPrinterQueueInfo
* pInfo
)
389 ImplSVData
* pSVData
= ImplGetSVData();
390 // #i74084# update info for this specific SalPrinterQueueInfo
391 pSVData
->mpDefInst
->GetPrinterQueueState( pInfo
);
393 // Testen, ob Treiber ueberhaupt mit dem JobSetup uebereinstimmt
394 ImplJobSetup
* pJobSetup
= maJobSetup
.ImplGetData();
396 if ( pJobSetup
->mpDriverData
)
398 if ( (pJobSetup
->maPrinterName
!= pInfo
->maPrinterName
) ||
399 (pJobSetup
->maDriver
!= pInfo
->maDriver
) )
401 rtl_freeMemory( pJobSetup
->mpDriverData
);
402 pJobSetup
->mpDriverData
= NULL
;
403 pJobSetup
->mnDriverDataLen
= 0;
407 // Printernamen merken
408 maPrinterName
= pInfo
->maPrinterName
;
409 maDriver
= pInfo
->maDriver
;
411 // In JobSetup den Printernamen eintragen
412 pJobSetup
->maPrinterName
= maPrinterName
;
413 pJobSetup
->maDriver
= maDriver
;
415 mpInfoPrinter
= pSVData
->mpDefInst
->CreateInfoPrinter( pInfo
, pJobSetup
);
418 mpJobGraphics
= NULL
;
419 ImplUpdateJobSetupPaper( maJobSetup
);
421 if ( !mpInfoPrinter
)
423 ImplInitDisplay( NULL
);
427 // we need a graphics
428 if ( !ImplGetGraphics() )
430 ImplInitDisplay( NULL
);
434 // Daten initialisieren
435 ImplUpdatePageData();
436 mpFontList
= new ImplDevFontList();
437 mpFontCache
= new ImplFontCache( TRUE
);
438 mpGraphics
->GetDevFontList( mpFontList
);
441 // -----------------------------------------------------------------------
443 void Printer::ImplInitDisplay( const Window
* pWindow
)
445 ImplSVData
* pSVData
= ImplGetSVData();
447 mpInfoPrinter
= NULL
;
450 mpJobGraphics
= NULL
;
453 mpDisplayDev
= new VirtualDevice( *pWindow
);
455 mpDisplayDev
= new VirtualDevice();
456 mpFontList
= pSVData
->maGDIData
.mpScreenFontList
;
457 mpFontCache
= pSVData
->maGDIData
.mpScreenFontCache
;
458 mnDPIX
= mpDisplayDev
->mnDPIX
;
459 mnDPIY
= mpDisplayDev
->mnDPIY
;
462 // -----------------------------------------------------------------------
464 SalPrinterQueueInfo
* Printer::ImplGetQueueInfo( const XubString
& rPrinterName
,
465 const XubString
* pDriver
)
467 ImplSVData
* pSVData
= ImplGetSVData();
468 if ( !pSVData
->maGDIData
.mpPrinterQueueList
)
469 ImplInitPrnQueueList();
471 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
472 if ( pPrnList
&& pPrnList
->m_aQueueInfos
.size() )
474 // first search for the printer name driectly
475 ImplPrnQueueData
* pInfo
= pPrnList
->Get( rPrinterName
);
477 return pInfo
->mpSalQueueInfo
;
479 // then search case insensitive
480 for( unsigned int i
= 0; i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
482 if( pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
->maPrinterName
.EqualsIgnoreCaseAscii( rPrinterName
) )
483 return pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
;
486 // then search for driver name
489 for( unsigned int i
= 0; i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
491 if( pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
->maDriver
== *pDriver
)
492 return pPrnList
->m_aQueueInfos
[i
].mpSalQueueInfo
;
496 // then the default printer
497 pInfo
= pPrnList
->Get( GetDefaultPrinterName() );
499 return pInfo
->mpSalQueueInfo
;
501 // last chance: the first available printer
502 return pPrnList
->m_aQueueInfos
[0].mpSalQueueInfo
;
508 // -----------------------------------------------------------------------
510 void Printer::ImplUpdatePageData()
512 // we need a graphics
513 if ( !ImplGetGraphics() )
516 mpGraphics
->GetResolution( mnDPIX
, mnDPIY
);
517 mpInfoPrinter
->GetPageInfo( maJobSetup
.ImplGetConstData(),
518 mnOutWidth
, mnOutHeight
,
519 maPageOffset
.X(), maPageOffset
.Y(),
520 maPaperSize
.Width(), maPaperSize
.Height() );
523 // -----------------------------------------------------------------------
525 void Printer::ImplUpdateFontList()
527 ImplUpdateFontData( TRUE
);
530 // -----------------------------------------------------------------------
535 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( GetDefaultPrinterName(), NULL
);
539 if ( !IsDisplayPrinter() )
543 ImplInitDisplay( NULL
);
546 // -----------------------------------------------------------------------
548 Printer::Printer( const Window
* pWindow
)
551 ImplInitDisplay( pWindow
);
554 // -----------------------------------------------------------------------
556 Printer::Printer( const JobSetup
& rJobSetup
) :
557 maJobSetup( rJobSetup
)
560 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rJobSetup
.mpData
->maPrinterName
,
561 &rJobSetup
.mpData
->maDriver
);
565 SetJobSetup( rJobSetup
);
569 ImplInitDisplay( NULL
);
570 maJobSetup
= JobSetup();
574 // -----------------------------------------------------------------------
576 Printer::Printer( const QueueInfo
& rQueueInfo
)
579 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rQueueInfo
.GetPrinterName(),
580 &rQueueInfo
.GetDriver() );
584 ImplInitDisplay( NULL
);
587 // -----------------------------------------------------------------------
589 Printer::Printer( const XubString
& rPrinterName
)
592 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( rPrinterName
, NULL
);
596 ImplInitDisplay( NULL
);
599 // -----------------------------------------------------------------------
603 DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
604 DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
605 DBG_ASSERT( !mpQPrinter
, "Printer::~Printer() - QueuePrinter not destroyed" );
606 DBG_ASSERT( !mpQMtf
, "Printer::~Printer() - QueueMetafile not destroyed" );
608 delete mpPrinterData
;
609 mpPrinterData
= NULL
;
611 delete mpPrinterOptions
;
613 ImplReleaseGraphics();
615 ImplGetSVData()->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
620 // OutputDevice-Dtor versucht das gleiche, deshalb muss hier
621 // der FontEntry auch auf NULL gesetzt werden
622 // TODO: consolidate duplicate cleanup by Printer and OutputDevice
625 mpFontCache
->Release( mpFontEntry
);
628 if ( mpGetDevFontList
)
630 delete mpGetDevFontList
;
631 mpGetDevFontList
= NULL
;
633 if ( mpGetDevSizeList
)
635 delete mpGetDevSizeList
;
636 mpGetDevSizeList
= NULL
;
640 // font list deleted by OutputDevice dtor
643 // Printer aus der Liste eintragen
644 ImplSVData
* pSVData
= ImplGetSVData();
646 mpPrev
->mpNext
= mpNext
;
648 pSVData
->maGDIData
.mpFirstPrinter
= mpNext
;
650 mpNext
->mpPrev
= mpPrev
;
652 pSVData
->maGDIData
.mpLastPrinter
= mpPrev
;
655 // -----------------------------------------------------------------------
656 void Printer::SetNextJobIsQuick( bool bQuick
)
658 mpPrinterData
->mbNextJobIsQuick
= bQuick
;
660 mpQPrinter
->SetNextJobIsQuick( bQuick
);
663 // -----------------------------------------------------------------------
664 void Printer::Compat_OldPrinterMetrics( bool bSet
)
668 mpInfoPrinter
->m_bCompatMetrics
= bSet
;
670 mpQPrinter
->Compat_OldPrinterMetrics( bSet
);
673 ImplUpdateFontData( TRUE
);
676 // -----------------------------------------------------------------------
678 ULONG
Printer::GetCapabilities( USHORT nType
) const
680 if ( IsDisplayPrinter() )
684 return mpInfoPrinter
->GetCapabilities( maJobSetup
.ImplGetConstData(), nType
);
689 // -----------------------------------------------------------------------
691 BOOL
Printer::HasSupport( PrinterSupport eFeature
) const
695 case SUPPORT_SET_ORIENTATION
:
696 return (BOOL
)GetCapabilities( PRINTER_CAPABILITIES_SETORIENTATION
);
697 case SUPPORT_SET_PAPERBIN
:
698 return (BOOL
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERBIN
);
699 case SUPPORT_SET_PAPERSIZE
:
700 return (BOOL
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPERSIZE
);
701 case SUPPORT_SET_PAPER
:
702 return (BOOL
)GetCapabilities( PRINTER_CAPABILITIES_SETPAPER
);
704 return (GetCapabilities( PRINTER_CAPABILITIES_COPIES
) != 0);
705 case SUPPORT_COLLATECOPY
:
706 return (GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES
) != 0);
707 case SUPPORT_SETUPDIALOG
:
708 return (BOOL
)GetCapabilities( PRINTER_CAPABILITIES_SUPPORTDIALOG
);
710 return (BOOL
) GetCapabilities( PRINTER_CAPABILITIES_FAX
);
712 return (BOOL
) GetCapabilities( PRINTER_CAPABILITIES_PDF
);
718 // -----------------------------------------------------------------------
720 BOOL
Printer::SetJobSetup( const JobSetup
& rSetup
)
722 if ( IsDisplayPrinter() || mbInPrintPage
)
725 JobSetup aJobSetup
= rSetup
;
727 ImplReleaseGraphics();
728 if ( mpInfoPrinter
->SetPrinterData( aJobSetup
.ImplGetData() ) )
730 ImplUpdateJobSetupPaper( aJobSetup
);
731 mbNewJobSetup
= TRUE
;
732 maJobSetup
= aJobSetup
;
733 ImplUpdatePageData();
734 ImplUpdateFontList();
741 // -----------------------------------------------------------------------
744 BOOL
Printer::Setup( Window
* pWindow
)
746 if ( IsDisplayPrinter() )
749 if ( IsJobActive() || IsPrinting() )
752 JobSetup aJobSetup
= maJobSetup
;
755 pWindow
= ImplGetDefaultWindow();
759 pFrame
= pWindow
->ImplGetFrame();
760 ImplReleaseGraphics();
761 ImplSVData
* pSVData
= ImplGetSVData();
762 pSVData
->maAppData
.mnModalMode
++;
764 BOOL bSetup
= mpInfoPrinter
->Setup( pFrame
, aJobSetup
.ImplGetData() );
765 pSVData
->maAppData
.mnModalMode
--;
769 ImplUpdateJobSetupPaper( aJobSetup
);
770 mbNewJobSetup
= TRUE
;
771 maJobSetup
= aJobSetup
;
772 ImplUpdatePageData();
773 ImplUpdateFontList();
779 // -----------------------------------------------------------------------
781 BOOL
Printer::SetPrinterProps( const Printer
* pPrinter
)
783 if ( IsJobActive() || IsPrinting() )
786 ImplSVData
* pSVData
= ImplGetSVData();
788 mbDefPrinter
= pPrinter
->mbDefPrinter
;
789 maPrintFile
= pPrinter
->maPrintFile
;
790 mbPrintFile
= pPrinter
->mbPrintFile
;
791 mnCopyCount
= pPrinter
->mnCopyCount
;
792 mbCollateCopy
= pPrinter
->mbCollateCopy
;
793 mnPageQueueSize
= pPrinter
->mnPageQueueSize
;
794 *mpPrinterOptions
= *pPrinter
->mpPrinterOptions
;
796 if ( pPrinter
->IsDisplayPrinter() )
798 // Alten Printer zerstoeren
799 if ( !IsDisplayPrinter() )
801 ImplReleaseGraphics();
802 pSVData
->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
805 mpFontCache
->Release( mpFontEntry
);
808 if ( mpGetDevFontList
)
810 delete mpGetDevFontList
;
811 mpGetDevFontList
= NULL
;
813 if ( mpGetDevSizeList
)
815 delete mpGetDevSizeList
;
816 mpGetDevSizeList
= NULL
;
818 // clean up font list
826 mpInfoPrinter
= NULL
;
829 // Neuen Printer bauen
830 ImplInitDisplay( NULL
);
834 // Alten Printer zerstoeren?
835 if ( GetName() != pPrinter
->GetName() )
837 ImplReleaseGraphics();
845 pSVData
->mpDefInst
->DestroyInfoPrinter( mpInfoPrinter
);
849 mpFontCache
->Release( mpFontEntry
);
852 if ( mpGetDevFontList
)
854 delete mpGetDevFontList
;
855 mpGetDevFontList
= NULL
;
857 if ( mpGetDevSizeList
)
859 delete mpGetDevSizeList
;
860 mpGetDevSizeList
= NULL
;
868 mpInfoPrinter
= NULL
;
871 // Neuen Printer bauen
872 XubString aDriver
= pPrinter
->GetDriverName();
873 SalPrinterQueueInfo
* pInfo
= ImplGetQueueInfo( pPrinter
->GetName(), &aDriver
);
877 SetJobSetup( pPrinter
->GetJobSetup() );
880 ImplInitDisplay( NULL
);
883 SetJobSetup( pPrinter
->GetJobSetup() );
888 // -----------------------------------------------------------------------
890 BOOL
Printer::SetOrientation( Orientation eOrientation
)
895 if ( maJobSetup
.ImplGetConstData()->meOrientation
!= eOrientation
)
897 JobSetup aJobSetup
= maJobSetup
;
898 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
899 pSetupData
->meOrientation
= eOrientation
;
901 if ( IsDisplayPrinter() )
903 mbNewJobSetup
= TRUE
;
904 maJobSetup
= aJobSetup
;
908 ImplReleaseGraphics();
909 if ( mpInfoPrinter
->SetData( SAL_JOBSET_ORIENTATION
, pSetupData
) )
911 ImplUpdateJobSetupPaper( aJobSetup
);
912 mbNewJobSetup
= TRUE
;
913 maJobSetup
= aJobSetup
;
914 ImplUpdatePageData();
915 ImplUpdateFontList();
925 // -----------------------------------------------------------------------
927 Orientation
Printer::GetOrientation() const
929 return maJobSetup
.ImplGetConstData()->meOrientation
;
932 // -----------------------------------------------------------------------
934 BOOL
Printer::SetPaperBin( USHORT nPaperBin
)
939 if ( (maJobSetup
.ImplGetConstData()->mnPaperBin
!= nPaperBin
) &&
940 (nPaperBin
< GetPaperBinCount()) )
942 JobSetup aJobSetup
= maJobSetup
;
943 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
944 pSetupData
->mnPaperBin
= nPaperBin
;
946 if ( IsDisplayPrinter() )
948 mbNewJobSetup
= TRUE
;
949 maJobSetup
= aJobSetup
;
953 ImplReleaseGraphics();
954 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERBIN
, pSetupData
) )
956 ImplUpdateJobSetupPaper( aJobSetup
);
957 mbNewJobSetup
= TRUE
;
958 maJobSetup
= aJobSetup
;
959 ImplUpdatePageData();
960 ImplUpdateFontList();
970 // -----------------------------------------------------------------------
972 USHORT
Printer::GetPaperBin() const
974 return maJobSetup
.ImplGetConstData()->mnPaperBin
;
977 // -----------------------------------------------------------------------
979 // Map user paper format to a available printer paper formats
980 void Printer::ImplFindPaperFormatForUserSize( JobSetup
& aJobSetup
)
982 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
984 int nLandscapeAngle
= GetLandscapeAngle();
985 int nPaperCount
= GetPaperInfoCount();
987 PaperInfo
aInfo(pSetupData
->mnPaperWidth
, pSetupData
->mnPaperHeight
);
989 // Alle Papierformate vergleichen und ein passendes raussuchen
990 for ( int i
= 0; i
< nPaperCount
; i
++ )
992 const PaperInfo
& rPaperInfo
= GetPaperInfo( i
);
994 if ( aInfo
.sloppyEqual(rPaperInfo
) )
996 pSetupData
->mePaperFormat
= ImplGetPaperFormat( rPaperInfo
.getWidth(),
997 rPaperInfo
.getHeight() );
1002 // If the printer supports landscape orientation, check paper sizes again
1003 // with landscape orientation. This is necessary as a printer driver provides
1004 // all paper sizes with portrait orientation only!!
1005 if ( pSetupData
->mePaperFormat
== PAPER_USER
&&
1006 nLandscapeAngle
!= 0 &&
1007 HasSupport( SUPPORT_SET_ORIENTATION
))
1010 PaperInfo
aRotatedInfo(pSetupData
->mnPaperHeight
, pSetupData
->mnPaperWidth
);
1012 for ( int i
= 0; i
< nPaperCount
; i
++ )
1014 const PaperInfo
& rPaperInfo
= GetPaperInfo( i
);
1016 if ( aRotatedInfo
.sloppyEqual( rPaperInfo
) )
1018 pSetupData
->mePaperFormat
= ImplGetPaperFormat( rPaperInfo
.getWidth(),
1019 rPaperInfo
.getHeight() );
1026 // -----------------------------------------------------------------------
1028 BOOL
Printer::SetPaper( Paper ePaper
)
1030 if ( mbInPrintPage
)
1033 if ( maJobSetup
.ImplGetConstData()->mePaperFormat
!= ePaper
)
1035 JobSetup aJobSetup
= maJobSetup
;
1036 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
1037 pSetupData
->mePaperFormat
= ePaper
;
1038 if ( ePaper
!= PAPER_USER
)
1040 PaperInfo
aInfo(ePaper
);
1041 pSetupData
->mnPaperWidth
= aInfo
.getWidth();
1042 pSetupData
->mnPaperHeight
= aInfo
.getHeight();
1045 if ( IsDisplayPrinter() )
1047 mbNewJobSetup
= TRUE
;
1048 maJobSetup
= aJobSetup
;
1052 ImplReleaseGraphics();
1053 if ( ePaper
== PAPER_USER
)
1054 ImplFindPaperFormatForUserSize( aJobSetup
);
1055 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERSIZE
|SAL_JOBSET_ORIENTATION
, pSetupData
) )
1057 ImplUpdateJobSetupPaper( aJobSetup
);
1058 mbNewJobSetup
= TRUE
;
1059 maJobSetup
= aJobSetup
;
1060 ImplUpdatePageData();
1061 ImplUpdateFontList();
1071 // -----------------------------------------------------------------------
1073 BOOL
Printer::SetPaperSizeUser( const Size
& rSize
)
1075 if ( mbInPrintPage
)
1078 Size aPixSize
= LogicToPixel( rSize
);
1079 Size aPageSize
= PixelToLogic( aPixSize
, MAP_100TH_MM
);
1080 if ( (maJobSetup
.ImplGetConstData()->mePaperFormat
!= PAPER_USER
) ||
1081 (maJobSetup
.ImplGetConstData()->mnPaperWidth
!= aPageSize
.Width()) ||
1082 (maJobSetup
.ImplGetConstData()->mnPaperHeight
!= aPageSize
.Height()) )
1084 JobSetup aJobSetup
= maJobSetup
;
1085 ImplJobSetup
* pSetupData
= aJobSetup
.ImplGetData();
1086 pSetupData
->mePaperFormat
= PAPER_USER
;
1087 pSetupData
->mnPaperWidth
= aPageSize
.Width();
1088 pSetupData
->mnPaperHeight
= aPageSize
.Height();
1090 if ( IsDisplayPrinter() )
1092 mbNewJobSetup
= TRUE
;
1093 maJobSetup
= aJobSetup
;
1097 ImplReleaseGraphics();
1098 ImplFindPaperFormatForUserSize( aJobSetup
);
1100 // Changing the paper size can also change the orientation!
1101 if ( mpInfoPrinter
->SetData( SAL_JOBSET_PAPERSIZE
|SAL_JOBSET_ORIENTATION
, pSetupData
) )
1103 ImplUpdateJobSetupPaper( aJobSetup
);
1104 mbNewJobSetup
= TRUE
;
1105 maJobSetup
= aJobSetup
;
1106 ImplUpdatePageData();
1107 ImplUpdateFontList();
1117 // -----------------------------------------------------------------------
1119 int Printer::GetPaperInfoCount() const
1121 if( ! mpInfoPrinter
)
1123 if( ! mpInfoPrinter
->m_bPapersInit
)
1124 mpInfoPrinter
->InitPaperFormats( maJobSetup
.ImplGetConstData() );
1125 return mpInfoPrinter
->m_aPaperFormats
.size();
1128 // -----------------------------------------------------------------------
1130 const PaperInfo
& Printer::GetPaperInfo( int nPaper
) const
1132 if( ! mpInfoPrinter
)
1133 return ImplGetEmptyPaper();
1134 if( ! mpInfoPrinter
->m_bPapersInit
)
1135 mpInfoPrinter
->InitPaperFormats( maJobSetup
.ImplGetConstData() );
1136 if( mpInfoPrinter
->m_aPaperFormats
.empty() || nPaper
< 0 || nPaper
>= int(mpInfoPrinter
->m_aPaperFormats
.size()) )
1137 return ImplGetEmptyPaper();
1138 return mpInfoPrinter
->m_aPaperFormats
[nPaper
];
1141 // -----------------------------------------------------------------------
1143 DuplexMode
Printer::GetDuplexMode() const
1145 return mpInfoPrinter
? mpInfoPrinter
->GetDuplexMode( maJobSetup
.ImplGetConstData() ) : DUPLEX_UNKNOWN
;
1148 // -----------------------------------------------------------------------
1150 int Printer::GetLandscapeAngle() const
1152 return mpInfoPrinter
? mpInfoPrinter
->GetLandscapeAngle( maJobSetup
.ImplGetConstData() ) : 900;
1155 // -----------------------------------------------------------------------
1157 Paper
Printer::GetPaper() const
1159 return maJobSetup
.ImplGetConstData()->mePaperFormat
;
1162 // -----------------------------------------------------------------------
1164 USHORT
Printer::GetPaperBinCount() const
1166 if ( IsDisplayPrinter() )
1169 return (USHORT
)mpInfoPrinter
->GetPaperBinCount( maJobSetup
.ImplGetConstData() );
1172 // -----------------------------------------------------------------------
1174 XubString
Printer::GetPaperBinName( USHORT nPaperBin
) const
1176 if ( IsDisplayPrinter() )
1177 return ImplGetSVEmptyStr();
1179 if ( nPaperBin
< GetPaperBinCount() )
1180 return mpInfoPrinter
->GetPaperBinName( maJobSetup
.ImplGetConstData(), nPaperBin
);
1182 return ImplGetSVEmptyStr();
1185 // -----------------------------------------------------------------------
1187 BOOL
Printer::SetCopyCount( USHORT nCopy
, BOOL
/*bCollate*/ )
1189 mnCopyCount
= nCopy
;
1193 // -----------------------------------------------------------------------
1195 void Printer::Error()
1197 maErrorHdl
.Call( this );
1200 // -----------------------------------------------------------------------
1202 void Printer::StartPrint()
1204 maStartPrintHdl
.Call( this );
1207 // -----------------------------------------------------------------------
1209 void Printer::EndPrint()
1211 maEndPrintHdl
.Call( this );
1214 // -----------------------------------------------------------------------
1216 void Printer::PrintPage()
1218 maPrintPageHdl
.Call( this );
1221 // -----------------------------------------------------------------------
1224 ULONG
ImplSalPrinterErrorCodeToVCL( ULONG nError
)
1230 nVCLError
= PRINTER_OK
;
1232 case SAL_PRINTER_ERROR_ABORT
:
1233 nVCLError
= PRINTER_ABORT
;
1236 nVCLError
= PRINTER_GENERALERROR
;
1243 // -----------------------------------------------------------------------
1245 void Printer::ImplEndPrint()
1250 if( mpQPrinter
) // not necessarily filled e.g. after AbortJob
1252 mpQPrinter
->Destroy();
1258 // -----------------------------------------------------------------------
1260 IMPL_LINK( Printer
, ImplDestroyPrinterAsync
, void*, pSalPrinter
)
1262 SalPrinter
* pPrinter
= (SalPrinter
*)pSalPrinter
;
1263 ImplSVData
* pSVData
= ImplGetSVData();
1264 pSVData
->mpDefInst
->DestroyPrinter( pPrinter
);
1268 // -----------------------------------------------------------------------
1270 void Printer::ImplUpdateQuickStatus()
1272 // remove possibly added "IsQuickJob"
1273 if( mpPrinterData
->mbNextJobIsQuick
)
1275 rtl::OUString
aKey( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) );
1276 // const data means not really const, but change all references
1277 // to refcounted job setup
1278 ImplJobSetup
* pImpSetup
= maJobSetup
.ImplGetConstData();
1279 pImpSetup
->maValueMap
.erase( aKey
);
1280 mpPrinterData
->mbNextJobIsQuick
= false;
1288 QuickGuard( Printer
* pPrn
) : mpPrinter( pPrn
) {}
1291 mpPrinter
->ImplUpdateQuickStatus();
1295 BOOL
Printer::StartJob( const XubString
& rJobName
)
1297 mnError
= PRINTER_OK
;
1299 if ( IsDisplayPrinter() )
1302 if ( IsJobActive() || IsPrinting() )
1305 if( mpPrinterData
->mbNextJobIsQuick
)
1307 String
aKey( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) );
1308 if( maJobSetup
.GetValue( aKey
).Len() == 0 )
1309 maJobSetup
.SetValue( aKey
, String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
1312 QuickGuard
aQGuard( this );
1314 ULONG nCopies
= mnCopyCount
;
1315 BOOL bCollateCopy
= mbCollateCopy
;
1316 BOOL bUserCopy
= FALSE
;
1317 if ( IsQueuePrinter() )
1319 if ( ((ImplQPrinter
*)this)->IsUserCopy() )
1322 bCollateCopy
= FALSE
;
1332 nDevCopy
= GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES
);
1334 nDevCopy
= GetCapabilities( PRINTER_CAPABILITIES_COPIES
);
1336 // Muessen Kopien selber gemacht werden?
1337 if ( nCopies
> nDevCopy
)
1341 bCollateCopy
= FALSE
;
1345 bCollateCopy
= FALSE
;
1347 // we need queue printing
1348 if( !mnPageQueueSize
)
1349 mnPageQueueSize
= 1;
1352 if ( !mnPageQueueSize
)
1354 ImplSVData
* pSVData
= ImplGetSVData();
1355 mpPrinter
= pSVData
->mpDefInst
->CreatePrinter( mpInfoPrinter
);
1360 XubString
* pPrintFile
;
1362 pPrintFile
= &maPrintFile
;
1366 // #125075# StartJob can Reschedule on Windows, sfx
1367 // depends on IsPrinting() in case of closing a document
1368 BOOL bSaveNewJobSetup
= mbNewJobSetup
;
1369 mbNewJobSetup
= FALSE
;
1370 String aSaveJobName
= maJobName
;
1371 maJobName
= rJobName
;
1376 if( ! ImplGetSVData()->maGDIData
.mbPrinterPullModel
)
1378 // in the pull model the job can only be started when
1379 // we have collected all pages to be printed
1380 if ( !mpPrinter
->StartJob( pPrintFile
, rJobName
, Application::GetDisplayName(),
1381 nCopies
, bCollateCopy
,
1382 maJobSetup
.ImplGetConstData() ) )
1384 mnError
= ImplSalPrinterErrorCodeToVCL( mpPrinter
->GetErrorCode() );
1386 mnError
= PRINTER_GENERALERROR
;
1387 pSVData
->mpDefInst
->DestroyPrinter( mpPrinter
);
1388 mbNewJobSetup
= bSaveNewJobSetup
;
1389 maJobName
= aSaveJobName
;
1403 mpQPrinter
= new ImplQPrinter( this );
1405 mpQPrinter
->Compat_OldPrinterMetrics( mpInfoPrinter
->m_bCompatMetrics
);
1406 mpQPrinter
->SetDigitLanguage( GetDigitLanguage() );
1407 mpQPrinter
->SetUserCopy( bUserCopy
);
1408 mpQPrinter
->SetPrinterOptions( *mpPrinterOptions
);
1410 // #125075# StartJob can Reschedule on Windows, sfx
1411 // depends on IsPrinting() in case of closing a document
1412 BOOL bSaveNewJobSetup
= mbNewJobSetup
;
1413 mbNewJobSetup
= FALSE
;
1414 String aSaveJobName
= maJobName
;
1415 maJobName
= rJobName
;
1419 if ( mpQPrinter
->StartJob( rJobName
) )
1423 mpQPrinter
->StartQueuePrint();
1427 mbNewJobSetup
= bSaveNewJobSetup
;
1428 maJobName
= aSaveJobName
;
1431 mnError
= mpQPrinter
->GetErrorCode();
1432 mpQPrinter
->Destroy();
1442 // -----------------------------------------------------------------------
1444 BOOL
Printer::EndJob()
1447 if ( !IsJobActive() )
1450 DBG_ASSERT( !mbInPrintPage
, "Printer::EndJob() - StartPage() without EndPage() called" );
1452 mbJobActive
= FALSE
;
1454 if ( mpPrinter
|| mpQPrinter
)
1456 ImplReleaseGraphics();
1468 mbDevOutput
= FALSE
;
1469 bRet
= mpPrinter
->EndJob();
1470 // Hier den Drucker nicht asyncron zerstoeren, da es
1471 // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
1472 // und ein Druckerobjekt zerstoert wird
1473 ImplGetSVData()->mpDefInst
->DestroyPrinter( mpPrinter
);
1478 mpQPrinter
->EndQueuePrint();
1484 // -----------------------------------------------------------------------
1486 BOOL
Printer::AbortJob()
1488 // Wenn wir einen Queue-Printer haben, kann man diesen noch mit
1489 // AbortJob() abbrechen, solange dieser noch am Drucken ist
1490 if ( !IsJobActive() && !IsPrinting() )
1493 mbJobActive
= FALSE
;
1494 mbInPrintPage
= FALSE
;
1495 mpJobGraphics
= NULL
;
1497 if ( mpPrinter
|| mpQPrinter
)
1506 ImplReleaseGraphics();
1507 mbDevOutput
= FALSE
;
1508 mpPrinter
->AbortJob();
1509 Application::PostUserEvent( LINK( this, Printer
, ImplDestroyPrinterAsync
), mpPrinter
);
1515 mpQPrinter
->AbortQueuePrint();
1516 mpQPrinter
->Destroy();
1533 // -----------------------------------------------------------------------
1535 BOOL
Printer::StartPage()
1537 if ( !IsJobActive() )
1540 if ( mpPrinter
|| mpQPrinter
)
1544 SalGraphics
* pGraphics
= mpPrinter
->StartPage( maJobSetup
.ImplGetConstData(), mbNewJobSetup
);
1547 ImplReleaseGraphics();
1548 mpJobGraphics
= pGraphics
;
1555 mpJobGraphics
= mpGraphics
;
1558 // PrintJob not aborted ???
1559 if ( IsJobActive() )
1561 mbInPrintPage
= TRUE
;
1565 mpQPrinter
->SetPrinterOptions( *mpPrinterOptions
);
1566 mpQMtf
= new GDIMetaFile
;
1567 mpQMtf
->Record( this );
1568 mpQMtf
->SaveStatus();
1583 // -----------------------------------------------------------------------
1585 BOOL
Printer::EndPage()
1587 if ( !IsJobActive() )
1590 mbInPrintPage
= FALSE
;
1592 if ( mpPrinter
|| mpQPrinter
)
1596 mpPrinter
->EndPage();
1597 ImplReleaseGraphics();
1598 mbDevOutput
= FALSE
;
1600 else if ( mpQPrinter
)
1602 // Eigentuemeruebergang an QPrinter
1604 mpQMtf
->WindStart();
1605 GDIMetaFile
* pPage
= mpQMtf
;
1607 mpQPrinter
->AddQueuePage( pPage
, mnCurPage
, mbNewJobSetup
);
1610 mpJobGraphics
= NULL
;
1611 mbNewJobSetup
= FALSE
;
1619 // -----------------------------------------------------------------------
1621 void Printer::updatePrinters()
1623 ImplSVData
* pSVData
= ImplGetSVData();
1624 ImplPrnQueueList
* pPrnList
= pSVData
->maGDIData
.mpPrinterQueueList
;
1628 ImplPrnQueueList
* pNewList
= new ImplPrnQueueList
;
1629 pSVData
->mpDefInst
->GetPrinterQueueInfo( pNewList
);
1631 bool bChanged
= pPrnList
->m_aQueueInfos
.size() != pNewList
->m_aQueueInfos
.size();
1632 for( unsigned int i
= 0; ! bChanged
&& i
< pPrnList
->m_aQueueInfos
.size(); i
++ )
1634 ImplPrnQueueData
& rInfo
= pPrnList
->m_aQueueInfos
[i
];
1635 ImplPrnQueueData
& rNewInfo
= pNewList
->m_aQueueInfos
[i
];
1636 if( ! rInfo
.mpSalQueueInfo
|| ! rNewInfo
.mpSalQueueInfo
|| // sanity check
1637 rInfo
.mpSalQueueInfo
->maPrinterName
!= rNewInfo
.mpSalQueueInfo
->maPrinterName
)
1644 ImplDeletePrnQueueList();
1645 pSVData
->maGDIData
.mpPrinterQueueList
= pNewList
;
1647 Application
* pApp
= GetpApp();
1650 DataChangedEvent
aDCEvt( DATACHANGED_PRINTER
);
1651 pApp
->DataChanged( aDCEvt
);
1652 pApp
->NotifyAllWindows( aDCEvt
);