Update ooo320-m1
[ooovba.git] / vcl / source / gdi / print.cxx
blobc9bfa1d328d70c902e7caf7019d8ee36e515c0db
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: print.cxx,v $
10 * $Revision: 1.65 $
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
37 #include <list>
39 #ifndef _SV_SVSYS_HXX
40 #include <svsys.h>
41 #endif
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 // =======================================================================
73 namespace
75 static Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM )
77 PaperInfo aInfo(nWidth100thMM, nHeight100thMM);
78 aInfo.doSloppyFit();
79 return aInfo.getPaper();
82 // -----------------------------------------------------------------------
84 static const PaperInfo& ImplGetEmptyPaper()
86 static PaperInfo aInfo(PAPER_USER);
87 return aInfo;
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()
139 // -------------
140 // - QueueInfo -
141 // -------------
143 QueueInfo::QueueInfo()
145 mnStatus = 0;
146 mnJobs = 0;
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
171 return
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;
193 return rOStream;
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;
209 return rIStream;
212 // =======================================================================
214 SalPrinterQueueInfo::SalPrinterQueueInfo()
216 mnStatus = 0;
217 mnJobs = QUEUE_JOBS_DONTKNOW;
218 mpSysData = NULL;
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];
272 return pData;
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;
293 if ( pPrnList )
295 delete pPrnList;
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 );
319 if( pInfo )
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;
335 return NULL;
338 // -----------------------------------------------------------------------
340 XubString Printer::GetDefaultPrinterName()
342 ImplSVData* pSVData = ImplGetSVData();
344 return pSVData->mpDefInst->GetDefaultPrinter();
347 // =======================================================================
349 void Printer::ImplInitData()
351 mpPrinterData = new ImplPrivatePrinterData();
352 mbDevOutput = FALSE;
353 meOutDevType = OUTDEV_PRINTER;
354 mbDefPrinter = FALSE;
355 mnError = 0;
356 mnCurPage = 0;
357 mnCurPrintPage = 0;
358 mnPageQueueSize = 0;
359 mnCopyCount = 1;
360 mbCollateCopy = FALSE;
361 mbPrinting = FALSE;
362 mbJobActive = FALSE;
363 mbPrintFile = FALSE;
364 mbInPrintPage = FALSE;
365 mbNewJobSetup = FALSE;
366 mpInfoPrinter = NULL;
367 mpPrinter = NULL;
368 mpDisplayDev = NULL;
369 mpQPrinter = NULL;
370 mpQMtf = NULL;
371 mbIsQueuePrinter = FALSE;
372 mpPrinterOptions = new PrinterOptions;
374 // Printer in die Liste eintragen
375 ImplSVData* pSVData = ImplGetSVData();
376 mpNext = pSVData->maGDIData.mpFirstPrinter;
377 mpPrev = NULL;
378 if ( mpNext )
379 mpNext->mpPrev = this;
380 else
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 );
416 mpPrinter = NULL;
417 mpJobPrinter = NULL;
418 mpJobGraphics = NULL;
419 ImplUpdateJobSetupPaper( maJobSetup );
421 if ( !mpInfoPrinter )
423 ImplInitDisplay( NULL );
424 return;
427 // we need a graphics
428 if ( !ImplGetGraphics() )
430 ImplInitDisplay( NULL );
431 return;
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;
448 mpPrinter = NULL;
449 mpJobPrinter = NULL;
450 mpJobGraphics = NULL;
452 if ( pWindow )
453 mpDisplayDev = new VirtualDevice( *pWindow );
454 else
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 );
476 if( pInfo )
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
487 if ( pDriver )
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() );
498 if( pInfo )
499 return pInfo->mpSalQueueInfo;
501 // last chance: the first available printer
502 return pPrnList->m_aQueueInfos[0].mpSalQueueInfo;
505 return NULL;
508 // -----------------------------------------------------------------------
510 void Printer::ImplUpdatePageData()
512 // we need a graphics
513 if ( !ImplGetGraphics() )
514 return;
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 // -----------------------------------------------------------------------
532 Printer::Printer()
534 ImplInitData();
535 SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( GetDefaultPrinterName(), NULL );
536 if ( pInfo )
538 ImplInit( pInfo );
539 if ( !IsDisplayPrinter() )
540 mbDefPrinter = TRUE;
542 else
543 ImplInitDisplay( NULL );
546 // -----------------------------------------------------------------------
548 Printer::Printer( const Window* pWindow )
550 ImplInitData();
551 ImplInitDisplay( pWindow );
554 // -----------------------------------------------------------------------
556 Printer::Printer( const JobSetup& rJobSetup ) :
557 maJobSetup( rJobSetup )
559 ImplInitData();
560 SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rJobSetup.mpData->maPrinterName,
561 &rJobSetup.mpData->maDriver );
562 if ( pInfo )
564 ImplInit( pInfo );
565 SetJobSetup( rJobSetup );
567 else
569 ImplInitDisplay( NULL );
570 maJobSetup = JobSetup();
574 // -----------------------------------------------------------------------
576 Printer::Printer( const QueueInfo& rQueueInfo )
578 ImplInitData();
579 SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rQueueInfo.GetPrinterName(),
580 &rQueueInfo.GetDriver() );
581 if ( pInfo )
582 ImplInit( pInfo );
583 else
584 ImplInitDisplay( NULL );
587 // -----------------------------------------------------------------------
589 Printer::Printer( const XubString& rPrinterName )
591 ImplInitData();
592 SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rPrinterName, NULL );
593 if ( pInfo )
594 ImplInit( pInfo );
595 else
596 ImplInitDisplay( NULL );
599 // -----------------------------------------------------------------------
601 Printer::~Printer()
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();
614 if ( mpInfoPrinter )
615 ImplGetSVData()->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
616 if ( mpDisplayDev )
617 delete mpDisplayDev;
618 else
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
623 if ( mpFontEntry )
625 mpFontCache->Release( mpFontEntry );
626 mpFontEntry = NULL;
628 if ( mpGetDevFontList )
630 delete mpGetDevFontList;
631 mpGetDevFontList = NULL;
633 if ( mpGetDevSizeList )
635 delete mpGetDevSizeList;
636 mpGetDevSizeList = NULL;
638 delete mpFontCache;
639 mpFontCache = NULL;
640 // font list deleted by OutputDevice dtor
643 // Printer aus der Liste eintragen
644 ImplSVData* pSVData = ImplGetSVData();
645 if ( mpPrev )
646 mpPrev->mpNext = mpNext;
647 else
648 pSVData->maGDIData.mpFirstPrinter = mpNext;
649 if ( mpNext )
650 mpNext->mpPrev = mpPrev;
651 else
652 pSVData->maGDIData.mpLastPrinter = mpPrev;
655 // -----------------------------------------------------------------------
656 void Printer::SetNextJobIsQuick( bool bQuick )
658 mpPrinterData->mbNextJobIsQuick = bQuick;
659 if( mpQPrinter )
660 mpQPrinter->SetNextJobIsQuick( bQuick );
663 // -----------------------------------------------------------------------
664 void Printer::Compat_OldPrinterMetrics( bool bSet )
666 // propagate flag
667 if( mpInfoPrinter )
668 mpInfoPrinter->m_bCompatMetrics = bSet;
669 if( mpQPrinter )
670 mpQPrinter->Compat_OldPrinterMetrics( bSet );
672 // get new font data
673 ImplUpdateFontData( TRUE );
676 // -----------------------------------------------------------------------
678 ULONG Printer::GetCapabilities( USHORT nType ) const
680 if ( IsDisplayPrinter() )
681 return FALSE;
683 if( mpInfoPrinter )
684 return mpInfoPrinter->GetCapabilities( maJobSetup.ImplGetConstData(), nType );
685 else
686 return FALSE;
689 // -----------------------------------------------------------------------
691 BOOL Printer::HasSupport( PrinterSupport eFeature ) const
693 switch ( eFeature )
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 );
703 case SUPPORT_COPY:
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 );
709 case SUPPORT_FAX:
710 return (BOOL) GetCapabilities( PRINTER_CAPABILITIES_FAX );
711 case SUPPORT_PDF:
712 return (BOOL) GetCapabilities( PRINTER_CAPABILITIES_PDF );
715 return TRUE;
718 // -----------------------------------------------------------------------
720 BOOL Printer::SetJobSetup( const JobSetup& rSetup )
722 if ( IsDisplayPrinter() || mbInPrintPage )
723 return FALSE;
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();
735 return TRUE;
738 return FALSE;
741 // -----------------------------------------------------------------------
744 BOOL Printer::Setup( Window* pWindow )
746 if ( IsDisplayPrinter() )
747 return FALSE;
749 if ( IsJobActive() || IsPrinting() )
750 return FALSE;
752 JobSetup aJobSetup = maJobSetup;
753 SalFrame* pFrame;
754 if ( !pWindow )
755 pWindow = ImplGetDefaultWindow();
756 if( !pWindow )
757 return FALSE;
759 pFrame = pWindow->ImplGetFrame();
760 ImplReleaseGraphics();
761 ImplSVData* pSVData = ImplGetSVData();
762 pSVData->maAppData.mnModalMode++;
763 nImplSysDialog++;
764 BOOL bSetup = mpInfoPrinter->Setup( pFrame, aJobSetup.ImplGetData() );
765 pSVData->maAppData.mnModalMode--;
766 nImplSysDialog--;
767 if ( bSetup )
769 ImplUpdateJobSetupPaper( aJobSetup );
770 mbNewJobSetup = TRUE;
771 maJobSetup = aJobSetup;
772 ImplUpdatePageData();
773 ImplUpdateFontList();
774 return TRUE;
776 return FALSE;
779 // -----------------------------------------------------------------------
781 BOOL Printer::SetPrinterProps( const Printer* pPrinter )
783 if ( IsJobActive() || IsPrinting() )
784 return FALSE;
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 );
803 if ( mpFontEntry )
805 mpFontCache->Release( mpFontEntry );
806 mpFontEntry = NULL;
808 if ( mpGetDevFontList )
810 delete mpGetDevFontList;
811 mpGetDevFontList = NULL;
813 if ( mpGetDevSizeList )
815 delete mpGetDevSizeList;
816 mpGetDevSizeList = NULL;
818 // clean up font list
819 delete mpFontCache;
820 delete mpFontList;
821 mpFontCache = NULL;
822 mpFontList = NULL;
824 mbInitFont = TRUE;
825 mbNewFont = TRUE;
826 mpInfoPrinter = NULL;
829 // Neuen Printer bauen
830 ImplInitDisplay( NULL );
831 return TRUE;
834 // Alten Printer zerstoeren?
835 if ( GetName() != pPrinter->GetName() )
837 ImplReleaseGraphics();
838 if ( mpDisplayDev )
840 delete mpDisplayDev;
841 mpDisplayDev = NULL;
843 else
845 pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
847 if ( mpFontEntry )
849 mpFontCache->Release( mpFontEntry );
850 mpFontEntry = NULL;
852 if ( mpGetDevFontList )
854 delete mpGetDevFontList;
855 mpGetDevFontList = NULL;
857 if ( mpGetDevSizeList )
859 delete mpGetDevSizeList;
860 mpGetDevSizeList = NULL;
862 delete mpFontCache;
863 delete mpFontList;
864 mpFontCache = NULL;
865 mpFontList = NULL;
866 mbInitFont = TRUE;
867 mbNewFont = TRUE;
868 mpInfoPrinter = NULL;
871 // Neuen Printer bauen
872 XubString aDriver = pPrinter->GetDriverName();
873 SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( pPrinter->GetName(), &aDriver );
874 if ( pInfo )
876 ImplInit( pInfo );
877 SetJobSetup( pPrinter->GetJobSetup() );
879 else
880 ImplInitDisplay( NULL );
882 else
883 SetJobSetup( pPrinter->GetJobSetup() );
885 return FALSE;
888 // -----------------------------------------------------------------------
890 BOOL Printer::SetOrientation( Orientation eOrientation )
892 if ( mbInPrintPage )
893 return FALSE;
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;
905 return TRUE;
908 ImplReleaseGraphics();
909 if ( mpInfoPrinter->SetData( SAL_JOBSET_ORIENTATION, pSetupData ) )
911 ImplUpdateJobSetupPaper( aJobSetup );
912 mbNewJobSetup = TRUE;
913 maJobSetup = aJobSetup;
914 ImplUpdatePageData();
915 ImplUpdateFontList();
916 return TRUE;
918 else
919 return FALSE;
922 return TRUE;
925 // -----------------------------------------------------------------------
927 Orientation Printer::GetOrientation() const
929 return maJobSetup.ImplGetConstData()->meOrientation;
932 // -----------------------------------------------------------------------
934 BOOL Printer::SetPaperBin( USHORT nPaperBin )
936 if ( mbInPrintPage )
937 return FALSE;
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;
950 return TRUE;
953 ImplReleaseGraphics();
954 if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERBIN, pSetupData ) )
956 ImplUpdateJobSetupPaper( aJobSetup );
957 mbNewJobSetup = TRUE;
958 maJobSetup = aJobSetup;
959 ImplUpdatePageData();
960 ImplUpdateFontList();
961 return TRUE;
963 else
964 return FALSE;
967 return TRUE;
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() );
998 break;
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() );
1020 break;
1026 // -----------------------------------------------------------------------
1028 BOOL Printer::SetPaper( Paper ePaper )
1030 if ( mbInPrintPage )
1031 return FALSE;
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;
1049 return TRUE;
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();
1062 return TRUE;
1064 else
1065 return FALSE;
1068 return TRUE;
1071 // -----------------------------------------------------------------------
1073 BOOL Printer::SetPaperSizeUser( const Size& rSize )
1075 if ( mbInPrintPage )
1076 return FALSE;
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;
1094 return TRUE;
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();
1108 return TRUE;
1110 else
1111 return FALSE;
1114 return TRUE;
1117 // -----------------------------------------------------------------------
1119 int Printer::GetPaperInfoCount() const
1121 if( ! mpInfoPrinter )
1122 return 0;
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() )
1167 return 0;
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 );
1181 else
1182 return ImplGetSVEmptyStr();
1185 // -----------------------------------------------------------------------
1187 BOOL Printer::SetCopyCount( USHORT nCopy, BOOL /*bCollate*/ )
1189 mnCopyCount = nCopy;
1190 return TRUE;
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 )
1226 ULONG nVCLError;
1227 switch ( nError )
1229 case 0:
1230 nVCLError = PRINTER_OK;
1231 break;
1232 case SAL_PRINTER_ERROR_ABORT:
1233 nVCLError = PRINTER_ABORT;
1234 break;
1235 default:
1236 nVCLError = PRINTER_GENERALERROR;
1237 break;
1240 return nVCLError;
1243 // -----------------------------------------------------------------------
1245 void Printer::ImplEndPrint()
1247 mbPrinting = FALSE;
1248 mnCurPrintPage = 0;
1249 maJobName.Erase();
1250 if( mpQPrinter ) // not necessarily filled e.g. after AbortJob
1252 mpQPrinter->Destroy();
1253 mpQPrinter = NULL;
1255 EndPrint();
1258 // -----------------------------------------------------------------------
1260 IMPL_LINK( Printer, ImplDestroyPrinterAsync, void*, pSalPrinter )
1262 SalPrinter* pPrinter = (SalPrinter*)pSalPrinter;
1263 ImplSVData* pSVData = ImplGetSVData();
1264 pSVData->mpDefInst->DestroyPrinter( pPrinter );
1265 return 0;
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;
1284 class QuickGuard
1286 Printer* mpPrinter;
1287 public:
1288 QuickGuard( Printer* pPrn ) : mpPrinter( pPrn ) {}
1289 ~QuickGuard()
1291 mpPrinter->ImplUpdateQuickStatus();
1295 BOOL Printer::StartJob( const XubString& rJobName )
1297 mnError = PRINTER_OK;
1299 if ( IsDisplayPrinter() )
1300 return FALSE;
1302 if ( IsJobActive() || IsPrinting() )
1303 return FALSE;
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() )
1321 nCopies = 1;
1322 bCollateCopy = FALSE;
1325 else
1327 if ( nCopies > 1 )
1329 ULONG nDevCopy;
1331 if ( bCollateCopy )
1332 nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
1333 else
1334 nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );
1336 // Muessen Kopien selber gemacht werden?
1337 if ( nCopies > nDevCopy )
1339 bUserCopy = TRUE;
1340 nCopies = 1;
1341 bCollateCopy = FALSE;
1344 else
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 );
1357 if ( !mpPrinter )
1358 return FALSE;
1360 XubString* pPrintFile;
1361 if ( mbPrintFile )
1362 pPrintFile = &maPrintFile;
1363 else
1364 pPrintFile = NULL;
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;
1372 mnCurPage = 1;
1373 mnCurPrintPage = 1;
1374 mbPrinting = TRUE;
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() );
1385 if ( !mnError )
1386 mnError = PRINTER_GENERALERROR;
1387 pSVData->mpDefInst->DestroyPrinter( mpPrinter );
1388 mbNewJobSetup = bSaveNewJobSetup;
1389 maJobName = aSaveJobName;
1390 mnCurPage = 0;
1391 mnCurPrintPage = 0;
1392 mbPrinting = FALSE;
1393 mpPrinter = NULL;
1394 return FALSE;
1398 mbJobActive = TRUE;
1399 StartPrint();
1401 else
1403 mpQPrinter = new ImplQPrinter( this );
1404 if( mpInfoPrinter )
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;
1416 mnCurPage = 1;
1417 mbPrinting = TRUE;
1419 if ( mpQPrinter->StartJob( rJobName ) )
1421 mbJobActive = TRUE;
1422 StartPrint();
1423 mpQPrinter->StartQueuePrint();
1425 else
1427 mbNewJobSetup = bSaveNewJobSetup;
1428 maJobName = aSaveJobName;
1429 mnCurPage = 0;
1430 mbPrinting = FALSE;
1431 mnError = mpQPrinter->GetErrorCode();
1432 mpQPrinter->Destroy();
1433 mpQPrinter = NULL;
1434 return FALSE;
1439 return TRUE;
1442 // -----------------------------------------------------------------------
1444 BOOL Printer::EndJob()
1446 BOOL bRet = FALSE;
1447 if ( !IsJobActive() )
1448 return bRet;
1450 DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
1452 mbJobActive = FALSE;
1454 if ( mpPrinter || mpQPrinter )
1456 ImplReleaseGraphics();
1458 mnCurPage = 0;
1460 bRet = TRUE;
1462 if ( mpPrinter )
1464 mbPrinting = FALSE;
1465 mnCurPrintPage = 0;
1466 maJobName.Erase();
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 );
1474 mpPrinter = NULL;
1475 EndPrint();
1477 else
1478 mpQPrinter->EndQueuePrint();
1481 return bRet;
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() )
1491 return FALSE;
1493 mbJobActive = FALSE;
1494 mbInPrintPage = FALSE;
1495 mpJobGraphics = NULL;
1497 if ( mpPrinter || mpQPrinter )
1499 mbPrinting = FALSE;
1500 mnCurPage = 0;
1501 mnCurPrintPage = 0;
1502 maJobName.Erase();
1504 if ( mpPrinter )
1506 ImplReleaseGraphics();
1507 mbDevOutput = FALSE;
1508 mpPrinter->AbortJob();
1509 Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
1510 mpPrinter = NULL;
1511 EndPrint();
1513 else
1515 mpQPrinter->AbortQueuePrint();
1516 mpQPrinter->Destroy();
1517 mpQPrinter = NULL;
1518 if ( mpQMtf )
1520 mpQMtf->Clear();
1521 delete mpQMtf;
1522 mpQMtf = NULL;
1524 EndPrint();
1527 return TRUE;
1530 return FALSE;
1533 // -----------------------------------------------------------------------
1535 BOOL Printer::StartPage()
1537 if ( !IsJobActive() )
1538 return FALSE;
1540 if ( mpPrinter || mpQPrinter )
1542 if ( mpPrinter )
1544 SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
1545 if ( pGraphics )
1547 ImplReleaseGraphics();
1548 mpJobGraphics = pGraphics;
1550 mbDevOutput = TRUE;
1552 else
1554 ImplGetGraphics();
1555 mpJobGraphics = mpGraphics;
1558 // PrintJob not aborted ???
1559 if ( IsJobActive() )
1561 mbInPrintPage = TRUE;
1562 mnCurPage++;
1563 if ( mpQPrinter )
1565 mpQPrinter->SetPrinterOptions( *mpPrinterOptions );
1566 mpQMtf = new GDIMetaFile;
1567 mpQMtf->Record( this );
1568 mpQMtf->SaveStatus();
1570 else
1572 mnCurPrintPage++;
1573 PrintPage();
1577 return TRUE;
1580 return FALSE;
1583 // -----------------------------------------------------------------------
1585 BOOL Printer::EndPage()
1587 if ( !IsJobActive() )
1588 return FALSE;
1590 mbInPrintPage = FALSE;
1592 if ( mpPrinter || mpQPrinter )
1594 if ( mpPrinter )
1596 mpPrinter->EndPage();
1597 ImplReleaseGraphics();
1598 mbDevOutput = FALSE;
1600 else if ( mpQPrinter )
1602 // Eigentuemeruebergang an QPrinter
1603 mpQMtf->Stop();
1604 mpQMtf->WindStart();
1605 GDIMetaFile* pPage = mpQMtf;
1606 mpQMtf = NULL;
1607 mpQPrinter->AddQueuePage( pPage, mnCurPage, mbNewJobSetup );
1610 mpJobGraphics = NULL;
1611 mbNewJobSetup = FALSE;
1613 return TRUE;
1616 return FALSE;
1619 // -----------------------------------------------------------------------
1621 void Printer::updatePrinters()
1623 ImplSVData* pSVData = ImplGetSVData();
1624 ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
1626 if ( pPrnList )
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 )
1639 bChanged = true;
1642 if( bChanged )
1644 ImplDeletePrnQueueList();
1645 pSVData->maGDIData.mpPrinterQueueList = pNewList;
1647 Application* pApp = GetpApp();
1648 if( pApp )
1650 DataChangedEvent aDCEvt( DATACHANGED_PRINTER );
1651 pApp->DataChanged( aDCEvt );
1652 pApp->NotifyAllWindows( aDCEvt );
1655 else
1656 delete pNewList;