LCOV - code coverage report
Current view: top level - vcl/generic/print - genprnpsp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 106 659 16.1 %
Date: 2012-08-25 Functions: 8 55 14.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 97 1081 9.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : /**
      31                 :            :   this file implements the sal printer interface ( SalPrinter, SalInfoPrinter
      32                 :            :   and some printer relevant methods of SalInstance and SalGraphicsData )
      33                 :            : 
      34                 :            :   as aunderlying library the printer features of psprint are used.
      35                 :            : 
      36                 :            :   The query methods of a SalInfoPrinter are implemented by querying psprint
      37                 :            : 
      38                 :            :   The job methods of a SalPrinter are implemented by calling psprint
      39                 :            :   printer job functions.
      40                 :            :  */
      41                 :            : 
      42                 :            : // For spawning PDF and FAX generation
      43                 :            : #if defined( UNX )
      44                 :            : #  include <unistd.h>
      45                 :            : #  include <sys/wait.h>
      46                 :            : #  include <sys/stat.h>
      47                 :            : #endif
      48                 :            : 
      49                 :            : #include "rtl/ustring.hxx"
      50                 :            : 
      51                 :            : #include "osl/module.h"
      52                 :            : 
      53                 :            : #include "vcl/svapp.hxx"
      54                 :            : #include "vcl/print.hxx"
      55                 :            : #include "vcl/pdfwriter.hxx"
      56                 :            : #include "vcl/printerinfomanager.hxx"
      57                 :            : 
      58                 :            : #include "saldatabasic.hxx"
      59                 :            : #include "generic/genprn.h"
      60                 :            : #include "generic/geninst.h"
      61                 :            : #include "generic/genpspgraphics.h"
      62                 :            : 
      63                 :            : #include "jobset.h"
      64                 :            : #include "print.h"
      65                 :            : #include "salptype.hxx"
      66                 :            : 
      67                 :            : #include <com/sun/star/beans/PropertyValue.hpp>
      68                 :            : 
      69                 :            : using namespace psp;
      70                 :            : using namespace com::sun::star;
      71                 :            : 
      72                 :            : using ::rtl::OUString;
      73                 :            : using ::rtl::OUStringHash;
      74                 :            : using ::rtl::OUStringToOString;
      75                 :            : 
      76                 :            : /*
      77                 :            :  *  static helpers
      78                 :            :  */
      79                 :            : 
      80                 :            : static oslModule driverLib                  = NULL;
      81                 :            : extern "C"
      82                 :            : {
      83                 :            : typedef int(*setupFunction)(PrinterInfo&);
      84                 :            : static setupFunction pSetupFunction         = NULL;
      85                 :            : typedef int(*faxFunction)(OUString&);
      86                 :            : static faxFunction pFaxNrFunction           = NULL;
      87                 :            : }
      88                 :            : 
      89                 :          0 : static rtl::OUString getPdfDir( const PrinterInfo& rInfo )
      90                 :            : {
      91                 :          0 :     rtl::OUString aDir;
      92                 :          0 :     sal_Int32 nIndex = 0;
      93         [ #  # ]:          0 :     while( nIndex != -1 )
      94                 :            :     {
      95                 :          0 :         rtl::OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) );
      96         [ #  # ]:          0 :         if( ! aToken.compareToAscii( "pdf=", 4 ) )
      97                 :            :         {
      98                 :          0 :             sal_Int32 nPos = 0;
      99                 :          0 :             aDir = aToken.getToken( 1, '=', nPos );
     100 [ #  # ][ #  # ]:          0 :             if( aDir.isEmpty() && getenv( "HOME" ) )
                 [ #  # ]
     101 [ #  # ][ #  # ]:          0 :                 aDir = rtl::OUString( getenv( "HOME" ), strlen( getenv( "HOME" ) ), osl_getThreadTextEncoding() );
     102                 :            :             break;
     103                 :            :         }
     104         [ #  # ]:          0 :     }
     105                 :          0 :     return aDir;
     106                 :            : }
     107                 :            : 
     108                 :          0 : static void getPaLib()
     109                 :            : {
     110                 :            : #if defined( UNX ) && !( defined( QUARTZ ) || defined( IOS ) )
     111         [ #  # ]:          0 :     if( ! driverLib )
     112                 :            :     {
     113         [ #  # ]:          0 :         OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( _XSALSET_LIBNAME ) );
     114         [ #  # ]:          0 :         driverLib   = osl_loadModuleRelative( (oslGenericFunction)getPaLib, aLibName.pData, SAL_LOADMODULE_DEFAULT );
     115         [ #  # ]:          0 :         if ( !driverLib )
     116                 :            :         {
     117                 :          0 :             return;
     118                 :            :         }
     119                 :            : 
     120         [ #  # ]:          0 :         pSetupFunction  = (setupFunction)osl_getAsciiFunctionSymbol( driverLib, "Sal_SetupPrinterDriver" );
     121         [ #  # ]:          0 :         if ( !pSetupFunction )
     122         [ #  # ]:          0 :             fprintf( stderr, "could not resolve Sal_SetupPrinterDriver\n" );
     123                 :            : 
     124         [ #  # ]:          0 :         pFaxNrFunction = (faxFunction)osl_getAsciiFunctionSymbol( driverLib, "Sal_queryFaxNumber" );
     125         [ #  # ]:          0 :         if ( !pFaxNrFunction )
     126 [ #  # ][ #  # ]:          0 :             fprintf( stderr, "could not resolve Sal_queryFaxNumber\n" );
     127                 :            :     }
     128                 :            : #endif
     129                 :            : }
     130                 :            : 
     131                 :          0 : inline int PtTo10Mu( int nPoints ) { return (int)((((double)nPoints)*35.27777778)+0.5); }
     132                 :            : 
     133                 :          0 : inline int TenMuToPt( int nUnits ) { return (int)((((double)nUnits)/35.27777778)+0.5); }
     134                 :            : 
     135                 :          3 : static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData )
     136                 :            : {
     137         [ -  + ]:          3 :     pJobSetup->meOrientation    = (Orientation)(rData.m_eOrientation == orientation::Landscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT);
     138                 :            : 
     139                 :            :     // copy page size
     140                 :          3 :     OUString aPaper;
     141                 :            :     int width, height;
     142                 :            : 
     143         [ +  - ]:          3 :     rData.m_aContext.getPageSize( aPaper, width, height );
     144 [ +  - ][ +  - ]:          3 :     pJobSetup->mePaperFormat    = PaperInfo::fromPSName(OUStringToOString( aPaper, RTL_TEXTENCODING_ISO_8859_1 ));
     145                 :            : 
     146                 :          3 :     pJobSetup->mnPaperWidth     = 0;
     147                 :          3 :     pJobSetup->mnPaperHeight    = 0;
     148         [ -  + ]:          3 :     if( pJobSetup->mePaperFormat == PAPER_USER )
     149                 :            :     {
     150                 :            :         // transform to 100dth mm
     151                 :          0 :         width               = PtTo10Mu( width );
     152                 :          0 :         height              = PtTo10Mu( height );
     153                 :            : 
     154         [ #  # ]:          0 :         if( rData.m_eOrientation == psp::orientation::Portrait )
     155                 :            :         {
     156                 :          0 :             pJobSetup->mnPaperWidth = width;
     157                 :          0 :             pJobSetup->mnPaperHeight= height;
     158                 :            :         }
     159                 :            :         else
     160                 :            :         {
     161                 :          0 :             pJobSetup->mnPaperWidth = height;
     162                 :          0 :             pJobSetup->mnPaperHeight= width;
     163                 :            :         }
     164                 :            :     }
     165                 :            : 
     166                 :            :     // copy input slot
     167                 :          3 :     const PPDKey* pKey = NULL;
     168                 :          3 :     const PPDValue* pValue = NULL;
     169                 :            : 
     170                 :          3 :     pJobSetup->mnPaperBin = 0;
     171         [ +  - ]:          3 :     if( rData.m_pParser )
     172 [ +  - ][ +  - ]:          3 :         pKey                    = rData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
         [ +  - ][ +  - ]
     173         [ -  + ]:          3 :     if( pKey )
     174         [ #  # ]:          0 :         pValue                  = rData.m_aContext.getValue( pKey );
     175 [ -  + ][ #  # ]:          3 :     if( pKey && pValue )
     176                 :            :     {
     177 [ #  # ][ #  # ]:          0 :         for( pJobSetup->mnPaperBin = 0;
                 [ #  # ]
     178         [ #  # ]:          0 :              pValue != pKey->getValue( pJobSetup->mnPaperBin ) &&
     179         [ #  # ]:          0 :                  pJobSetup->mnPaperBin < pKey->countValues();
     180                 :            :              pJobSetup->mnPaperBin++ )
     181                 :            :             ;
     182 [ #  # ][ #  # ]:          0 :         if( pJobSetup->mnPaperBin >= pKey->countValues() )
     183                 :          0 :             pJobSetup->mnPaperBin = 0;
     184                 :            :     }
     185                 :            : 
     186                 :            :     // copy duplex
     187                 :          3 :     pKey = NULL;
     188                 :          3 :     pValue = NULL;
     189                 :            : 
     190                 :          3 :     pJobSetup->meDuplexMode = DUPLEX_UNKNOWN;
     191         [ +  - ]:          3 :     if( rData.m_pParser )
     192 [ +  - ][ +  - ]:          3 :         pKey = rData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
         [ +  - ][ +  - ]
     193         [ +  - ]:          3 :     if( pKey )
     194         [ +  - ]:          3 :         pValue = rData.m_aContext.getValue( pKey );
     195 [ +  - ][ +  - ]:          3 :     if( pKey && pValue )
     196                 :            :     {
     197 [ +  - ][ -  + ]:          3 :         if( pValue->m_aOption.EqualsIgnoreCaseAscii( "None" ) ||
         [ #  # ][ +  - ]
     198         [ #  # ]:          0 :             pValue->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 )
     199                 :            :            )
     200                 :            :         {
     201                 :          3 :             pJobSetup->meDuplexMode = DUPLEX_OFF;
     202                 :            :         }
     203 [ #  # ][ #  # ]:          0 :         else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexNoTumble" ) )
     204                 :            :         {
     205                 :          0 :             pJobSetup->meDuplexMode = DUPLEX_LONGEDGE;
     206                 :            :         }
     207 [ #  # ][ #  # ]:          0 :         else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexTumble" ) )
     208                 :            :         {
     209                 :          0 :             pJobSetup->meDuplexMode = DUPLEX_SHORTEDGE;
     210                 :            :         }
     211                 :            :     }
     212                 :            : 
     213                 :            :     // copy the whole context
     214         [ +  - ]:          3 :     if( pJobSetup->mpDriverData )
     215                 :          3 :         rtl_freeMemory( pJobSetup->mpDriverData );
     216                 :            : 
     217                 :            :     int nBytes;
     218                 :          3 :     void* pBuffer = NULL;
     219 [ +  - ][ +  - ]:          3 :     if( rData.getStreamBuffer( pBuffer, nBytes ) )
     220                 :            :     {
     221                 :          3 :         pJobSetup->mnDriverDataLen = nBytes;
     222                 :          3 :         pJobSetup->mpDriverData = (sal_uInt8*)pBuffer;
     223                 :            :     }
     224                 :            :     else
     225                 :            :     {
     226                 :          0 :         pJobSetup->mnDriverDataLen = 0;
     227                 :          0 :         pJobSetup->mpDriverData = NULL;
     228                 :          3 :     }
     229                 :          3 : }
     230                 :            : 
     231                 :            : // Needs a cleaner abstraction ...
     232                 :            : #if defined( UNX )
     233                 :          0 : static bool passFileToCommandLine( const OUString& rFilename, const OUString& rCommandLine, bool bRemoveFile = true )
     234                 :            : {
     235                 :          0 :     bool bSuccess = false;
     236                 :            : 
     237         [ #  # ]:          0 :     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
     238         [ #  # ]:          0 :     rtl::OString aCmdLine(rtl::OUStringToOString(rCommandLine, aEncoding));
     239         [ #  # ]:          0 :     rtl::OString aFilename(rtl::OUStringToOString(rFilename, aEncoding));
     240                 :            : 
     241                 :          0 :     bool bPipe = aCmdLine.indexOf( "(TMP)" ) != -1 ? false : true;
     242                 :            : 
     243                 :            :     // setup command line for exec
     244         [ #  # ]:          0 :     if( ! bPipe )
     245                 :          0 :         aCmdLine = aCmdLine.replaceAll(rtl::OString("(TMP)"), aFilename);
     246                 :            : 
     247                 :            : #if OSL_DEBUG_LEVEL > 1
     248                 :            :     fprintf( stderr, "%s commandline: \"%s\"\n",
     249                 :            :              bPipe ? "piping to" : "executing",
     250                 :            :              aCmdLine.getStr() );
     251                 :            :     struct stat aStat;
     252                 :            :     if( stat( aFilename.getStr(), &aStat ) )
     253                 :            :         fprintf( stderr, "stat( %s ) failed\n", aFilename.getStr() );
     254                 :            :     fprintf( stderr, "Tmp file %s has modes: 0%03lo\n", aFilename.getStr(), (long)aStat.st_mode );
     255                 :            : #endif
     256                 :            :     const char* argv[4];
     257         [ #  # ]:          0 :     if( ! ( argv[ 0 ] = getenv( "SHELL" ) ) )
     258                 :          0 :         argv[ 0 ] = "/bin/sh";
     259                 :          0 :     argv[ 1 ] = "-c";
     260                 :          0 :     argv[ 2 ] = aCmdLine.getStr();
     261                 :          0 :     argv[ 3 ] = 0;
     262                 :            : 
     263                 :          0 :     bool bHavePipes = false;
     264                 :            :     int pid, fd[2];
     265                 :            : 
     266         [ #  # ]:          0 :     if( bPipe )
     267                 :          0 :         bHavePipes = pipe( fd ) ? false : true;
     268         [ #  # ]:          0 :     if( ( pid = fork() ) > 0 )
     269                 :            :     {
     270 [ #  # ][ #  # ]:          0 :         if( bPipe && bHavePipes )
     271                 :            :         {
     272         [ #  # ]:          0 :             close( fd[0] );
     273                 :            :             char aBuffer[ 2048 ];
     274         [ #  # ]:          0 :             FILE* fp = fopen( aFilename.getStr(), "r" );
     275 [ #  # ][ #  # ]:          0 :             while (fp && !feof(fp))
                 [ #  # ]
     276                 :            :             {
     277         [ #  # ]:          0 :                 size_t nBytesRead = fread(aBuffer, 1, sizeof( aBuffer ), fp);
     278         [ #  # ]:          0 :                 if (nBytesRead )
     279                 :            :                 {
     280         [ #  # ]:          0 :                     size_t nBytesWritten = write(fd[1], aBuffer, nBytesRead);
     281                 :            :                     OSL_ENSURE(nBytesWritten == nBytesRead, "short write");
     282         [ #  # ]:          0 :                     if (nBytesWritten != nBytesRead)
     283                 :          0 :                         break;
     284                 :            :                 }
     285                 :            :             }
     286         [ #  # ]:          0 :             fclose( fp );
     287         [ #  # ]:          0 :             close( fd[ 1 ] );
     288                 :            :         }
     289                 :          0 :         int status = 0;
     290         [ #  # ]:          0 :         waitpid( pid, &status, 0 );
     291         [ #  # ]:          0 :         if( ! status )
     292                 :          0 :             bSuccess = true;
     293                 :            :     }
     294         [ #  # ]:          0 :     else if( ! pid )
     295                 :            :     {
     296 [ #  # ][ #  # ]:          0 :         if( bPipe && bHavePipes )
     297                 :            :         {
     298         [ #  # ]:          0 :             close( fd[1] );
     299         [ #  # ]:          0 :             if( fd[0] != STDIN_FILENO ) // not probable, but who knows :)
     300                 :          0 :                 dup2( fd[0], STDIN_FILENO );
     301                 :            :         }
     302                 :          0 :         execv( argv[0], const_cast<char**>(argv) );
     303         [ #  # ]:          0 :         fprintf( stderr, "failed to execute \"%s\"\n", aCmdLine.getStr() );
     304                 :          0 :         _exit( 1 );
     305                 :            :     }
     306                 :            :     else
     307         [ #  # ]:          0 :         fprintf( stderr, "failed to fork\n" );
     308                 :            : 
     309                 :            :     // clean up the mess
     310         [ #  # ]:          0 :     if( bRemoveFile )
     311                 :          0 :         unlink( aFilename.getStr() );
     312                 :            : 
     313                 :          0 :     return bSuccess;
     314                 :            : }
     315                 :            : #endif
     316                 :            : 
     317                 :          0 : static bool sendAFax( const OUString& rFaxNumber, const OUString& rFileName, const OUString& rCommand )
     318                 :            : {
     319                 :            : #if defined( UNX )
     320         [ #  # ]:          0 :     std::list< OUString > aFaxNumbers;
     321                 :            : 
     322         [ #  # ]:          0 :     if( rFaxNumber.isEmpty() )
     323                 :            :     {
     324         [ #  # ]:          0 :         getPaLib();
     325         [ #  # ]:          0 :         if( pFaxNrFunction )
     326                 :            :         {
     327                 :          0 :             OUString aNewNr;
     328 [ #  # ][ #  # ]:          0 :             if( pFaxNrFunction( aNewNr ) )
     329         [ #  # ]:          0 :                 aFaxNumbers.push_back( aNewNr );
     330                 :            :         }
     331                 :            :     }
     332                 :            :     else
     333                 :            :     {
     334                 :          0 :         sal_Int32 nIndex = 0;
     335                 :          0 :         OUString aFaxes( rFaxNumber );
     336         [ #  # ]:          0 :         OUString aBeginToken( RTL_CONSTASCII_USTRINGPARAM("<Fax#>") );
     337         [ #  # ]:          0 :         OUString aEndToken( RTL_CONSTASCII_USTRINGPARAM("</Fax#>") );
     338         [ #  # ]:          0 :         while( nIndex != -1 )
     339                 :            :         {
     340                 :          0 :             nIndex = aFaxes.indexOf( aBeginToken, nIndex );
     341         [ #  # ]:          0 :             if( nIndex != -1 )
     342                 :            :             {
     343                 :          0 :                 sal_Int32 nBegin = nIndex + aBeginToken.getLength();
     344                 :          0 :                 nIndex = aFaxes.indexOf( aEndToken, nIndex );
     345         [ #  # ]:          0 :                 if( nIndex != -1 )
     346                 :            :                 {
     347         [ #  # ]:          0 :                     aFaxNumbers.push_back( aFaxes.copy( nBegin, nIndex-nBegin ) );
     348                 :          0 :                     nIndex += aEndToken.getLength();
     349                 :            :                 }
     350                 :            :             }
     351                 :          0 :         }
     352                 :            :     }
     353                 :            : 
     354                 :          0 :     bool bSuccess = true;
     355         [ #  # ]:          0 :     if( aFaxNumbers.begin() != aFaxNumbers.end() )
     356                 :            :     {
     357 [ #  # ][ #  # ]:          0 :         while( aFaxNumbers.begin() != aFaxNumbers.end() && bSuccess )
         [ #  # ][ #  # ]
                 [ #  # ]
     358                 :            :         {
     359         [ #  # ]:          0 :             OUString aFaxNumber( aFaxNumbers.front() );
     360         [ #  # ]:          0 :             aFaxNumbers.pop_front();
     361                 :            :             OUString aCmdLine(
     362                 :          0 :                 rCommand.replaceAll("(PHONE)", aFaxNumber));
     363                 :            : #if OSL_DEBUG_LEVEL > 1
     364                 :            :             fprintf( stderr, "sending fax to \"%s\"\n", OUStringToOString( aFaxNumber, osl_getThreadTextEncoding() ).getStr() );
     365                 :            : #endif
     366         [ #  # ]:          0 :             bSuccess = passFileToCommandLine( rFileName, aCmdLine, false );
     367                 :          0 :         }
     368                 :            :     }
     369                 :            :     else
     370                 :          0 :         bSuccess = false;
     371                 :            : 
     372                 :            :     // clean up temp file
     373 [ #  # ][ #  # ]:          0 :     unlink(rtl::OUStringToOString(rFileName, osl_getThreadTextEncoding()).getStr());
     374                 :            : 
     375                 :          0 :     return bSuccess;
     376                 :            : #else
     377                 :            :     (void)rFaxNumber; (void)rFileName; (void)rCommand;
     378                 :            :     return false;
     379                 :            : #endif
     380                 :            : }
     381                 :            : 
     382                 :          0 : static bool createPdf( const OUString& rToFile, const OUString& rFromFile, const OUString& rCommandLine )
     383                 :            : {
     384                 :            : #if defined( UNX )
     385                 :            :     OUString aCommandLine(
     386                 :          0 :         rCommandLine.replaceAll("(OUTFILE)", rToFile));
     387                 :            : 
     388         [ #  # ]:          0 :     return passFileToCommandLine( rFromFile, aCommandLine );
     389                 :            : #else
     390                 :            :     (void)rToFile; (void)rFromFile; (void)rCommandLine;
     391                 :            :     return false;
     392                 :            : #endif
     393                 :            : }
     394                 :            : 
     395                 :            : /*
     396                 :            :  *  SalInstance
     397                 :            :  */
     398                 :            : 
     399                 :          0 : void SalGenericInstance::configurePspInfoPrinter(PspSalInfoPrinter *pPrinter,
     400                 :            :     SalPrinterQueueInfo* pQueueInfo, ImplJobSetup* pJobSetup)
     401                 :            : {
     402         [ #  # ]:          0 :     if( pJobSetup )
     403                 :            :     {
     404         [ #  # ]:          0 :         PrinterInfoManager& rManager( PrinterInfoManager::get() );
     405 [ #  # ][ #  # ]:          0 :         PrinterInfo aInfo( rManager.getPrinterInfo( pQueueInfo->maPrinterName ) );
     406         [ #  # ]:          0 :         pPrinter->m_aJobData = aInfo;
     407         [ #  # ]:          0 :         pPrinter->m_aPrinterGfx.Init( pPrinter->m_aJobData );
     408                 :            : 
     409         [ #  # ]:          0 :         if( pJobSetup->mpDriverData )
     410         [ #  # ]:          0 :             JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo );
     411                 :            : 
     412                 :          0 :         pJobSetup->mnSystem         = JOBSETUP_SYSTEM_UNIX;
     413                 :          0 :         pJobSetup->maPrinterName    = pQueueInfo->maPrinterName;
     414                 :          0 :         pJobSetup->maDriver         = aInfo.m_aDriverName;
     415 [ #  # ][ #  # ]:          0 :         copyJobDataToJobSetup( pJobSetup, aInfo );
     416                 :            :     }
     417                 :          0 : }
     418                 :            : 
     419                 :          0 : SalInfoPrinter* SalGenericInstance::CreateInfoPrinter( SalPrinterQueueInfo*    pQueueInfo,
     420                 :            :                                                    ImplJobSetup*            pJobSetup )
     421                 :            : {
     422                 :          0 :     mbPrinterInit = true;
     423                 :            :     // create and initialize SalInfoPrinter
     424         [ #  # ]:          0 :     PspSalInfoPrinter* pPrinter = new PspSalInfoPrinter();
     425                 :          0 :     configurePspInfoPrinter(pPrinter, pQueueInfo, pJobSetup);
     426                 :          0 :     return pPrinter;
     427                 :            : }
     428                 :            : 
     429                 :          0 : void SalGenericInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
     430                 :            : {
     431         [ #  # ]:          0 :     delete pPrinter;
     432                 :          0 : }
     433                 :            : 
     434                 :          0 : SalPrinter* SalGenericInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
     435                 :            : {
     436                 :          0 :     mbPrinterInit = true;
     437                 :            :     // create and initialize SalPrinter
     438         [ #  # ]:          0 :     PspSalPrinter* pPrinter = new PspSalPrinter( pInfoPrinter );
     439                 :          0 :     pPrinter->m_aJobData = static_cast<PspSalInfoPrinter*>(pInfoPrinter)->m_aJobData;
     440                 :            : 
     441                 :          0 :     return pPrinter;
     442                 :            : }
     443                 :            : 
     444                 :          0 : void SalGenericInstance::DestroyPrinter( SalPrinter* pPrinter )
     445                 :            : {
     446         [ #  # ]:          0 :     delete pPrinter;
     447                 :          0 : }
     448                 :            : 
     449                 :          0 : void SalGenericInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
     450                 :            : {
     451                 :          0 :     mbPrinterInit = true;
     452         [ #  # ]:          0 :     PrinterInfoManager& rManager( PrinterInfoManager::get() );
     453 [ #  # ][ #  # ]:          0 :     static const char* pNoSyncDetection = getenv( "SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION" );
     454 [ #  # ][ #  # ]:          0 :     if( ! pNoSyncDetection || ! *pNoSyncDetection )
     455                 :            :     {
     456                 :            :         // #i62663# synchronize possible asynchronouse printer detection now
     457         [ #  # ]:          0 :         rManager.checkPrintersChanged( true );
     458                 :            :     }
     459         [ #  # ]:          0 :     ::std::list< OUString > aPrinters;
     460         [ #  # ]:          0 :     rManager.listPrinters( aPrinters );
     461                 :            : 
     462         [ #  # ]:          0 :     for( ::std::list< OUString >::iterator it = aPrinters.begin(); it != aPrinters.end(); ++it )
     463                 :            :     {
     464         [ #  # ]:          0 :         const PrinterInfo& rInfo( rManager.getPrinterInfo( *it ) );
     465                 :            :         // Neuen Eintrag anlegen
     466 [ #  # ][ #  # ]:          0 :         SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
     467                 :          0 :         pInfo->maPrinterName    = *it;
     468                 :          0 :         pInfo->maDriver         = rInfo.m_aDriverName;
     469                 :          0 :         pInfo->maLocation       = rInfo.m_aLocation;
     470                 :          0 :         pInfo->maComment        = rInfo.m_aComment;
     471                 :          0 :         pInfo->mpSysData        = NULL;
     472                 :            : 
     473                 :          0 :         sal_Int32 nIndex = 0;
     474         [ #  # ]:          0 :         while( nIndex != -1 )
     475                 :            :         {
     476                 :          0 :             rtl::OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) );
     477         [ #  # ]:          0 :             if( aToken.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("pdf=") ) )
     478                 :            :             {
     479         [ #  # ]:          0 :                 pInfo->maLocation = getPdfDir( rInfo );
     480                 :            :                 break;
     481                 :            :             }
     482         [ #  # ]:          0 :         }
     483                 :            : 
     484         [ #  # ]:          0 :         pList->Add( pInfo );
     485                 :          0 :     }
     486                 :          0 : }
     487                 :            : 
     488                 :          0 : void SalGenericInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
     489                 :            : {
     490         [ #  # ]:          0 :     delete pInfo;
     491                 :          0 : }
     492                 :            : 
     493                 :          0 : void SalGenericInstance::GetPrinterQueueState( SalPrinterQueueInfo* )
     494                 :            : {
     495                 :          0 :     mbPrinterInit = true;
     496                 :          0 : }
     497                 :            : 
     498                 :          0 : rtl::OUString SalGenericInstance::GetDefaultPrinter()
     499                 :            : {
     500                 :          0 :     mbPrinterInit = true;
     501                 :          0 :     PrinterInfoManager& rManager( PrinterInfoManager::get() );
     502                 :          0 :     return rManager.getDefaultPrinter();
     503                 :            : }
     504                 :            : 
     505                 :        109 : PspSalInfoPrinter::PspSalInfoPrinter()
     506 [ +  - ][ +  - ]:        109 :     : m_pGraphics( NULL )
     507                 :            : {
     508                 :        109 : }
     509                 :            : 
     510 [ +  - ][ +  - ]:        107 : PspSalInfoPrinter::~PspSalInfoPrinter()
     511                 :            : {
     512         [ -  + ]:        107 :     if( m_pGraphics )
     513                 :            :     {
     514 [ #  # ][ #  # ]:          0 :         delete m_pGraphics;
     515                 :          0 :         m_pGraphics = NULL;
     516                 :            :     }
     517         [ -  + ]:        107 : }
     518                 :            : 
     519                 :          0 : void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* )
     520                 :            : {
     521                 :          0 :     m_aPaperFormats.clear();
     522                 :          0 :     m_bPapersInit = true;
     523                 :            : 
     524         [ #  # ]:          0 :     if( m_aJobData.m_pParser )
     525                 :            :     {
     526 [ #  # ][ #  # ]:          0 :         const PPDKey* pKey = m_aJobData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
                 [ #  # ]
     527         [ #  # ]:          0 :         if( pKey )
     528                 :            :         {
     529                 :          0 :             int nValues = pKey->countValues();
     530         [ #  # ]:          0 :             for( int i = 0; i < nValues; i++ )
     531                 :            :             {
     532         [ #  # ]:          0 :                 const PPDValue* pValue = pKey->getValue( i );
     533                 :          0 :                 int nWidth = 0, nHeight = 0;
     534         [ #  # ]:          0 :                 m_aJobData.m_pParser->getPaperDimension( pValue->m_aOption, nWidth, nHeight );
     535         [ #  # ]:          0 :                 PaperInfo aInfo(PtTo10Mu( nWidth ), PtTo10Mu( nHeight ));
     536         [ #  # ]:          0 :                 m_aPaperFormats.push_back( aInfo );
     537                 :            :             }
     538                 :            :         }
     539                 :            :     }
     540                 :          0 : }
     541                 :            : 
     542                 :          0 : int PspSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* )
     543                 :            : {
     544                 :          0 :     return 900;
     545                 :            : }
     546                 :            : 
     547                 :        112 : SalGraphics* PspSalInfoPrinter::GetGraphics()
     548                 :            : {
     549                 :            :     // return a valid pointer only once
     550                 :            :     // the reasoning behind this is that we could have different
     551                 :            :     // SalGraphics that can run in multiple threads
     552                 :            :     // (future plans)
     553                 :        112 :     SalGraphics* pRet = NULL;
     554         [ +  - ]:        112 :     if( ! m_pGraphics )
     555                 :            :     {
     556                 :        112 :         m_pGraphics = GetGenericInstance()->CreatePrintGraphics();
     557                 :        112 :         m_pGraphics->Init( &m_aJobData, &m_aPrinterGfx, NULL, false, this );
     558                 :        112 :         pRet = m_pGraphics;
     559                 :            :     }
     560                 :        112 :     return pRet;
     561                 :            : }
     562                 :            : 
     563                 :        110 : void PspSalInfoPrinter::ReleaseGraphics( SalGraphics* pGraphics )
     564                 :            : {
     565         [ +  - ]:        110 :     if( pGraphics == m_pGraphics )
     566                 :            :     {
     567         [ +  - ]:        110 :         delete pGraphics;
     568                 :        110 :         m_pGraphics = NULL;
     569                 :            :     }
     570                 :        110 :     return;
     571                 :            : }
     572                 :            : 
     573                 :          0 : sal_Bool PspSalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pJobSetup )
     574                 :            : {
     575 [ #  # ][ #  # ]:          0 :     if( ! pFrame || ! pJobSetup )
     576                 :          0 :         return sal_False;
     577                 :            : 
     578         [ #  # ]:          0 :     getPaLib();
     579                 :            : 
     580         [ #  # ]:          0 :     if( ! pSetupFunction )
     581                 :          0 :         return sal_False;
     582                 :            : 
     583         [ #  # ]:          0 :     PrinterInfoManager& rManager = PrinterInfoManager::get();
     584                 :            : 
     585 [ #  # ][ #  # ]:          0 :     PrinterInfo aInfo( rManager.getPrinterInfo( pJobSetup->maPrinterName ) );
     586         [ #  # ]:          0 :     if ( pJobSetup->mpDriverData )
     587                 :            :     {
     588         [ #  # ]:          0 :         SetData( ~0, pJobSetup );
     589         [ #  # ]:          0 :         JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo );
     590                 :            :     }
     591                 :            : 
     592 [ #  # ][ #  # ]:          0 :     if( pSetupFunction( aInfo ) )
     593                 :            :     {
     594                 :          0 :         rtl_freeMemory( pJobSetup->mpDriverData );
     595                 :          0 :         pJobSetup->mpDriverData = NULL;
     596                 :            : 
     597                 :            :         int nBytes;
     598                 :          0 :         void* pBuffer = NULL;
     599         [ #  # ]:          0 :         aInfo.getStreamBuffer( pBuffer, nBytes );
     600                 :          0 :         pJobSetup->mnDriverDataLen  = nBytes;
     601                 :          0 :         pJobSetup->mpDriverData     = (sal_uInt8*)pBuffer;
     602                 :            : 
     603                 :            :         // copy everything to job setup
     604         [ #  # ]:          0 :         copyJobDataToJobSetup( pJobSetup, aInfo );
     605         [ #  # ]:          0 :         JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData );
     606                 :          0 :         return sal_True;
     607                 :            :     }
     608         [ #  # ]:          0 :     return sal_False;
     609                 :            : }
     610                 :            : 
     611                 :            : // This function gets the driver data and puts it into pJobSetup
     612                 :            : // If pJobSetup->mpDriverData is NOT NULL, then the independend
     613                 :            : // data should be merged into the driver data
     614                 :            : // If pJobSetup->mpDriverData IS NULL, then the driver defaults
     615                 :            : // should be merged into the independent data
     616                 :          3 : sal_Bool PspSalInfoPrinter::SetPrinterData( ImplJobSetup* pJobSetup )
     617                 :            : {
     618         [ +  - ]:          3 :     if( pJobSetup->mpDriverData )
     619                 :          3 :         return SetData( ~0, pJobSetup );
     620                 :            : 
     621                 :          0 :     copyJobDataToJobSetup( pJobSetup, m_aJobData );
     622                 :            : 
     623                 :          3 :     return sal_True;
     624                 :            : }
     625                 :            : 
     626                 :            : // This function merges the independ driver data
     627                 :            : // and sets the new independ data in pJobSetup
     628                 :            : // Only the data must be changed, where the bit
     629                 :            : // in nGetDataFlags is set
     630                 :          3 : sal_Bool PspSalInfoPrinter::SetData(
     631                 :            :     sal_uLong nSetDataFlags,
     632                 :            :     ImplJobSetup* pJobSetup )
     633                 :            : {
     634         [ +  - ]:          3 :     JobData aData;
     635         [ +  - ]:          3 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     636                 :            : 
     637         [ +  - ]:          3 :     if( aData.m_pParser )
     638                 :            :     {
     639                 :            :         const PPDKey* pKey;
     640                 :            :         const PPDValue* pValue;
     641                 :            : 
     642                 :            :         // merge papersize if necessary
     643         [ +  - ]:          3 :         if( nSetDataFlags & SAL_JOBSET_PAPERSIZE )
     644                 :            :         {
     645                 :          3 :             OUString aPaper;
     646                 :            : 
     647         [ -  + ]:          3 :             if( pJobSetup->mePaperFormat == PAPER_USER )
     648                 :            :                 aPaper = aData.m_pParser->matchPaper(
     649                 :            :                     TenMuToPt( pJobSetup->mnPaperWidth ),
     650 [ #  # ][ #  # ]:          0 :                     TenMuToPt( pJobSetup->mnPaperHeight ) );
                 [ #  # ]
     651                 :            :             else
     652 [ +  - ][ +  - ]:          3 :                 aPaper = rtl::OStringToOUString(PaperInfo::toPSName(pJobSetup->mePaperFormat), RTL_TEXTENCODING_ISO_8859_1);
     653                 :            : 
     654 [ +  - ][ +  - ]:          3 :             pKey = aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
         [ +  - ][ +  - ]
     655 [ +  - ][ +  - ]:          3 :             pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : NULL;
         [ +  - ][ +  - ]
         [ #  # ][ +  - ]
     656                 :            : 
     657                 :            :             // some PPD files do not specify the standard paper names (e.g. C5 instead of EnvC5)
     658                 :            :             // try to find the correct paper anyway using the size
     659 [ +  - ][ -  + ]:          3 :             if( pKey && ! pValue && pJobSetup->mePaperFormat != PAPER_USER )
                 [ #  # ]
     660                 :            :             {
     661         [ #  # ]:          0 :                 PaperInfo aInfo( pJobSetup->mePaperFormat );
     662                 :            :                 aPaper = aData.m_pParser->matchPaper(
     663                 :          0 :                     TenMuToPt( aInfo.getWidth() ),
     664 [ #  # ][ #  # ]:          0 :                     TenMuToPt( aInfo.getHeight() ) );
                 [ #  # ]
     665 [ #  # ][ #  # ]:          0 :                 pValue = pKey->getValueCaseInsensitive( aPaper );
                 [ #  # ]
     666                 :            :             }
     667                 :            : 
     668 [ +  - ][ +  - ]:          3 :             if( ! ( pKey && pValue && aData.m_aContext.setValue( pKey, pValue, false ) == pValue ) )
         [ +  - ][ -  + ]
                 [ -  + ]
     669         [ +  - ]:          3 :                 return sal_False;
     670                 :            :         }
     671                 :            : 
     672                 :            :         // merge paperbin if necessary
     673         [ +  - ]:          3 :         if( nSetDataFlags & SAL_JOBSET_PAPERBIN )
     674                 :            :         {
     675 [ +  - ][ +  - ]:          3 :             pKey = aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
         [ +  - ][ +  - ]
     676         [ -  + ]:          3 :             if( pKey )
     677                 :            :             {
     678                 :          0 :                 int nPaperBin = pJobSetup->mnPaperBin;
     679 [ #  # ][ #  # ]:          0 :                 if( nPaperBin >= pKey->countValues() )
     680                 :          0 :                     pValue = pKey->getDefaultValue();
     681                 :            :                 else
     682         [ #  # ]:          0 :                     pValue = pKey->getValue( pJobSetup->mnPaperBin );
     683                 :            : 
     684                 :            :                 // may fail due to constraints;
     685                 :            :                 // real paper bin is copied back to jobsetup in that case
     686         [ #  # ]:          0 :                 aData.m_aContext.setValue( pKey, pValue );
     687                 :            :             }
     688                 :            :             // if printer has no InputSlot key simply ignore this setting
     689                 :            :             // (e.g. SGENPRT has no InputSlot)
     690                 :            :         }
     691                 :            : 
     692                 :            :         // merge orientation if necessary
     693         [ +  - ]:          3 :         if( nSetDataFlags & SAL_JOBSET_ORIENTATION )
     694         [ -  + ]:          3 :             aData.m_eOrientation = pJobSetup->meOrientation == ORIENTATION_LANDSCAPE ? orientation::Landscape : orientation::Portrait;
     695                 :            : 
     696                 :            :         // merge duplex if necessary
     697         [ +  - ]:          3 :         if( nSetDataFlags & SAL_JOBSET_DUPLEXMODE )
     698                 :            :         {
     699 [ +  - ][ +  - ]:          3 :             pKey = aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
         [ +  - ][ +  - ]
     700         [ +  - ]:          3 :             if( pKey )
     701                 :            :             {
     702                 :          3 :                 pValue = NULL;
     703   [ +  -  -  - ]:          3 :                 switch( pJobSetup->meDuplexMode )
     704                 :            :                 {
     705                 :            :                 case DUPLEX_OFF:
     706 [ +  - ][ +  - ]:          3 :                     pValue = pKey->getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
         [ +  - ][ +  - ]
     707         [ -  + ]:          3 :                     if( pValue == NULL )
     708 [ #  # ][ #  # ]:          0 :                         pValue = pKey->getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SimplexNoTumble" ) ) );
         [ #  # ][ #  # ]
     709                 :          3 :                     break;
     710                 :            :                 case DUPLEX_SHORTEDGE:
     711 [ #  # ][ #  # ]:          0 :                     pValue = pKey->getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DuplexTumble" ) ) );
         [ #  # ][ #  # ]
     712                 :          0 :                     break;
     713                 :            :                 case DUPLEX_LONGEDGE:
     714 [ #  # ][ #  # ]:          0 :                     pValue = pKey->getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DuplexNoTumble" ) ) );
         [ #  # ][ #  # ]
     715                 :          0 :                     break;
     716                 :            :                 case DUPLEX_UNKNOWN:
     717                 :            :                 default:
     718                 :          0 :                     pValue = 0;
     719                 :          0 :                     break;
     720                 :            :                 }
     721         [ -  + ]:          3 :                 if( ! pValue )
     722                 :          0 :                     pValue = pKey->getDefaultValue();
     723         [ +  - ]:          3 :                 aData.m_aContext.setValue( pKey, pValue );
     724                 :            :             }
     725                 :            :         }
     726                 :            : 
     727         [ +  - ]:          3 :         m_aJobData = aData;
     728         [ +  - ]:          3 :         copyJobDataToJobSetup( pJobSetup, aData );
     729                 :          3 :         return sal_True;
     730                 :            :     }
     731                 :            : 
     732         [ +  - ]:          3 :     return sal_False;
     733                 :            : }
     734                 :            : 
     735                 :        112 : void PspSalInfoPrinter::GetPageInfo(
     736                 :            :     const ImplJobSetup* pJobSetup,
     737                 :            :     long& rOutWidth, long& rOutHeight,
     738                 :            :     long& rPageOffX, long& rPageOffY,
     739                 :            :     long& rPageWidth, long& rPageHeight )
     740                 :            : {
     741         [ +  - ]:        112 :     if( ! pJobSetup )
     742                 :        112 :         return;
     743                 :            : 
     744         [ +  - ]:        112 :     JobData aData;
     745         [ +  - ]:        112 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     746                 :            : 
     747                 :            :     // get the selected page size
     748         [ +  - ]:        112 :     if( aData.m_pParser )
     749                 :            :     {
     750                 :            : 
     751                 :        112 :         OUString aPaper;
     752                 :            :         int width, height;
     753                 :        112 :         int left = 0, top = 0, right = 0, bottom = 0;
     754         [ +  - ]:        112 :         int nDPI = aData.m_aContext.getRenderResolution();
     755                 :            : 
     756                 :            : 
     757         [ +  - ]:        112 :         if( aData.m_eOrientation == psp::orientation::Portrait )
     758                 :            :         {
     759         [ +  - ]:        112 :             aData.m_aContext.getPageSize( aPaper, width, height );
     760 [ +  - ][ +  - ]:        112 :             aData.m_pParser->getMargins( aPaper, left, right, top, bottom );
                 [ +  - ]
     761                 :            :         }
     762                 :            :         else
     763                 :            :         {
     764         [ #  # ]:          0 :             aData.m_aContext.getPageSize( aPaper, height, width );
     765 [ #  # ][ #  # ]:          0 :             aData.m_pParser->getMargins( aPaper, top, bottom, right, left );
                 [ #  # ]
     766                 :            :         }
     767                 :            : 
     768                 :        112 :         rPageWidth  = width * nDPI / 72;
     769                 :        112 :         rPageHeight = height * nDPI / 72;
     770                 :        112 :         rPageOffX   = left * nDPI / 72;
     771                 :        112 :         rPageOffY   = top * nDPI / 72;
     772                 :        112 :         rOutWidth   = ( width  - left - right ) * nDPI / 72;
     773                 :        112 :         rOutHeight  = ( height - top  - bottom ) * nDPI / 72;
     774         [ +  - ]:        112 :     }
     775                 :            : }
     776                 :            : 
     777                 :          0 : sal_uLong PspSalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup )
     778                 :            : {
     779         [ #  # ]:          0 :     if( ! pJobSetup )
     780                 :          0 :         return 0;
     781                 :            : 
     782         [ #  # ]:          0 :     JobData aData;
     783         [ #  # ]:          0 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     784                 :            : 
     785 [ #  # ][ #  # ]:          0 :     const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     786 [ #  # ][ #  # ]:          0 :     return pKey ? pKey->countValues() : 0;
                 [ #  # ]
     787                 :            : }
     788                 :            : 
     789                 :          0 : rtl::OUString PspSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, sal_uLong nPaperBin )
     790                 :            : {
     791         [ #  # ]:          0 :     JobData aData;
     792         [ #  # ]:          0 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     793                 :            : 
     794                 :          0 :     OUString aRet;
     795         [ #  # ]:          0 :     if( aData.m_pParser )
     796                 :            :     {
     797 [ #  # ][ #  # ]:          0 :         const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     798 [ #  # ][ #  # ]:          0 :         if( ! pKey || nPaperBin >= (sal_uLong)pKey->countValues() )
         [ #  # ][ #  # ]
     799 [ #  # ][ #  # ]:          0 :             aRet = aData.m_pParser->getDefaultInputSlot();
                 [ #  # ]
     800                 :            :         else
     801                 :            :         {
     802         [ #  # ]:          0 :             const PPDValue* pValue = pKey->getValue( nPaperBin );
     803         [ #  # ]:          0 :             if( pValue )
     804 [ #  # ][ #  # ]:          0 :                 aRet = aData.m_pParser->translateOption( pKey->getKey(), pValue->m_aOption );
                 [ #  # ]
     805                 :            :         }
     806                 :            :     }
     807                 :            : 
     808         [ #  # ]:          0 :     return aRet;
     809                 :            : }
     810                 :            : 
     811                 :          0 : sal_uLong PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, sal_uInt16 nType )
     812                 :            : {
     813   [ #  #  #  #  :          0 :     switch( nType )
          #  #  #  #  #  
             #  #  #  # ]
     814                 :            :     {
     815                 :            :         case PRINTER_CAPABILITIES_SUPPORTDIALOG:
     816                 :          0 :             return 1;
     817                 :            :         case PRINTER_CAPABILITIES_COPIES:
     818                 :          0 :             return 0xffff;
     819                 :            :         case PRINTER_CAPABILITIES_COLLATECOPIES:
     820                 :            :         {
     821                 :            :             // see if the PPD contains a value to set Collate to True
     822         [ #  # ]:          0 :             JobData aData;
     823         [ #  # ]:          0 :             JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     824                 :            : 
     825 [ #  # ][ #  # ]:          0 :             const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) ) : NULL;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     826 [ #  # ][ #  # ]:          0 :             const PPDValue* pVal = pKey ? pKey->getValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "True" ) ) ) : NULL;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     827                 :            : 
     828                 :            :             // PPDs don't mention the number of possible collated copies.
     829                 :            :             // so let's guess as many as we want ?
     830 [ #  # ][ #  # ]:          0 :             return pVal ? 0xffff : 0;
     831                 :            :         }
     832                 :            :         case PRINTER_CAPABILITIES_SETORIENTATION:
     833                 :          0 :             return 1;
     834                 :            :         case PRINTER_CAPABILITIES_SETDUPLEX:
     835                 :          0 :             return 1;
     836                 :            :         case PRINTER_CAPABILITIES_SETPAPERBIN:
     837                 :          0 :             return 1;
     838                 :            :         case PRINTER_CAPABILITIES_SETPAPERSIZE:
     839                 :          0 :             return 1;
     840                 :            :         case PRINTER_CAPABILITIES_SETPAPER:
     841                 :          0 :             return 0;
     842                 :            :         case PRINTER_CAPABILITIES_FAX:
     843         [ #  # ]:          0 :             return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "fax" ) ? 1 : 0;
     844                 :            :         case PRINTER_CAPABILITIES_PDF:
     845         [ #  # ]:          0 :             if( PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "pdf" ) )
     846                 :          0 :                 return 1;
     847                 :            :             else
     848                 :            :             {
     849                 :            :                 // see if the PPD contains a value to set Collate to True
     850 [ #  # ][ #  # ]:          0 :                 JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName );
                 [ #  # ]
     851         [ #  # ]:          0 :                 if( pJobSetup->mpDriverData )
     852         [ #  # ]:          0 :                     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     853 [ #  # ][ #  # ]:          0 :                 return aData.m_nPDFDevice > 0 ? 1 : 0;
     854                 :            :             }
     855                 :            :         case PRINTER_CAPABILITIES_EXTERNALDIALOG:
     856         [ #  # ]:          0 :             return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "external_dialog" ) ? 1 : 0;
     857                 :            :         case PRINTER_CAPABILITIES_USEPULLMODEL:
     858                 :            :         {
     859                 :            :             // see if the PPD contains a value to set Collate to True
     860 [ #  # ][ #  # ]:          0 :             JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName );
                 [ #  # ]
     861         [ #  # ]:          0 :             if( pJobSetup->mpDriverData )
     862         [ #  # ]:          0 :                 JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
     863 [ #  # ][ #  # ]:          0 :             return aData.m_nPDFDevice > 0 ? 1 : 0;
     864                 :            :         }
     865                 :          0 :         default: break;
     866                 :            :     };
     867                 :          0 :     return 0;
     868                 :            : }
     869                 :            : 
     870                 :            : /*
     871                 :            :  *  SalPrinter
     872                 :            :  */
     873                 :          0 : PspSalPrinter::PspSalPrinter( SalInfoPrinter* pInfoPrinter )
     874                 :            :  : m_bFax( false ),
     875                 :            :    m_bPdf( false ),
     876                 :            :    m_bSwallowFaxNo( false ),
     877                 :            :    m_bIsPDFWriterJob( false ),
     878                 :            :    m_pGraphics( NULL ),
     879                 :            :    m_nCopies( 1 ),
     880                 :            :    m_bCollate( false ),
     881 [ #  # ][ #  # ]:          0 :    m_pInfoPrinter( pInfoPrinter )
                 [ #  # ]
     882                 :            : {
     883                 :          0 : }
     884                 :            : 
     885 [ #  # ][ #  # ]:          0 : PspSalPrinter::~PspSalPrinter()
                 [ #  # ]
     886                 :            : {
     887         [ #  # ]:          0 : }
     888                 :            : 
     889                 :          0 : static rtl::OUString getTmpName()
     890                 :            : {
     891                 :          0 :     rtl::OUString aTmp, aSys;
     892         [ #  # ]:          0 :     osl_createTempFile( NULL, NULL, &aTmp.pData );
     893         [ #  # ]:          0 :     osl_getSystemPathFromFileURL( aTmp.pData, &aSys.pData );
     894                 :            : 
     895                 :          0 :     return aSys;
     896                 :            : }
     897                 :            : 
     898                 :          0 : sal_Bool PspSalPrinter::StartJob(
     899                 :            :     const rtl::OUString* pFileName,
     900                 :            :     const rtl::OUString& rJobName,
     901                 :            :     const rtl::OUString& rAppName,
     902                 :            :     sal_uLong nCopies,
     903                 :            :     bool bCollate,
     904                 :            :     bool bDirect,
     905                 :            :     ImplJobSetup* pJobSetup )
     906                 :            : {
     907                 :            :     OSL_TRACE("PspSalPrinter::StartJob");
     908 [ #  # ][ #  # ]:          0 :     GetSalData()->m_pInstance->jobStartedPrinterUpdate();
     909                 :            : 
     910                 :          0 :     m_bFax      = false;
     911                 :          0 :     m_bPdf      = false;
     912         [ #  # ]:          0 :     m_aFileName = pFileName ? *pFileName : rtl::OUString();
     913                 :          0 :     m_aTmpFile  = rtl::OUString();
     914                 :          0 :     m_nCopies   = nCopies;
     915                 :          0 :     m_bCollate  = bCollate;
     916                 :            : 
     917         [ #  # ]:          0 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData );
     918         [ #  # ]:          0 :     if( m_nCopies > 1 )
     919                 :            :     {
     920                 :            :         // in case user did not do anything (m_nCopies=1)
     921                 :            :         // take the default from jobsetup
     922                 :          0 :         m_aJobData.m_nCopies = m_nCopies;
     923         [ #  # ]:          0 :         m_aJobData.setCollate( bCollate );
     924                 :            :     }
     925                 :            : 
     926                 :          0 :     int nMode = 0;
     927                 :            : #if defined( UNX )
     928                 :            :     // check whether this printer is configured as fax
     929                 :          0 :     sal_Int32 nIndex = 0;
     930 [ #  # ][ #  # ]:          0 :     const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) );
     931         [ #  # ]:          0 :     while( nIndex != -1 )
     932                 :            :     {
     933                 :          0 :         OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) );
     934         [ #  # ]:          0 :         if( ! aToken.compareToAscii( "fax", 3 ) )
     935                 :            :         {
     936                 :          0 :             m_bFax = true;
     937         [ #  # ]:          0 :             m_aTmpFile = getTmpName();
     938                 :          0 :             nMode = S_IRUSR | S_IWUSR;
     939                 :            : 
     940                 :          0 :             ::boost::unordered_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it;
     941 [ #  # ][ #  # ]:          0 :             it = pJobSetup->maValueMap.find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FAX#")) );
     942 [ #  # ][ #  # ]:          0 :             if( it != pJobSetup->maValueMap.end() )
     943         [ #  # ]:          0 :                 m_aFaxNr = it->second;
     944                 :            : 
     945                 :          0 :             sal_Int32 nPos = 0;
     946                 :          0 :             m_bSwallowFaxNo = ! aToken.getToken( 1, '=', nPos ).compareToAscii( "swallow", 7 ) ? true : false;
     947                 :            : 
     948                 :            :             break;
     949                 :            :         }
     950         [ #  # ]:          0 :         if( ! aToken.compareToAscii( "pdf=", 4 ) )
     951                 :            :         {
     952                 :          0 :             m_bPdf = true;
     953         [ #  # ]:          0 :             m_aTmpFile = getTmpName();
     954                 :          0 :             nMode = S_IRUSR | S_IWUSR;
     955                 :            : 
     956         [ #  # ]:          0 :             if( m_aFileName.isEmpty() )
     957                 :            :             {
     958 [ #  # ][ #  # ]:          0 :                 rtl::OUStringBuffer aFileName( getPdfDir( rInfo ) );
     959         [ #  # ]:          0 :                 aFileName.append( '/' );
     960         [ #  # ]:          0 :                 aFileName.append( rJobName );
     961         [ #  # ]:          0 :                 aFileName.appendAscii( RTL_CONSTASCII_STRINGPARAM( ".pdf" ) );
     962         [ #  # ]:          0 :                 m_aFileName = aFileName.makeStringAndClear();
     963                 :            :             }
     964                 :            :             break;
     965                 :            :         }
     966         [ #  # ]:          0 :     }
     967                 :            : #endif
     968         [ #  # ]:          0 :     m_aPrinterGfx.Init( m_aJobData );
     969                 :            : 
     970 [ #  # ][ #  # ]:          0 :     return m_aPrintJob.StartJob( ! m_aTmpFile.isEmpty() ? m_aTmpFile : m_aFileName, nMode, rJobName, rAppName, m_aJobData, &m_aPrinterGfx, bDirect ) ? sal_True : sal_False;
                 [ #  # ]
     971                 :            : }
     972                 :            : 
     973                 :          0 : sal_Bool PspSalPrinter::EndJob()
     974                 :            : {
     975                 :          0 :     sal_Bool bSuccess = sal_False;
     976         [ #  # ]:          0 :     if( m_bIsPDFWriterJob )
     977                 :          0 :         bSuccess = sal_True;
     978                 :            :     else
     979                 :            :     {
     980                 :          0 :         bSuccess = m_aPrintJob.EndJob();
     981                 :            :        OSL_TRACE("PspSalPrinter::EndJob %d", bSuccess);
     982                 :            : 
     983         [ #  # ]:          0 :         if( bSuccess )
     984                 :            :         {
     985                 :            :             // check for fax
     986         [ #  # ]:          0 :             if( m_bFax )
     987                 :            :             {
     988                 :          0 :                 const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) );
     989                 :            :                 // sendAFax removes the file after use
     990                 :          0 :                 bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand );
     991                 :            :             }
     992         [ #  # ]:          0 :             else if( m_bPdf )
     993                 :            :             {
     994                 :          0 :                 const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) );
     995                 :          0 :                 bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand );
     996                 :            :             }
     997                 :            :         }
     998                 :            :     }
     999                 :          0 :     GetSalData()->m_pInstance->jobEndedPrinterUpdate();
    1000                 :          0 :     return bSuccess;
    1001                 :            : }
    1002                 :            : 
    1003                 :          0 : sal_Bool PspSalPrinter::AbortJob()
    1004                 :            : {
    1005         [ #  # ]:          0 :     sal_Bool bAbort = m_aPrintJob.AbortJob() ? sal_True : sal_False;
    1006                 :          0 :     GetSalData()->m_pInstance->jobEndedPrinterUpdate();
    1007                 :          0 :     return bAbort;
    1008                 :            : }
    1009                 :            : 
    1010                 :          0 : SalGraphics* PspSalPrinter::StartPage( ImplJobSetup* pJobSetup, sal_Bool )
    1011                 :            : {
    1012                 :            :     OSL_TRACE("PspSalPrinter::StartPage");
    1013                 :            : 
    1014                 :          0 :     JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData );
    1015                 :          0 :     m_pGraphics = GetGenericInstance()->CreatePrintGraphics();
    1016                 :            :     m_pGraphics->Init( &m_aJobData, &m_aPrinterGfx, m_bFax ? &m_aFaxNr : NULL,
    1017         [ #  # ]:          0 :                        m_bSwallowFaxNo, m_pInfoPrinter );
    1018         [ #  # ]:          0 :     if( m_nCopies > 1 )
    1019                 :            :     {
    1020                 :            :         // in case user did not do anything (m_nCopies=1)
    1021                 :            :         // take the default from jobsetup
    1022                 :          0 :         m_aJobData.m_nCopies = m_nCopies;
    1023 [ #  # ][ #  # ]:          0 :         m_aJobData.setCollate( m_nCopies > 1 && m_bCollate );
    1024                 :            :     }
    1025                 :            : 
    1026                 :          0 :     m_aPrintJob.StartPage( m_aJobData );
    1027                 :          0 :     m_aPrinterGfx.Init( m_aPrintJob );
    1028                 :            : 
    1029                 :          0 :     return m_pGraphics;
    1030                 :            : }
    1031                 :            : 
    1032                 :          0 : sal_Bool PspSalPrinter::EndPage()
    1033                 :            : {
    1034                 :          0 :     sal_Bool bResult = m_aPrintJob.EndPage();
    1035                 :          0 :     m_aPrinterGfx.Clear();
    1036                 :            :     OSL_TRACE("PspSalPrinter::EndPage");
    1037         [ #  # ]:          0 :     return bResult ? sal_True : sal_False;
    1038                 :            : }
    1039                 :            : 
    1040                 :          0 : sal_uLong PspSalPrinter::GetErrorCode()
    1041                 :            : {
    1042                 :          0 :     return 0;
    1043                 :            : }
    1044                 :            : 
    1045                 :            : struct PDFNewJobParameters
    1046                 :            : {
    1047                 :            :     Size        maPageSize;
    1048                 :            :     sal_uInt16      mnPaperBin;
    1049                 :            : 
    1050                 :          0 :     PDFNewJobParameters( const Size& i_rSize = Size(),
    1051                 :            :                          sal_uInt16 i_nPaperBin = 0xffff )
    1052                 :          0 :     : maPageSize( i_rSize ), mnPaperBin( i_nPaperBin ) {}
    1053                 :            : 
    1054                 :          0 :     bool operator!=(const PDFNewJobParameters& rComp ) const
    1055                 :            :     {
    1056                 :          0 :         Size aCompLSSize( rComp.maPageSize.Height(), rComp.maPageSize.Width() );
    1057                 :            :         return
    1058                 :          0 :             (maPageSize != rComp.maPageSize && maPageSize != aCompLSSize)
    1059         [ #  # ]:          0 :         ||  mnPaperBin != rComp.mnPaperBin
           [ #  #  #  # ]
    1060                 :            :         ;
    1061                 :            :     }
    1062                 :            : 
    1063                 :            :     bool operator==(const PDFNewJobParameters& rComp) const
    1064                 :            :     {
    1065                 :            :         return ! this->operator!=(rComp);
    1066                 :            :     }
    1067                 :            : };
    1068                 :            : 
    1069                 :          0 : struct PDFPrintFile
    1070                 :            : {
    1071                 :            :     rtl::OUString       maTmpURL;
    1072                 :            :     PDFNewJobParameters maParameters;
    1073                 :            : 
    1074                 :          0 :     PDFPrintFile( const rtl::OUString& i_rURL, const PDFNewJobParameters& i_rNewParameters )
    1075                 :            :     : maTmpURL( i_rURL )
    1076                 :          0 :     , maParameters( i_rNewParameters ) {}
    1077                 :            : };
    1078                 :            : 
    1079                 :          0 : sal_Bool PspSalPrinter::StartJob( const rtl::OUString* i_pFileName, const rtl::OUString& i_rJobName, const rtl::OUString& i_rAppName,
    1080                 :            :                               ImplJobSetup* i_pSetupData, vcl::PrinterController& i_rController )
    1081                 :            : {
    1082                 :            :     OSL_TRACE( "StartJob with controller: pFilename = %s", i_pFileName ? rtl::OUStringToOString( *i_pFileName, RTL_TEXTENCODING_UTF8 ).getStr() : "<nil>" );
    1083                 :            :     // mark for endjob
    1084                 :          0 :     m_bIsPDFWriterJob = true;
    1085                 :            :     // reset IsLastPage
    1086         [ #  # ]:          0 :     i_rController.setLastPage( sal_False );
    1087                 :            : 
    1088                 :            :     // update job data
    1089         [ #  # ]:          0 :     if( i_pSetupData )
    1090         [ #  # ]:          0 :         JobData::constructFromStreamBuffer( i_pSetupData->mpDriverData, i_pSetupData->mnDriverDataLen, m_aJobData );
    1091                 :            : 
    1092                 :            :     OSL_ASSERT( m_aJobData.m_nPDFDevice > 0 );
    1093                 :          0 :     m_aJobData.m_nPDFDevice = 1;
    1094                 :            : 
    1095                 :            :     // possibly create one job for collated output
    1096                 :          0 :     sal_Bool bSinglePrintJobs = sal_False;
    1097 [ #  # ][ #  # ]:          0 :     beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) );
    1098         [ #  # ]:          0 :     if( pSingleValue )
    1099                 :            :     {
    1100                 :          0 :         pSingleValue->Value >>= bSinglePrintJobs;
    1101                 :            :     }
    1102                 :            : 
    1103         [ #  # ]:          0 :     int nCopies = i_rController.getPrinter()->GetCopyCount();
    1104         [ #  # ]:          0 :     bool bCollate = i_rController.getPrinter()->IsCollateCopy();
    1105                 :            : 
    1106                 :            :     // notify start of real print job
    1107         [ #  # ]:          0 :     i_rController.jobStarted();
    1108                 :            : 
    1109                 :            :     // setup PDFWriter context
    1110         [ #  # ]:          0 :     vcl::PDFWriter::PDFWriterContext aContext;
    1111                 :          0 :     aContext.Version            = vcl::PDFWriter::PDF_1_4;
    1112                 :          0 :     aContext.Tagged             = false;
    1113                 :          0 :     aContext.EmbedStandardFonts = true;
    1114 [ #  # ][ #  # ]:          0 :     aContext.DocumentLocale     = Application::GetSettings().GetLocale();
    1115         [ #  # ]:          0 :     aContext.ColorMode          = i_rController.getPrinter()->GetPrinterOptions().IsConvertToGreyscales()
    1116         [ #  # ]:          0 :     ? vcl::PDFWriter::DrawGreyscale : vcl::PDFWriter::DrawColor;
    1117                 :            : 
    1118                 :            :     // prepare doc info
    1119         [ #  # ]:          0 :     aContext.DocumentInfo.Title              = i_rJobName;
    1120         [ #  # ]:          0 :     aContext.DocumentInfo.Creator            = i_rAppName;
    1121         [ #  # ]:          0 :     aContext.DocumentInfo.Producer           = i_rAppName;
    1122                 :            : 
    1123                 :            :     // define how we handle metafiles in PDFWriter
    1124                 :          0 :     vcl::PDFWriter::PlayMetafileContext aMtfContext;
    1125                 :          0 :     aMtfContext.m_bOnlyLosslessCompression = true;
    1126                 :            : 
    1127         [ #  # ]:          0 :     boost::shared_ptr<vcl::PDFWriter> pWriter;
    1128         [ #  # ]:          0 :     std::vector< PDFPrintFile > aPDFFiles;
    1129 [ #  # ][ #  # ]:          0 :     boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() );
    1130         [ #  # ]:          0 :     int nAllPages = i_rController.getFilteredPageCount();
    1131         [ #  # ]:          0 :     i_rController.createProgressDialog();
    1132                 :          0 :     bool bAborted = false;
    1133                 :          0 :     PDFNewJobParameters aLastParm;
    1134                 :            : 
    1135                 :          0 :     aContext.DPIx = pPrinter->ImplGetDPIX();
    1136                 :          0 :     aContext.DPIy = pPrinter->ImplGetDPIY();
    1137 [ #  # ][ #  # ]:          0 :     for( int nPage = 0; nPage < nAllPages && ! bAborted; nPage++ )
                 [ #  # ]
    1138                 :            :     {
    1139         [ #  # ]:          0 :         if( nPage == nAllPages-1 )
    1140         [ #  # ]:          0 :             i_rController.setLastPage( sal_True );
    1141                 :            : 
    1142                 :            :         // get the page's metafile
    1143         [ #  # ]:          0 :         GDIMetaFile aPageFile;
    1144         [ #  # ]:          0 :         vcl::PrinterController::PageSize aPageSize = i_rController.getFilteredPageFile( nPage, aPageFile );
    1145 [ #  # ][ #  # ]:          0 :         if( i_rController.isProgressCanceled() )
    1146                 :            :         {
    1147                 :          0 :             bAborted = true;
    1148         [ #  # ]:          0 :             if( nPage != nAllPages-1 )
    1149                 :            :             {
    1150         [ #  # ]:          0 :                 i_rController.createProgressDialog();
    1151         [ #  # ]:          0 :                 i_rController.setLastPage( sal_True );
    1152         [ #  # ]:          0 :                 i_rController.getFilteredPageFile( nPage, aPageFile );
    1153                 :            :             }
    1154                 :            :         }
    1155                 :            :         else
    1156                 :            :         {
    1157 [ #  # ][ #  # ]:          0 :             pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
                 [ #  # ]
    1158         [ #  # ]:          0 :             pPrinter->SetPaperSizeUser( aPageSize.aSize, true );
    1159 [ #  # ][ #  # ]:          0 :             PDFNewJobParameters aNewParm( pPrinter->GetPaperSize(), pPrinter->GetPaperBin() );
    1160                 :            : 
    1161                 :            :             // create PDF writer on demand
    1162                 :            :             // either on first page
    1163                 :            :             // or on paper format change - cups does not support multiple paper formats per job (yet?)
    1164                 :            :             // so we need to start a new job to get a new paper format from the printer
    1165                 :            :             // orientation switches (that is switch of height and width) is handled transparently by CUPS
    1166 [ #  # ][ #  # ]:          0 :             if( ! pWriter ||
           [ #  #  #  # ]
    1167                 :          0 :                 (aNewParm != aLastParm && ! i_pFileName ) )
    1168                 :            :             {
    1169         [ #  # ]:          0 :                 if( pWriter )
    1170                 :            :                 {
    1171         [ #  # ]:          0 :                     pWriter->Emit();
    1172                 :            :                 }
    1173                 :            :                 // produce PDF file
    1174                 :          0 :                 OUString aPDFUrl;
    1175         [ #  # ]:          0 :                 if( i_pFileName )
    1176                 :          0 :                     aPDFUrl = *i_pFileName;
    1177                 :            :                 else
    1178         [ #  # ]:          0 :                     osl_createTempFile( NULL, NULL, &aPDFUrl.pData );
    1179                 :            :                 // normalize to file URL
    1180         [ #  # ]:          0 :                 if( aPDFUrl.compareToAscii( "file:", 5 ) != 0 )
    1181                 :            :                 {
    1182                 :            :                     // this is not a file URL, but it should
    1183                 :            :                     // form it into a osl friendly file URL
    1184                 :          0 :                     rtl::OUString aTmp;
    1185         [ #  # ]:          0 :                     osl_getFileURLFromSystemPath( aPDFUrl.pData, &aTmp.pData );
    1186                 :          0 :                     aPDFUrl = aTmp;
    1187                 :            :                 }
    1188                 :            :                 // save current file and paper format
    1189                 :          0 :                 aLastParm = aNewParm;
    1190         [ #  # ]:          0 :                 aPDFFiles.push_back( PDFPrintFile( aPDFUrl, aNewParm ) );
    1191                 :            :                 // update context
    1192                 :          0 :                 aContext.URL = aPDFUrl;
    1193                 :            : 
    1194                 :            :                 // create and initialize PDFWriter
    1195                 :            :                 #if defined __SUNPRO_CC
    1196                 :            :                 #pragma disable_warn
    1197                 :            :                 #endif
    1198 [ #  # ][ #  # ]:          0 :                 pWriter.reset( new vcl::PDFWriter( aContext, uno::Reference< beans::XMaterialHolder >() ) );
                 [ #  # ]
    1199                 :            :                 #if defined __SUNPRO_CC
    1200                 :            :                 #pragma enable_warn
    1201                 :            :                 #endif
    1202                 :            :             }
    1203                 :            : 
    1204                 :          0 :             pWriter->NewPage( TenMuToPt( aNewParm.maPageSize.Width() ),
    1205                 :          0 :                               TenMuToPt( aNewParm.maPageSize.Height() ),
    1206         [ #  # ]:          0 :                               vcl::PDFWriter::Portrait );
    1207                 :            : 
    1208         [ #  # ]:          0 :             pWriter->PlayMetafile( aPageFile, aMtfContext, NULL );
    1209                 :            :         }
    1210         [ #  # ]:          0 :     }
    1211                 :            : 
    1212                 :            :     // emit the last file
    1213         [ #  # ]:          0 :     if( pWriter )
    1214         [ #  # ]:          0 :         pWriter->Emit();
    1215                 :            : 
    1216                 :            :     // handle collate, copy count and multiple jobs correctly
    1217                 :          0 :     int nOuterJobs = 1;
    1218         [ #  # ]:          0 :     if( bSinglePrintJobs )
    1219                 :            :     {
    1220                 :          0 :         nOuterJobs = nCopies;
    1221                 :          0 :         m_aJobData.m_nCopies = 1;
    1222                 :            :     }
    1223                 :            :     else
    1224                 :            :     {
    1225         [ #  # ]:          0 :         if( bCollate )
    1226                 :            :         {
    1227 [ #  # ][ #  # ]:          0 :             if( aPDFFiles.size() == 1 && pPrinter->HasSupport( SUPPORT_COLLATECOPY ) )
         [ #  # ][ #  # ]
    1228                 :            :             {
    1229         [ #  # ]:          0 :                 m_aJobData.setCollate( true );
    1230                 :          0 :                 m_aJobData.m_nCopies = nCopies;
    1231                 :            :             }
    1232                 :            :             else
    1233                 :            :             {
    1234                 :          0 :                 nOuterJobs = nCopies;
    1235                 :          0 :                 m_aJobData.m_nCopies = 1;
    1236                 :            :             }
    1237                 :            :         }
    1238                 :            :         else
    1239                 :            :         {
    1240         [ #  # ]:          0 :             m_aJobData.setCollate( false );
    1241                 :          0 :             m_aJobData.m_nCopies = nCopies;
    1242                 :            :         }
    1243                 :            :     }
    1244                 :            : 
    1245                 :            :     // spool files
    1246 [ #  # ][ #  # ]:          0 :     if( ! i_pFileName && ! bAborted )
    1247                 :            :     {
    1248                 :          0 :         bool bFirstJob = true;
    1249         [ #  # ]:          0 :         for( int nCurJob = 0; nCurJob < nOuterJobs; nCurJob++ )
    1250                 :            :         {
    1251         [ #  # ]:          0 :             for( size_t i = 0; i < aPDFFiles.size(); i++ )
    1252                 :            :             {
    1253                 :          0 :                 oslFileHandle pFile = NULL;
    1254         [ #  # ]:          0 :                 osl_openFile( aPDFFiles[i].maTmpURL.pData, &pFile, osl_File_OpenFlag_Read );
    1255 [ #  # ][ #  # ]:          0 :                 if (pFile && (osl_setFilePos(pFile, osl_Pos_Absolut, 0) == osl_File_E_None))
         [ #  # ][ #  # ]
    1256                 :            :                 {
    1257         [ #  # ]:          0 :                     std::vector< char > buffer( 0x10000, 0 );
    1258                 :            :                     // update job data with current page size
    1259                 :          0 :                     Size aPageSize( aPDFFiles[i].maParameters.maPageSize );
    1260         [ #  # ]:          0 :                     m_aJobData.setPaper( TenMuToPt( aPageSize.Width() ), TenMuToPt( aPageSize.Height() ) );
    1261                 :            :                     // update job data with current paperbin
    1262         [ #  # ]:          0 :                     m_aJobData.setPaperBin( aPDFFiles[i].maParameters.mnPaperBin );
    1263                 :            : 
    1264                 :            :                     // spool current file
    1265 [ #  # ][ #  # ]:          0 :                     FILE* fp = PrinterInfoManager::get().startSpool( pPrinter->GetName(), i_rController.isDirectPrint() );
                 [ #  # ]
    1266         [ #  # ]:          0 :                     if( fp )
    1267                 :            :                     {
    1268                 :          0 :                         sal_uInt64 nBytesRead = 0;
    1269         [ #  # ]:          0 :                         do
    1270                 :            :                         {
    1271 [ #  # ][ #  # ]:          0 :                             osl_readFile( pFile, &buffer[0], buffer.size(), &nBytesRead );
    1272         [ #  # ]:          0 :                             if( nBytesRead > 0 )
    1273                 :            :                             {
    1274 [ #  # ][ #  # ]:          0 :                                 size_t nBytesWritten = fwrite(&buffer[0], 1, nBytesRead, fp);
    1275                 :            :                                 OSL_ENSURE(nBytesRead == nBytesWritten, "short write");
    1276         [ #  # ]:          0 :                                 if (nBytesRead != nBytesWritten)
    1277                 :          0 :                                     break;
    1278                 :            :                             }
    1279                 :          0 :                         } while( nBytesRead == buffer.size() );
    1280                 :          0 :                         rtl::OUStringBuffer aBuf( i_rJobName.getLength() + 8 );
    1281         [ #  # ]:          0 :                         aBuf.append( i_rJobName );
    1282 [ #  # ][ #  # ]:          0 :                         if( i > 0 || nCurJob > 0 )
    1283                 :            :                         {
    1284         [ #  # ]:          0 :                             aBuf.append( sal_Unicode(' ') );
    1285         [ #  # ]:          0 :                             aBuf.append( sal_Int32( i + nCurJob * aPDFFiles.size() ) );
    1286                 :            :                         }
    1287 [ #  # ][ #  # ]:          0 :                         PrinterInfoManager::get().endSpool( pPrinter->GetName(), aBuf.makeStringAndClear(), fp, m_aJobData, bFirstJob );
                 [ #  # ]
    1288                 :          0 :                         bFirstJob = false;
    1289                 :          0 :                     }
    1290                 :            :                 }
    1291         [ #  # ]:          0 :                 osl_closeFile( pFile );
    1292                 :            :             }
    1293                 :            :         }
    1294                 :            :     }
    1295                 :            : 
    1296                 :            :     // job has been spooled
    1297 [ #  # ][ #  # ]:          0 :     i_rController.setJobState( bAborted ? view::PrintableState_JOB_ABORTED : view::PrintableState_JOB_SPOOLED );
    1298                 :            : 
    1299                 :            :     // clean up the temporary PDF files
    1300 [ #  # ][ #  # ]:          0 :     if( ! i_pFileName || bAborted )
    1301                 :            :     {
    1302         [ #  # ]:          0 :         for( size_t i = 0; i < aPDFFiles.size(); i++ )
    1303                 :            :         {
    1304         [ #  # ]:          0 :             osl_removeFile( aPDFFiles[i].maTmpURL.pData );
    1305                 :            :             OSL_TRACE( "removed print PDF file %s", rtl::OUStringToOString( aPDFFiles[i].maTmpURL, RTL_TEXTENCODING_UTF8 ).getStr() );
    1306                 :            :         }
    1307                 :            :     }
    1308                 :            : 
    1309 [ #  # ][ #  # ]:          0 :     return sal_True;
                 [ #  # ]
    1310                 :            : }
    1311                 :            : 
    1312                 :            : 
    1313                 :            : class PrinterUpdate
    1314                 :            : {
    1315                 :            :     static Timer* pPrinterUpdateTimer;
    1316                 :            :     static int    nActiveJobs;
    1317                 :            : 
    1318                 :            :     static void doUpdate();
    1319                 :            :     DECL_STATIC_LINK( PrinterUpdate, UpdateTimerHdl, void* );
    1320                 :            : public:
    1321                 :            :     static void update(SalGenericInstance &rInstance);
    1322                 :          0 :     static void jobStarted() { nActiveJobs++; }
    1323                 :            :     static void jobEnded();
    1324                 :            : };
    1325                 :            : 
    1326                 :            : Timer* PrinterUpdate::pPrinterUpdateTimer = NULL;
    1327                 :            : int PrinterUpdate::nActiveJobs = 0;
    1328                 :            : 
    1329                 :          0 : void PrinterUpdate::doUpdate()
    1330                 :            : {
    1331                 :          0 :     ::psp::PrinterInfoManager& rManager( ::psp::PrinterInfoManager::get() );
    1332                 :          0 :     SalGenericInstance *pInst = static_cast<SalGenericInstance *>( GetSalData()->m_pInstance );
    1333 [ #  # ][ #  # ]:          0 :     if( pInst && rManager.checkPrintersChanged( false ) )
                 [ #  # ]
    1334                 :          0 :         pInst->PostPrintersChanged();
    1335                 :          0 : }
    1336                 :            : 
    1337                 :            : // -----------------------------------------------------------------------
    1338                 :            : 
    1339                 :          0 : IMPL_STATIC_LINK_NOINSTANCE( PrinterUpdate, UpdateTimerHdl, void*, EMPTYARG )
    1340                 :            : {
    1341         [ #  # ]:          0 :     if( nActiveJobs < 1 )
    1342                 :            :     {
    1343                 :          0 :         doUpdate();
    1344         [ #  # ]:          0 :         delete pPrinterUpdateTimer;
    1345                 :          0 :         pPrinterUpdateTimer = NULL;
    1346                 :            :     }
    1347                 :            :     else
    1348                 :          0 :         pPrinterUpdateTimer->Start();
    1349                 :            : 
    1350                 :          0 :     return 0;
    1351                 :            : }
    1352                 :            : 
    1353                 :          0 : void PrinterUpdate::update(SalGenericInstance &rInstance)
    1354                 :            : {
    1355         [ #  # ]:          0 :     if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
    1356                 :          0 :         return;
    1357                 :            : 
    1358         [ #  # ]:          0 :     if( ! rInstance.isPrinterInit() )
    1359                 :            :     {
    1360                 :            :         // #i45389# start background printer detection
    1361                 :          0 :         psp::PrinterInfoManager::get();
    1362                 :          0 :         return;
    1363                 :            :     }
    1364                 :            : 
    1365         [ #  # ]:          0 :     if( nActiveJobs < 1 )
    1366                 :          0 :         doUpdate();
    1367         [ #  # ]:          0 :     else if( ! pPrinterUpdateTimer )
    1368                 :            :     {
    1369         [ #  # ]:          0 :         pPrinterUpdateTimer = new Timer();
    1370                 :          0 :         pPrinterUpdateTimer->SetTimeout( 500 );
    1371                 :          0 :         pPrinterUpdateTimer->SetTimeoutHdl( STATIC_LINK( NULL, PrinterUpdate, UpdateTimerHdl ) );
    1372                 :          0 :         pPrinterUpdateTimer->Start();
    1373                 :            :     }
    1374                 :            : }
    1375                 :            : 
    1376                 :          0 : void SalGenericInstance::updatePrinterUpdate()
    1377                 :            : {
    1378                 :          0 :     PrinterUpdate::update(*this);
    1379                 :          0 : }
    1380                 :            : 
    1381                 :          0 : void SalGenericInstance::jobStartedPrinterUpdate()
    1382                 :            : {
    1383                 :          0 :     PrinterUpdate::jobStarted();
    1384                 :          0 : }
    1385                 :            : 
    1386                 :          0 : void PrinterUpdate::jobEnded()
    1387                 :            : {
    1388                 :          0 :     nActiveJobs--;
    1389         [ #  # ]:          0 :     if( nActiveJobs < 1 )
    1390                 :            :     {
    1391         [ #  # ]:          0 :         if( pPrinterUpdateTimer )
    1392                 :            :         {
    1393                 :          0 :             pPrinterUpdateTimer->Stop();
    1394         [ #  # ]:          0 :             delete pPrinterUpdateTimer;
    1395                 :          0 :             pPrinterUpdateTimer = NULL;
    1396                 :          0 :             doUpdate();
    1397                 :            :         }
    1398                 :            :     }
    1399                 :          0 : }
    1400                 :            : 
    1401                 :          0 : void SalGenericInstance::jobEndedPrinterUpdate()
    1402                 :            : {
    1403                 :          0 :     PrinterUpdate::jobEnded();
    1404                 :          0 : }
    1405                 :            : 
    1406                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10