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

Generated by: LCOV version 1.10