LCOV - code coverage report
Current view: top level - libreoffice/sfx2/source/doc - printhelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 31 348 8.9 %
Date: 2012-12-27 Functions: 9 31 29.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "printhelper.hxx"
      22             : 
      23             : #include <com/sun/star/view/XPrintJob.hpp>
      24             : #include <com/sun/star/awt/Size.hpp>
      25             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      26             : #include <com/sun/star/view/PaperFormat.hpp>
      27             : #include <com/sun/star/view/PaperOrientation.hpp>
      28             : #include <com/sun/star/ucb/NameClash.hpp>
      29             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      30             : #include <com/sun/star/frame/XModel.hpp>
      31             : #include <com/sun/star/lang/EventObject.hpp>
      32             : #include <com/sun/star/view/DuplexMode.hpp>
      33             : #include <comphelper/processfactory.hxx>
      34             : #include <svl/lstner.hxx>
      35             : #include <svl/stritem.hxx>
      36             : #include <svl/intitem.hxx>
      37             : #include <svl/eitem.hxx>
      38             : #include <unotools/tempfile.hxx>
      39             : #include <unotools/localfilehelper.hxx>
      40             : #include <osl/file.hxx>
      41             : #include <osl/thread.hxx>
      42             : #include <tools/urlobj.hxx>
      43             : #include <ucbhelper/content.hxx>
      44             : #include <cppuhelper/interfacecontainer.hxx>
      45             : #include <osl/mutex.hxx>
      46             : #include <cppuhelper/implbase1.hxx>
      47             : 
      48             : #include <sfx2/viewfrm.hxx>
      49             : #include <sfx2/viewsh.hxx>
      50             : #include <sfx2/dispatch.hxx>
      51             : #include <sfx2/request.hxx>
      52             : #include <sfx2/printer.hxx>
      53             : #include <sfx2/app.hxx>
      54             : #include <sfx2/objsh.hxx>
      55             : #include <sfx2/event.hxx>
      56             : 
      57             : using namespace ::com::sun::star;
      58             : using namespace ::com::sun::star::uno;
      59             : 
      60         530 : struct IMPL_PrintListener_DataContainer : public SfxListener
      61             : {
      62             :     SfxObjectShellRef                               m_pObjectShell;
      63             :     ::cppu::OMultiTypeInterfaceContainerHelper      m_aInterfaceContainer;
      64             :     uno::Reference< com::sun::star::view::XPrintJob>     m_xPrintJob;
      65             :     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aPrintOptions;
      66             : 
      67         501 :     IMPL_PrintListener_DataContainer( ::osl::Mutex& aMutex)
      68             :             :   m_pObjectShell          ( 0 )
      69         501 :             ,   m_aInterfaceContainer   ( aMutex )
      70             :     {
      71         501 :     }
      72             : 
      73             : 
      74             :     void Notify(            SfxBroadcaster& aBC     ,
      75             :                     const   SfxHint&        aHint   ) ;
      76             : };
      77             : 
      78           0 : awt::Size impl_Size_Object2Struct( const Size& aSize )
      79             : {
      80           0 :     awt::Size aReturnValue;
      81           0 :     aReturnValue.Width  = aSize.Width()  ;
      82           0 :     aReturnValue.Height = aSize.Height() ;
      83           0 :     return aReturnValue ;
      84             : }
      85             : 
      86           0 : Size impl_Size_Struct2Object( const awt::Size& aSize )
      87             : {
      88           0 :     Size aReturnValue;
      89           0 :     aReturnValue.Width()  = aSize.Width  ;
      90           0 :     aReturnValue.Height() = aSize.Height ;
      91           0 :     return aReturnValue ;
      92             : }
      93             : 
      94           0 : class SfxPrintJob_Impl : public cppu::WeakImplHelper1
      95             : <
      96             :     com::sun::star::view::XPrintJob
      97             : >
      98             : {
      99             :         IMPL_PrintListener_DataContainer* m_pData;
     100             : 
     101             : public:
     102             :         SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData );
     103             :         virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrintOptions(  ) throw (RuntimeException);
     104             :         virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrinter(  ) throw (RuntimeException);
     105             :         virtual Reference< ::com::sun::star::view::XPrintable > SAL_CALL getPrintable(  ) throw (RuntimeException);
     106             :         virtual void SAL_CALL cancelJob() throw (RuntimeException);
     107             : };
     108             : 
     109           0 : SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData )
     110           0 :     : m_pData( pData )
     111             : {
     112           0 : }
     113             : 
     114           0 : Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrintOptions() throw (RuntimeException)
     115             : {
     116           0 :     return m_pData->m_aPrintOptions;
     117             : }
     118             : 
     119           0 : Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrinter() throw (RuntimeException)
     120             : {
     121           0 :     if( m_pData->m_pObjectShell.Is() )
     122             :     {
     123           0 :         Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell->GetModel(), UNO_QUERY );
     124           0 :         if ( xPrintable.is() )
     125           0 :             return xPrintable->getPrinter();
     126             :     }
     127           0 :     return Sequence< ::com::sun::star::beans::PropertyValue >();
     128             : }
     129             : 
     130           0 : Reference< ::com::sun::star::view::XPrintable > SAL_CALL SfxPrintJob_Impl::getPrintable() throw (RuntimeException)
     131             : {
     132           0 :     Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->GetModel() : NULL, UNO_QUERY );
     133           0 :     return xPrintable;
     134             : }
     135             : 
     136           0 : void SAL_CALL SfxPrintJob_Impl::cancelJob() throw (RuntimeException)
     137             : {
     138             :     // FIXME: how to cancel PrintJob via API?!
     139           0 :     if( m_pData->m_pObjectShell.Is() )
     140           0 :         m_pData->m_pObjectShell->Broadcast( SfxPrintingHint( -2 ) );
     141           0 : }
     142             : 
     143         501 : SfxPrintHelper::SfxPrintHelper()
     144             : {
     145         501 :     m_pData = new IMPL_PrintListener_DataContainer(m_aMutex);
     146         501 : }
     147             : 
     148         501 : void SAL_CALL SfxPrintHelper::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
     149             : {
     150         501 :     if ( aArguments.getLength() )
     151             :     {
     152         501 :         com::sun::star::uno::Reference < com::sun::star::frame::XModel > xModel;
     153         501 :         aArguments[0] >>= xModel;
     154         501 :         uno::Reference < lang::XUnoTunnel > xObj( xModel, uno::UNO_QUERY );
     155         501 :         uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
     156         501 :         sal_Int64 nHandle = xObj->getSomething( aSeq );
     157         501 :         if ( nHandle )
     158             :         {
     159         501 :             m_pData->m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
     160         501 :             m_pData->StartListening(*m_pData->m_pObjectShell);
     161         501 :         }
     162             :     }
     163         501 : }
     164             : 
     165         795 : SfxPrintHelper::~SfxPrintHelper()
     166             : {
     167         265 :     delete m_pData;
     168         530 : }
     169             : 
     170             : namespace
     171             : {
     172           0 :     view::PaperFormat convertToPaperFormat(Paper eFormat)
     173             :     {
     174             :         view::PaperFormat eRet;
     175           0 :         switch (eFormat)
     176             :         {
     177             :             case PAPER_A3:
     178           0 :                 eRet = view::PaperFormat_A3;
     179           0 :                 break;
     180             :             case PAPER_A4:
     181           0 :                 eRet = view::PaperFormat_A4;
     182           0 :                 break;
     183             :             case PAPER_A5:
     184           0 :                 eRet = view::PaperFormat_A5;
     185           0 :                 break;
     186             :             case PAPER_B4_ISO:
     187           0 :                 eRet = view::PaperFormat_B4;
     188           0 :                 break;
     189             :             case PAPER_B5_ISO:
     190           0 :                 eRet = view::PaperFormat_B5;
     191           0 :                 break;
     192             :             case PAPER_LETTER:
     193           0 :                 eRet = view::PaperFormat_LETTER;
     194           0 :                 break;
     195             :             case PAPER_LEGAL:
     196           0 :                 eRet = view::PaperFormat_LEGAL;
     197           0 :                 break;
     198             :             case PAPER_TABLOID:
     199           0 :                 eRet = view::PaperFormat_TABLOID;
     200           0 :                 break;
     201             :             case PAPER_USER:
     202             :             default:
     203           0 :                 eRet = view::PaperFormat_USER;
     204           0 :                 break;
     205             :         }
     206           0 :         return eRet;
     207             :     }
     208             : 
     209           0 :     Paper convertToPaper(view::PaperFormat eFormat)
     210             :     {
     211           0 :         Paper eRet(PAPER_USER);
     212           0 :         switch (eFormat)
     213             :         {
     214             :             case view::PaperFormat_A3:
     215           0 :                 eRet = PAPER_A3;
     216           0 :                 break;
     217             :             case view::PaperFormat_A4:
     218           0 :                 eRet = PAPER_A4;
     219           0 :                 break;
     220             :             case view::PaperFormat_A5:
     221           0 :                 eRet = PAPER_A5;
     222           0 :                 break;
     223             :             case view::PaperFormat_B4:
     224           0 :                 eRet = PAPER_B4_ISO;
     225           0 :                 break;
     226             :             case view::PaperFormat_B5:
     227           0 :                 eRet = PAPER_B5_ISO;
     228           0 :                 break;
     229             :             case view::PaperFormat_LETTER:
     230           0 :                 eRet = PAPER_LETTER;
     231           0 :                 break;
     232             :             case view::PaperFormat_LEGAL:
     233           0 :                 eRet = PAPER_LEGAL;
     234           0 :                 break;
     235             :             case view::PaperFormat_TABLOID:
     236           0 :                 eRet = PAPER_TABLOID;
     237           0 :                 break;
     238             :             case view::PaperFormat_USER:
     239           0 :                 eRet = PAPER_USER;
     240           0 :                 break;
     241             :             case view::PaperFormat_MAKE_FIXED_SIZE:
     242           0 :                 break;
     243             :             //deliberate no default to force warn on a new papersize
     244             :         }
     245           0 :         return eRet;
     246             :     }
     247             : }
     248             : 
     249             : //________________________________________________________________________________________________________
     250             : //  XPrintable
     251             : //________________________________________________________________________________________________________
     252             : 
     253           0 : uno::Sequence< beans::PropertyValue > SAL_CALL SfxPrintHelper::getPrinter() throw(::com::sun::star::uno::RuntimeException)
     254             : {
     255             :     // object already disposed?
     256           0 :     SolarMutexGuard aGuard;
     257             : 
     258             :     // search for any view of this document that is currently printing
     259           0 :     const Printer *pPrinter = NULL;
     260           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
     261           0 :     SfxViewFrame* pFirst = pViewFrm;
     262           0 :     while ( pViewFrm && !pPrinter )
     263             :     {
     264           0 :         pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
     265           0 :         pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell, sal_False );
     266             :     }
     267             : 
     268             :     // if no view is printing currently, use the permanent SfxPrinter instance
     269           0 :     if ( !pPrinter && pFirst )
     270           0 :         pPrinter = pFirst->GetViewShell()->GetPrinter(sal_True);
     271             : 
     272           0 :     if ( !pPrinter )
     273           0 :         return uno::Sequence< beans::PropertyValue >();
     274             : 
     275           0 :     uno::Sequence< beans::PropertyValue > aPrinter(8);
     276             : 
     277           0 :     aPrinter.getArray()[7].Name = DEFINE_CONST_UNICODE( "CanSetPaperSize" );
     278           0 :     aPrinter.getArray()[7].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPERSIZE ) );
     279             : 
     280           0 :     aPrinter.getArray()[6].Name = DEFINE_CONST_UNICODE( "CanSetPaperFormat" );
     281           0 :     aPrinter.getArray()[6].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPER ) );
     282             : 
     283           0 :     aPrinter.getArray()[5].Name = DEFINE_CONST_UNICODE( "CanSetPaperOrientation" );
     284           0 :     aPrinter.getArray()[5].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_ORIENTATION ) );
     285             : 
     286           0 :     aPrinter.getArray()[4].Name = DEFINE_CONST_UNICODE( "IsBusy" );
     287           0 :     aPrinter.getArray()[4].Value <<= ( pPrinter->IsPrinting() );
     288             : 
     289           0 :     aPrinter.getArray()[3].Name = DEFINE_CONST_UNICODE( "PaperSize" );
     290           0 :     awt::Size aSize = impl_Size_Object2Struct(pPrinter->GetPaperSize() );
     291           0 :     aPrinter.getArray()[3].Value <<= aSize;
     292             : 
     293           0 :     aPrinter.getArray()[2].Name = DEFINE_CONST_UNICODE( "PaperFormat" );
     294           0 :     view::PaperFormat eFormat = convertToPaperFormat(pPrinter->GetPaper());
     295           0 :     aPrinter.getArray()[2].Value <<= eFormat;
     296             : 
     297           0 :     aPrinter.getArray()[1].Name = DEFINE_CONST_UNICODE( "PaperOrientation" );
     298           0 :     view::PaperOrientation eOrient = (view::PaperOrientation)pPrinter->GetOrientation();
     299           0 :     aPrinter.getArray()[1].Value <<= eOrient;
     300             : 
     301           0 :     aPrinter.getArray()[0].Name = DEFINE_CONST_UNICODE( "Name" );
     302           0 :     String sStringTemp = pPrinter->GetName() ;
     303           0 :     aPrinter.getArray()[0].Value <<= ::rtl::OUString( sStringTemp );
     304             : 
     305           0 :     return aPrinter;
     306             : }
     307             : 
     308             : //________________________________________________________________________________________________________
     309             : //  XPrintable
     310             : //________________________________________________________________________________________________________
     311             : 
     312           0 : void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,SfxPrinter*& pPrinter,sal_uInt16& nChangeFlags,SfxViewShell*& pViewSh)
     313             : 
     314             : {
     315             :     // Get old Printer
     316           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
     317           0 :                                 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
     318           0 :     if ( !pViewFrm )
     319             :         return;
     320             : 
     321           0 :     pViewSh = pViewFrm->GetViewShell();
     322           0 :     pPrinter = pViewSh->GetPrinter(sal_True);
     323           0 :     if ( !pPrinter )
     324             :         return;
     325             : 
     326             :     // new Printer-Name available?
     327           0 :     nChangeFlags = 0;
     328           0 :     sal_Int32 lDummy = 0;
     329           0 :     for ( int n = 0; n < rPrinter.getLength(); ++n )
     330             :     {
     331             :         // get Property-Value from printer description
     332           0 :         const beans::PropertyValue &rProp = rPrinter.getConstArray()[n];
     333             : 
     334             :         // Name-Property?
     335           0 :         if ( rProp.Name.compareToAscii( "Name" ) == 0 )
     336             :         {
     337           0 :             ::rtl::OUString aPrinterName;
     338           0 :             if ( ! ( rProp.Value >>= aPrinterName ) )
     339           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     340             : 
     341           0 :             if ( aPrinterName != pPrinter->GetName() )
     342             :             {
     343           0 :                 pPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aPrinterName );
     344           0 :                 nChangeFlags = SFX_PRINTER_PRINTER;
     345             :             }
     346           0 :             break;
     347             :         }
     348             :     }
     349             : 
     350           0 :     Size aSetPaperSize( 0, 0);
     351           0 :     view::PaperFormat nPaperFormat = view::PaperFormat_USER;
     352             : 
     353             :     // other properties
     354           0 :     for ( int i = 0; i < rPrinter.getLength(); ++i )
     355             :     {
     356             :         // get Property-Value from printer description
     357           0 :         const beans::PropertyValue &rProp = rPrinter.getConstArray()[i];
     358             : 
     359             :         // PaperOrientation-Property?
     360           0 :         if ( rProp.Name.compareToAscii( "PaperOrientation" ) == 0 )
     361             :         {
     362             :             view::PaperOrientation eOrient;
     363           0 :             if ( ( rProp.Value >>= eOrient ) == sal_False )
     364             :             {
     365           0 :                 if ( ( rProp.Value >>= lDummy ) == sal_False )
     366           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     367           0 :                 eOrient = ( view::PaperOrientation) lDummy;
     368             :             }
     369             : 
     370           0 :             if ( (Orientation) eOrient != pPrinter->GetOrientation() )
     371             :             {
     372           0 :                 pPrinter->SetOrientation( (Orientation) eOrient );
     373           0 :                 nChangeFlags |= SFX_PRINTER_CHG_ORIENTATION;
     374             :             }
     375             :         }
     376             : 
     377             :         // PaperFormat-Property?
     378           0 :         else if ( rProp.Name.compareToAscii( "PaperFormat" ) == 0 )
     379             :         {
     380           0 :             if ( ( rProp.Value >>= nPaperFormat ) == sal_False )
     381             :             {
     382           0 :                 if ( ( rProp.Value >>= lDummy ) == sal_False )
     383           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     384           0 :                 nPaperFormat = ( view::PaperFormat ) lDummy;
     385             :             }
     386             : 
     387           0 :             if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
     388             :             {
     389           0 :                 pPrinter->SetPaper( convertToPaper(nPaperFormat) );
     390           0 :                 nChangeFlags |= SFX_PRINTER_CHG_SIZE;
     391             :             }
     392             :         }
     393             : 
     394             :         // PaperSize-Property?
     395           0 :         else if ( rProp.Name.compareToAscii( "PaperSize" ) == 0 )
     396             :         {
     397           0 :             awt::Size aTempSize ;
     398           0 :             if ( ( rProp.Value >>= aTempSize ) == sal_False )
     399             :             {
     400           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     401             :             }
     402             :             else
     403             :             {
     404           0 :                 aSetPaperSize = impl_Size_Struct2Object(aTempSize);
     405             :             }
     406             :         }
     407             : 
     408             :         // PrinterTray-Property
     409           0 :         else if ( rProp.Name.compareToAscii( "PrinterPaperTray" ) == 0 )
     410             :         {
     411           0 :             rtl::OUString aTmp;
     412           0 :             if ( ( rProp.Value >>= aTmp ) == sal_False )
     413           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     414           0 :             sal_uInt16 nCount = pPrinter->GetPaperBinCount();
     415           0 :             for (sal_uInt16 nBin=0; nBin<nCount; nBin++)
     416             :             {
     417           0 :                 ::rtl::OUString aName( pPrinter->GetPaperBinName(nBin) );
     418           0 :                 if ( aName == aTmp )
     419             :                 {
     420           0 :                     pPrinter->SetPaperBin(nBin);
     421             :                     break;
     422             :                 }
     423           0 :             }
     424             :         }
     425             :     }
     426             : 
     427             :     // The PaperSize may be set only when actually PAPER_USER
     428             :     // applies, otherwise the driver could choose a invalid format.
     429           0 :     if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
     430             :     {
     431             :         // Bug 56929 - MapMode of 100mm which recalculated when
     432             :         // the device is set. Additionally only set if they were really changed.
     433           0 :         aSetPaperSize = pPrinter->LogicToPixel( aSetPaperSize, MAP_100TH_MM );
     434           0 :         if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
     435             :         {
     436           0 :             pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
     437           0 :             nChangeFlags |= SFX_PRINTER_CHG_SIZE;
     438             :         }
     439             :     }
     440             : 
     441             :     //wait until printing is done
     442           0 :     SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
     443           0 :     while ( pDocPrinter->IsPrinting() )
     444           0 :         Application::Yield();
     445             : }
     446             : 
     447           0 : void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
     448             :         throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
     449             : {
     450             :     // object already disposed?
     451           0 :     SolarMutexGuard aGuard;
     452             : 
     453           0 :     SfxViewShell* pViewSh = NULL;
     454           0 :     SfxPrinter* pPrinter = NULL;
     455           0 :     sal_uInt16 nChangeFlags = 0;
     456           0 :     impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
     457             :     // set new printer
     458           0 :     if ( pViewSh && pPrinter )
     459           0 :         pViewSh->SetPrinter( pPrinter, nChangeFlags, false );
     460           0 : }
     461             : 
     462             : //________________________________________________________________________________________________________
     463             : //  ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
     464             : //________________________________________________________________________________________________________
     465             : 
     466             : /* This implements a thread which will be started to wait for asynchronous
     467             :    print jobs to temp. localy files. If they finish we move the temp. files
     468             :    to her right locations by using the ucb.
     469             :  */
     470           0 : class ImplUCBPrintWatcher : public ::osl::Thread
     471             : {
     472             :     private:
     473             :         /// of course we must know the printer which execute the job
     474             :         SfxPrinter* m_pPrinter;
     475             :         /// this describes the target location for the printed temp file
     476             :         String m_sTargetURL;
     477             :         /// it holds the temp file alive, till the print job will finish and remove it from disk automaticly if the object die
     478             :         ::utl::TempFile* m_pTempFile;
     479             : 
     480             :     public:
     481             :         /* initialize this watcher but don't start it */
     482           0 :         ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFile* pTempFile, const String& sTargetURL )
     483             :                 : m_pPrinter  ( pPrinter   )
     484             :                 , m_sTargetURL( sTargetURL )
     485           0 :                 , m_pTempFile ( pTempFile  )
     486           0 :         {}
     487             : 
     488             :         /* waits for finishing of the print job and moves the temp file afterwards
     489             :            Note: Starting of the job is done outside this thread!
     490             :            But we have to free some of the given resources on heap!
     491             :          */
     492           0 :         void SAL_CALL run()
     493             :         {
     494             :             /* SAFE { */
     495             :             {
     496           0 :                 SolarMutexGuard aGuard;
     497           0 :                 while( m_pPrinter->IsPrinting() )
     498           0 :                     Application::Yield();
     499           0 :                 m_pPrinter = NULL; // don't delete it! It's borrowed only :-)
     500             :             }
     501             :             /* } SAFE */
     502             : 
     503             :             // lock for further using of our member isn't neccessary - because
     504             :             // we truns alone by defenition. Nobody join for us nor use us ...
     505           0 :             moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
     506             : 
     507             :             // finishing of this run() method will call onTerminate() automaticly
     508             :             // kill this thread there!
     509           0 :         }
     510             : 
     511             :         /* nobody wait for this thread. We must kill ourself ...
     512             :          */
     513           0 :         void SAL_CALL onTerminated()
     514             :         {
     515           0 :             delete this;
     516           0 :         }
     517             : 
     518             :         /* static helper to move the temp. file to the target location by using the ucb
     519             :            It's static to be useable from outside too. So it's not realy neccessary to start
     520             :            the thread, if finishing of the job was detected outside this thread.
     521             :            But it must be called without using a corresponding thread for the given parameter!
     522             :          */
     523           0 :         static void moveAndDeleteTemp( ::utl::TempFile** ppTempFile, const String& sTargetURL )
     524             :         {
     525             :             // move the file
     526             :             try
     527             :             {
     528           0 :                 INetURLObject aSplitter(sTargetURL);
     529             :                 String        sFileName = aSplitter.getName(
     530             :                                             INetURLObject::LAST_SEGMENT,
     531             :                                             true,
     532           0 :                                             INetURLObject::DECODE_WITH_CHARSET);
     533           0 :                 if (aSplitter.removeSegment() && sFileName.Len()>0)
     534             :                 {
     535             :                     ::ucbhelper::Content aSource(
     536             :                             ::rtl::OUString((*ppTempFile)->GetURL()),
     537             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     538           0 :                             comphelper::getProcessComponentContext());
     539             : 
     540             :                     ::ucbhelper::Content aTarget(
     541             :                             ::rtl::OUString(aSplitter.GetMainURL(INetURLObject::NO_DECODE)),
     542             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     543           0 :                             comphelper::getProcessComponentContext());
     544             : 
     545             :                     aTarget.transferContent(
     546             :                             aSource,
     547             :                             ::ucbhelper::InsertOperation_COPY,
     548             :                             ::rtl::OUString(sFileName),
     549           0 :                             ::com::sun::star::ucb::NameClash::OVERWRITE);
     550           0 :                 }
     551             :             }
     552           0 :             catch (const ::com::sun::star::ucb::ContentCreationException&)
     553             :             {
     554             :                 OSL_FAIL("content create exception");
     555             :             }
     556           0 :             catch (const ::com::sun::star::ucb::CommandAbortedException&)
     557             :             {
     558             :                 OSL_FAIL("command abort exception");
     559             :             }
     560           0 :             catch (const ::com::sun::star::uno::RuntimeException&)
     561             :             {
     562             :                 OSL_FAIL("runtime exception");
     563             :             }
     564           0 :             catch (const ::com::sun::star::uno::Exception&)
     565             :             {
     566             :                 OSL_FAIL("unknown exception");
     567             :             }
     568             : 
     569             :             // kill the temp file!
     570           0 :             delete *ppTempFile;
     571           0 :             *ppTempFile = NULL;
     572           0 :         }
     573             : };
     574             : 
     575             : //------------------------------------------------
     576             : 
     577             : //________________________________________________________________________________________________________
     578             : //  XPrintable
     579             : //________________________________________________________________________________________________________
     580           0 : void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
     581             :         throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
     582             : {
     583           0 :     if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
     584             :         return;
     585             : 
     586             :     // object already disposed?
     587             :     // object already disposed?
     588           0 :     SolarMutexGuard aGuard;
     589             : 
     590             :     // get view for sfx printing capabilities
     591           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
     592           0 :                                 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
     593           0 :     if ( !pViewFrm )
     594             :         return;
     595           0 :     SfxViewShell* pView = pViewFrm->GetViewShell();
     596           0 :     if ( !pView )
     597             :         return;
     598           0 :     sal_Bool bMonitor = sal_False;
     599             :     // We need this information at the end of this method, if we start the vcl printer
     600             :     // by executing the slot. Because if it is a ucb relevant URL we must wait for
     601             :     // finishing the print job and move the temporary local file by using the ucb
     602             :     // to the right location. But in case of no file name is given or it is already
     603             :     // a local one we can supress this special handling. Because then vcl makes all
     604             :     // right for us.
     605           0 :     String sUcbUrl;
     606           0 :     ::utl::TempFile* pUCBPrintTempFile = NULL;
     607             : 
     608           0 :     uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
     609           0 :     sal_Int32 nProps = 0;
     610           0 :     sal_Bool  bWaitUntilEnd = sal_False;
     611           0 :     sal_Int16 nDuplexMode = ::com::sun::star::view::DuplexMode::UNKNOWN;
     612           0 :     for ( int n = 0; n < rOptions.getLength(); ++n )
     613             :     {
     614             :         // get Property-Value from options
     615           0 :         const beans::PropertyValue &rProp = rOptions.getConstArray()[n];
     616             : 
     617             :         // FileName-Property?
     618           0 :         if ( rProp.Name.compareToAscii( "FileName" ) == 0 )
     619             :         {
     620             :             // unpack th URL and check for a valid and well known protocol
     621           0 :             ::rtl::OUString sTemp;
     622           0 :             if (
     623           0 :                 ( rProp.Value.getValueType()!=::getCppuType((const ::rtl::OUString*)0))  ||
     624           0 :                 (!(rProp.Value>>=sTemp))
     625             :                )
     626             :             {
     627           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     628             :             }
     629             : 
     630           0 :             String        sPath        ;
     631           0 :             String        sURL  (sTemp);
     632           0 :             INetURLObject aCheck(sURL );
     633           0 :             if (aCheck.GetProtocol()==INET_PROT_NOT_VALID)
     634             :             {
     635             :                 // OK - it's not a valid URL. But may it's a simple
     636             :                 // system path directly. It will be supported for historical
     637             :                 // reasons. Otherwhise we break to much external code ...
     638             :                 // We try to convert it to a file URL. If its possible
     639             :                 // we put the system path to the item set and let vcl work with it.
     640             :                 // No ucb or thread will be neccessary then. In case it couldnt be
     641             :                 // converted its not an URL nor a system path. Then we can't accept
     642             :                 // this parameter and have to throw an exception.
     643           0 :                 ::rtl::OUString sSystemPath(sTemp);
     644           0 :                 ::rtl::OUString sFileURL;
     645           0 :                 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
     646           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     647           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     648           0 :                 aCheckedArgs[nProps++].Value <<= sFileURL;
     649             :                 // and append the local filename
     650           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     651           0 :                 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
     652           0 :                 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sTemp );
     653             :             }
     654             :             else
     655             :             // It's a valid URL. but now we must know, if it is a local one or not.
     656             :             // It's a question of using ucb or not!
     657           0 :             if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL,sPath))
     658             :             {
     659             :                 // it's a local file, we can use vcl without special handling
     660             :                 // And we have to use the system notation of the incoming URL.
     661             :                 // But it into the descriptor and let the slot be executed at
     662             :                 // the end of this method.
     663           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     664           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     665             :                 // and append the local filename
     666           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     667           0 :                 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
     668           0 :                 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sPath );
     669             :             }
     670             :             else
     671             :             {
     672             :                 // it's an ucb target. So we must use a temp. file for vcl
     673             :                 // and move it after printing by using the ucb.
     674             :                 // Create a temp file on the heap (because it must delete the
     675             :                 // real file on disk automaticly if it die - bt we have to share it with
     676             :                 // some other sources ... e.g. the ImplUCBPrintWatcher).
     677             :                 // And we put the name of this temp file to the descriptor instead
     678             :                 // of the URL. The URL we save for later using seperatly.
     679             :                 // Execution of the print job will be done later by executing
     680             :                 // a slot ...
     681           0 :                 pUCBPrintTempFile = new ::utl::TempFile();
     682           0 :                 pUCBPrintTempFile->EnableKillingFile();
     683             : 
     684             :                 //FIXME: does it work?
     685           0 :                 aCheckedArgs[nProps].Name = rtl::OUString("LocalFileName");
     686           0 :                 aCheckedArgs[nProps++].Value <<= ::rtl::OUString( pUCBPrintTempFile->GetFileName() );
     687           0 :                 sUcbUrl = sURL;
     688           0 :             }
     689             :         }
     690             : 
     691             :         // CopyCount-Property
     692           0 :         else if ( rProp.Name.compareToAscii( "CopyCount" ) == 0 )
     693             :         {
     694           0 :             sal_Int32 nCopies = 0;
     695           0 :             if ( ( rProp.Value >>= nCopies ) == sal_False )
     696           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     697             : 
     698           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     699           0 :             aCheckedArgs[nProps++].Value <<= nCopies;
     700             :         }
     701             : 
     702             :         // Collate-Property
     703             :         // Sort-Property (deprecated)
     704           0 :         else if ( rProp.Name.compareToAscii( "Collate" ) == 0 ||
     705           0 :                 ( rProp.Name.compareToAscii( "Sort" ) == 0 ) )
     706             :         {
     707           0 :             sal_Bool bTemp = sal_Bool();
     708           0 :             if ( rProp.Value >>= bTemp )
     709             :             {
     710           0 :                 aCheckedArgs[nProps].Name = rtl::OUString("Collate");
     711           0 :                 aCheckedArgs[nProps++].Value <<= bTemp;
     712             :             }
     713             :             else
     714           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     715             :         }
     716             : 
     717             :         // Pages-Property
     718           0 :         else if ( rProp.Name.compareToAscii( "Pages" ) == 0 )
     719             :         {
     720           0 :             ::rtl::OUString sTemp;
     721           0 :             if( rProp.Value >>= sTemp )
     722             :             {
     723           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     724           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     725             :             }
     726             :             else
     727           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     728             :         }
     729             : 
     730             :         // MonitorVisible
     731           0 :         else if ( rProp.Name.compareToAscii( "MonitorVisible" ) == 0 )
     732             :         {
     733           0 :             if( !(rProp.Value >>= bMonitor) )
     734           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     735           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     736           0 :             aCheckedArgs[nProps++].Value <<= bMonitor;
     737             :         }
     738             : 
     739             :         // Wait
     740           0 :         else if ( rProp.Name.compareToAscii( "Wait" ) == 0 )
     741             :         {
     742           0 :             if ( !(rProp.Value >>= bWaitUntilEnd) )
     743           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     744           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     745           0 :             aCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
     746             :         }
     747             : 
     748           0 :         else if ( rProp.Name.compareToAscii( "DuplexMode" ) == 0 )
     749             :         {
     750           0 :             if ( !(rProp.Value >>= nDuplexMode ) )
     751           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     752           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     753           0 :             aCheckedArgs[nProps++].Value <<= nDuplexMode;
     754             :         }
     755             :     }
     756             : 
     757           0 :     if ( nProps != aCheckedArgs.getLength() )
     758           0 :         aCheckedArgs.realloc(nProps);
     759             : 
     760             :     // Execute the print request every time.
     761             :     // It doesn'tmatter if it is a real printer used or we print to a local file
     762             :     // nor if we print to a temp file and move it afterwards by using the ucb.
     763             :     // That will be handled later. see pUCBPrintFile below!
     764           0 :     pView->ExecPrint( aCheckedArgs, sal_True, sal_False );
     765             : 
     766             :     // Ok - may be execution before has finished (or started!) printing.
     767             :     // And may it was a printing to a file.
     768             :     // Now we have to check if we can move the file (if neccessary) via ucb to his right location.
     769             :     // Cases:
     770             :     //  a) printing finished                        => move the file directly and forget the watcher thread
     771             :     //  b) printing is asynchron and runs currently => start watcher thread and exit this method
     772             :     //                                                 This thread make all neccessary things by itself.
     773           0 :     if (pUCBPrintTempFile!=NULL)
     774             :     {
     775             :         // a)
     776           0 :         SfxPrinter* pPrinter = pView->GetPrinter();
     777           0 :         if ( ! pPrinter->IsPrinting() )
     778           0 :             ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
     779             :         // b)
     780             :         else
     781             :         {
     782             :             // Note: we create(d) some resource on the heap. (thread and tep file)
     783             :             // They will be delected by the thread automaticly if he finish his run() method.
     784           0 :             ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
     785           0 :             pWatcher->create();
     786             :         }
     787           0 :     }
     788             : }
     789             : 
     790       10017 : void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     791             : {
     792       10017 :     if ( &rBC == m_pObjectShell )
     793             :     {
     794       10017 :         SfxPrintingHint* pPrintHint = PTR_CAST( SfxPrintingHint, &rHint );
     795       10017 :         if ( pPrintHint )
     796             :         {
     797           0 :             if ( pPrintHint->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED )
     798             :             {
     799           0 :                 if ( !m_xPrintJob.is() )
     800           0 :                     m_xPrintJob = new SfxPrintJob_Impl( this );
     801           0 :                 m_aPrintOptions = pPrintHint->GetOptions();
     802             :             }
     803           0 :             else if ( pPrintHint->GetWhich() != -2 )    // -2 : CancelPrintJob
     804             :             {
     805           0 :                 view::PrintJobEvent aEvent;
     806           0 :                 aEvent.Source = m_xPrintJob;
     807           0 :                 aEvent.State = (com::sun::star::view::PrintableState) pPrintHint->GetWhich();
     808           0 :                 ::cppu::OInterfaceContainerHelper* pContainer = m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) );
     809           0 :                 if ( pContainer!=NULL )
     810             :                 {
     811           0 :                     ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
     812           0 :                     while (pIterator.hasMoreElements())
     813           0 :                         ((view::XPrintJobListener*)pIterator.next())->printJobEvent( aEvent );
     814           0 :                 }
     815             :             }
     816             :         }
     817             :     }
     818       10017 : }
     819             : 
     820         501 : void SAL_CALL SfxPrintHelper::addPrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
     821             : {
     822         501 :     SolarMutexGuard aGuard;
     823         501 :     m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
     824         501 : }
     825             : 
     826           0 : void SAL_CALL SfxPrintHelper::removePrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
     827             : {
     828           0 :     SolarMutexGuard aGuard;
     829           0 :     m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
     830           0 : }
     831             : 
     832             : 
     833             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10