LCOV - code coverage report
Current view: top level - sfx2/source/doc - printhelper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 33 354 9.3 %
Date: 2015-06-13 12:38:46 Functions: 11 33 33.3 %
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        8192 : 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        4114 :     explicit IMPL_PrintListener_DataContainer( ::osl::Mutex& aMutex)
      71             :             :   m_pObjectShell          ( 0 )
      72        4114 :             ,   m_aInterfaceContainer   ( aMutex )
      73             :     {
      74        4114 :     }
      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             :     explicit 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        4114 : SfxPrintHelper::SfxPrintHelper()
     147             : {
     148        4114 :     m_pData = new IMPL_PrintListener_DataContainer(m_aMutex);
     149        4114 : }
     150             : 
     151        4114 : 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        4114 :     if ( aArguments.getLength() )
     154             :     {
     155        4114 :         com::sun::star::uno::Reference < com::sun::star::frame::XModel > xModel;
     156        4114 :         aArguments[0] >>= xModel;
     157        8228 :         uno::Reference < lang::XUnoTunnel > xObj( xModel, uno::UNO_QUERY );
     158        8228 :         uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
     159        4114 :         sal_Int64 nHandle = xObj->getSomething( aSeq );
     160        4114 :         if ( nHandle )
     161             :         {
     162        4114 :             m_pData->m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
     163        4114 :             m_pData->StartListening(*m_pData->m_pObjectShell);
     164        4114 :         }
     165             :     }
     166        4114 : }
     167             : 
     168       12288 : SfxPrintHelper::~SfxPrintHelper()
     169             : {
     170        4096 :     delete m_pData;
     171        8192 : }
     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,
     316             :                                      SfxPrinter*& pPrinter,
     317             :                                      SfxPrinterChangeFlags& nChangeFlags,
     318             :                                      SfxViewShell*& pViewSh)
     319             : 
     320             : {
     321             :     // Get old Printer
     322           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
     323           0 :                                 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, false ) : 0;
     324           0 :     if ( !pViewFrm )
     325           0 :         return;
     326             : 
     327           0 :     pViewSh = pViewFrm->GetViewShell();
     328           0 :     pPrinter = pViewSh->GetPrinter(true);
     329           0 :     if ( !pPrinter )
     330           0 :         return;
     331             : 
     332             :     // new Printer-Name available?
     333           0 :     nChangeFlags = SfxPrinterChangeFlags::NONE;
     334           0 :     sal_Int32 lDummy = 0;
     335           0 :     for ( int n = 0; n < rPrinter.getLength(); ++n )
     336             :     {
     337             :         // get Property-Value from printer description
     338           0 :         const beans::PropertyValue &rProp = rPrinter.getConstArray()[n];
     339             : 
     340             :         // Name-Property?
     341           0 :         if ( rProp.Name == "Name" )
     342             :         {
     343           0 :             OUString aPrinterName;
     344           0 :             if ( ! ( rProp.Value >>= aPrinterName ) )
     345           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     346             : 
     347           0 :             if ( aPrinterName != pPrinter->GetName() )
     348             :             {
     349           0 :                 pPrinter = VclPtr<SfxPrinter>::Create( pPrinter->GetOptions().Clone(), aPrinterName );
     350           0 :                 nChangeFlags = SfxPrinterChangeFlags::PRINTER;
     351             :             }
     352           0 :             break;
     353             :         }
     354             :     }
     355             : 
     356           0 :     Size aSetPaperSize( 0, 0);
     357           0 :     view::PaperFormat nPaperFormat = view::PaperFormat_USER;
     358             : 
     359             :     // other properties
     360           0 :     for ( int i = 0; i < rPrinter.getLength(); ++i )
     361             :     {
     362             :         // get Property-Value from printer description
     363           0 :         const beans::PropertyValue &rProp = rPrinter.getConstArray()[i];
     364             : 
     365             :         // PaperOrientation-Property?
     366           0 :         if ( rProp.Name == "PaperOrientation" )
     367             :         {
     368             :             view::PaperOrientation eOrient;
     369           0 :             if ( !( rProp.Value >>= eOrient ) )
     370             :             {
     371           0 :                 if ( !( rProp.Value >>= lDummy ) )
     372           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     373           0 :                 eOrient = ( view::PaperOrientation) lDummy;
     374             :             }
     375             : 
     376           0 :             if ( (Orientation) eOrient != pPrinter->GetOrientation() )
     377             :             {
     378           0 :                 pPrinter->SetOrientation( (Orientation) eOrient );
     379           0 :                 nChangeFlags |= SfxPrinterChangeFlags::CHG_ORIENTATION;
     380             :             }
     381             :         }
     382             : 
     383             :         // PaperFormat-Property?
     384           0 :         else if ( rProp.Name == "PaperFormat" )
     385             :         {
     386           0 :             if ( !( rProp.Value >>= nPaperFormat ) )
     387             :             {
     388           0 :                 if ( !( rProp.Value >>= lDummy ) )
     389           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     390           0 :                 nPaperFormat = ( view::PaperFormat ) lDummy;
     391             :             }
     392             : 
     393           0 :             if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
     394             :             {
     395           0 :                 pPrinter->SetPaper( convertToPaper(nPaperFormat) );
     396           0 :                 nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
     397             :             }
     398             :         }
     399             : 
     400             :         // PaperSize-Property?
     401           0 :         else if ( rProp.Name == "PaperSize" )
     402             :         {
     403           0 :             awt::Size aTempSize ;
     404           0 :             if ( !( rProp.Value >>= aTempSize ) )
     405             :             {
     406           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     407             :             }
     408             :             else
     409             :             {
     410           0 :                 aSetPaperSize = impl_Size_Struct2Object(aTempSize);
     411             :             }
     412             :         }
     413             : 
     414             :         // PrinterTray-Property
     415           0 :         else if ( rProp.Name == "PrinterPaperTray" )
     416             :         {
     417           0 :             OUString aTmp;
     418           0 :             if ( !( rProp.Value >>= aTmp ) )
     419           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     420           0 :             sal_uInt16 nCount = pPrinter->GetPaperBinCount();
     421           0 :             for (sal_uInt16 nBin=0; nBin<nCount; nBin++)
     422             :             {
     423           0 :                 OUString aName( pPrinter->GetPaperBinName(nBin) );
     424           0 :                 if ( aName == aTmp )
     425             :                 {
     426           0 :                     pPrinter->SetPaperBin(nBin);
     427           0 :                     break;
     428             :                 }
     429           0 :             }
     430             :         }
     431             :     }
     432             : 
     433             :     // The PaperSize may be set only when actually PAPER_USER
     434             :     // applies, otherwise the driver could choose a invalid format.
     435           0 :     if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
     436             :     {
     437             :         // Bug 56929 - MapMode of 100mm which recalculated when
     438             :         // the device is set. Additionally only set if they were really changed.
     439           0 :         aSetPaperSize = pPrinter->LogicToPixel( aSetPaperSize, MAP_100TH_MM );
     440           0 :         if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
     441             :         {
     442           0 :             pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
     443           0 :             nChangeFlags |= SfxPrinterChangeFlags::CHG_SIZE;
     444             :         }
     445             :     }
     446             : 
     447             :     //wait until printing is done
     448           0 :     SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
     449           0 :     while ( pDocPrinter->IsPrinting() )
     450           0 :         Application::Yield();
     451             : }
     452             : 
     453           0 : void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
     454             :         throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     455             : {
     456             :     // object already disposed?
     457           0 :     SolarMutexGuard aGuard;
     458             : 
     459           0 :     SfxViewShell* pViewSh = NULL;
     460           0 :     SfxPrinter* pPrinter = NULL;
     461           0 :     SfxPrinterChangeFlags nChangeFlags = SfxPrinterChangeFlags::NONE;
     462           0 :     impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
     463             :     // set new printer
     464           0 :     if ( pViewSh && pPrinter )
     465           0 :         pViewSh->SetPrinter( pPrinter, nChangeFlags, false );
     466           0 : }
     467             : 
     468             : 
     469             : //  ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
     470             : 
     471             : 
     472             : /* This implements a thread which will be started to wait for asynchronous
     473             :    print jobs to temp. localy files. If they finish we move the temp. files
     474             :    to her right locations by using the ucb.
     475             :  */
     476           0 : class ImplUCBPrintWatcher : public ::osl::Thread
     477             : {
     478             :     private:
     479             :         /// of course we must know the printer which execute the job
     480             :         VclPtr<SfxPrinter> m_pPrinter;
     481             :         /// this describes the target location for the printed temp file
     482             :         OUString m_sTargetURL;
     483             :         /// it holds the temp file alive, till the print job will finish and remove it from disk automatically if the object die
     484             :         ::utl::TempFile* m_pTempFile;
     485             : 
     486             :     public:
     487             :         /* initialize this watcher but don't start it */
     488           0 :         ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFile* pTempFile, const OUString& sTargetURL )
     489             :                 : m_pPrinter  ( pPrinter   )
     490             :                 , m_sTargetURL( sTargetURL )
     491           0 :                 , m_pTempFile ( pTempFile  )
     492           0 :         {}
     493             : 
     494             :         /* waits for finishing of the print job and moves the temp file afterwards
     495             :            Note: Starting of the job is done outside this thread!
     496             :            But we have to free some of the given resources on heap!
     497             :          */
     498           0 :         void SAL_CALL run() SAL_OVERRIDE
     499             :         {
     500           0 :             osl_setThreadName("ImplUCBPrintWatcher");
     501             : 
     502             :             /* SAFE { */
     503             :             {
     504           0 :                 SolarMutexGuard aGuard;
     505           0 :                 while( m_pPrinter->IsPrinting() )
     506           0 :                     Application::Yield();
     507           0 :                 m_pPrinter.clear(); // don't delete it! It's borrowed only :-)
     508             :             }
     509             :             /* } SAFE */
     510             : 
     511             :             // lock for further using of our member isn't necessary - because
     512             :             // we truns alone by defenition. Nobody join for us nor use us ...
     513           0 :             moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
     514             : 
     515             :             // finishing of this run() method will call onTerminate() automatically
     516             :             // kill this thread there!
     517           0 :         }
     518             : 
     519             :         /* nobody wait for this thread. We must kill ourself ...
     520             :          */
     521           0 :         void SAL_CALL onTerminated() SAL_OVERRIDE
     522             :         {
     523           0 :             delete this;
     524           0 :         }
     525             : 
     526             :         /* static helper to move the temp. file to the target location by using the ucb
     527             :            It's static to be useable from outside too. So it's not really necessary to start
     528             :            the thread, if finishing of the job was detected outside this thread.
     529             :            But it must be called without using a corresponding thread for the given parameter!
     530             :          */
     531           0 :         static void moveAndDeleteTemp( ::utl::TempFile** ppTempFile, const OUString& sTargetURL )
     532             :         {
     533             :             // move the file
     534             :             try
     535             :             {
     536           0 :                 INetURLObject aSplitter(sTargetURL);
     537             :                 OUString        sFileName = aSplitter.getName(
     538             :                                             INetURLObject::LAST_SEGMENT,
     539             :                                             true,
     540           0 :                                             INetURLObject::DECODE_WITH_CHARSET);
     541           0 :                 if (aSplitter.removeSegment() && !sFileName.isEmpty())
     542             :                 {
     543             :                     ::ucbhelper::Content aSource(
     544             :                             OUString((*ppTempFile)->GetURL()),
     545             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     546           0 :                             comphelper::getProcessComponentContext());
     547             : 
     548             :                     ::ucbhelper::Content aTarget(
     549             :                             OUString(aSplitter.GetMainURL(INetURLObject::NO_DECODE)),
     550             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     551           0 :                             comphelper::getProcessComponentContext());
     552             : 
     553             :                     aTarget.transferContent(
     554             :                             aSource,
     555             :                             ::ucbhelper::InsertOperation_COPY,
     556             :                             OUString(sFileName),
     557           0 :                             ::com::sun::star::ucb::NameClash::OVERWRITE);
     558           0 :                 }
     559             :             }
     560           0 :             catch (const ::com::sun::star::ucb::ContentCreationException&)
     561             :             {
     562             :                 OSL_FAIL("content create exception");
     563             :             }
     564           0 :             catch (const ::com::sun::star::ucb::CommandAbortedException&)
     565             :             {
     566             :                 OSL_FAIL("command abort exception");
     567             :             }
     568           0 :             catch (const ::com::sun::star::uno::RuntimeException&)
     569             :             {
     570             :                 OSL_FAIL("runtime exception");
     571             :             }
     572           0 :             catch (const ::com::sun::star::uno::Exception&)
     573             :             {
     574             :                 OSL_FAIL("unknown exception");
     575             :             }
     576             : 
     577             :             // kill the temp file!
     578           0 :             delete *ppTempFile;
     579           0 :             *ppTempFile = NULL;
     580           0 :         }
     581             : };
     582             : 
     583             : 
     584             : 
     585             : 
     586             : //  XPrintable
     587             : 
     588           0 : void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
     589             :         throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     590             : {
     591           0 :     if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
     592           0 :         return;
     593             : 
     594             :     // object already disposed?
     595             :     // object already disposed?
     596           0 :     SolarMutexGuard aGuard;
     597             : 
     598             :     // get view for sfx printing capabilities
     599           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
     600           0 :                                 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, false ) : 0;
     601           0 :     if ( !pViewFrm )
     602           0 :         return;
     603           0 :     SfxViewShell* pView = pViewFrm->GetViewShell();
     604           0 :     if ( !pView )
     605           0 :         return;
     606           0 :     bool bMonitor = false;
     607             :     // We need this information at the end of this method, if we start the vcl printer
     608             :     // by executing the slot. Because if it is a ucb relevant URL we must wait for
     609             :     // finishing the print job and move the temporary local file by using the ucb
     610             :     // to the right location. But in case of no file name is given or it is already
     611             :     // a local one we can suppress this special handling. Because then vcl makes all
     612             :     // right for us.
     613           0 :     OUString sUcbUrl;
     614           0 :     ::utl::TempFile* pUCBPrintTempFile = NULL;
     615             : 
     616           0 :     uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
     617           0 :     sal_Int32 nProps = 0;
     618           0 :     bool  bWaitUntilEnd = false;
     619           0 :     sal_Int16 nDuplexMode = ::com::sun::star::view::DuplexMode::UNKNOWN;
     620           0 :     for ( int n = 0; n < rOptions.getLength(); ++n )
     621             :     {
     622             :         // get Property-Value from options
     623           0 :         const beans::PropertyValue &rProp = rOptions.getConstArray()[n];
     624             : 
     625             :         // FileName-Property?
     626           0 :         if ( rProp.Name == "FileName" )
     627             :         {
     628             :             // unpack th URL and check for a valid and well known protocol
     629           0 :             OUString sTemp;
     630           0 :             if (
     631           0 :                 ( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get())  ||
     632           0 :                 (!(rProp.Value>>=sTemp))
     633             :                )
     634             :             {
     635           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     636             :             }
     637             : 
     638           0 :             OUString      sPath        ;
     639           0 :             OUString      sURL  (sTemp);
     640           0 :             INetURLObject aCheck(sURL );
     641           0 :             if (aCheck.GetProtocol()==INetProtocol::NotValid)
     642             :             {
     643             :                 // OK - it's not a valid URL. But may it's a simple
     644             :                 // system path directly. It will be supported for historical
     645             :                 // reasons. Otherwhise we break to much external code ...
     646             :                 // We try to convert it to a file URL. If its possible
     647             :                 // we put the system path to the item set and let vcl work with it.
     648             :                 // No ucb or thread will be necessary then. In case it couldnt be
     649             :                 // converted its not an URL nor a system path. Then we can't accept
     650             :                 // this parameter and have to throw an exception.
     651           0 :                 OUString sSystemPath(sTemp);
     652           0 :                 OUString sFileURL;
     653           0 :                 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
     654           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     655           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     656           0 :                 aCheckedArgs[nProps++].Value <<= sFileURL;
     657             :                 // and append the local filename
     658           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     659           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     660           0 :                 aCheckedArgs[nProps++].Value <<= OUString( sTemp );
     661             :             }
     662             :             else
     663             :             // It's a valid URL. but now we must know, if it is a local one or not.
     664             :             // It's a question of using ucb or not!
     665           0 :             if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL,sPath))
     666             :             {
     667             :                 // it's a local file, we can use vcl without special handling
     668             :                 // And we have to use the system notation of the incoming URL.
     669             :                 // But it into the descriptor and let the slot be executed at
     670             :                 // the end of this method.
     671           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     672           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     673             :                 // and append the local filename
     674           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     675           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     676           0 :                 aCheckedArgs[nProps++].Value <<= sPath;
     677             :             }
     678             :             else
     679             :             {
     680             :                 // it's an ucb target. So we must use a temp. file for vcl
     681             :                 // and move it after printing by using the ucb.
     682             :                 // Create a temp file on the heap (because it must delete the
     683             :                 // real file on disk automatically if it die - bt we have to share it with
     684             :                 // some other sources ... e.g. the ImplUCBPrintWatcher).
     685             :                 // And we put the name of this temp file to the descriptor instead
     686             :                 // of the URL. The URL we save for later using separately.
     687             :                 // Execution of the print job will be done later by executing
     688             :                 // a slot ...
     689           0 :                 if(!pUCBPrintTempFile)
     690           0 :                     pUCBPrintTempFile = new ::utl::TempFile();
     691           0 :                 pUCBPrintTempFile->EnableKillingFile();
     692             : 
     693             :                 //FIXME: does it work?
     694           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     695           0 :                 aCheckedArgs[nProps++].Value <<= OUString( pUCBPrintTempFile->GetFileName() );
     696           0 :                 sUcbUrl = sURL;
     697           0 :             }
     698             :         }
     699             : 
     700             :         // CopyCount-Property
     701           0 :         else if ( rProp.Name == "CopyCount" )
     702             :         {
     703           0 :             sal_Int32 nCopies = 0;
     704           0 :             if ( !( rProp.Value >>= nCopies ) )
     705           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     706             : 
     707           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     708           0 :             aCheckedArgs[nProps++].Value <<= nCopies;
     709             :         }
     710             : 
     711             :         // Collate-Property
     712             :         // Sort-Property (deprecated)
     713           0 :         else if ( rProp.Name == "Collate" || rProp.Name == "Sort" )
     714             :         {
     715             :             bool bTemp;
     716           0 :             if ( rProp.Value >>= bTemp )
     717             :             {
     718           0 :                 aCheckedArgs[nProps].Name = "Collate";
     719           0 :                 aCheckedArgs[nProps++].Value <<= bTemp;
     720             :             }
     721             :             else
     722           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     723             :         }
     724             : 
     725             :         // Pages-Property
     726           0 :         else if ( rProp.Name == "Pages" )
     727             :         {
     728           0 :             OUString sTemp;
     729           0 :             if( rProp.Value >>= sTemp )
     730             :             {
     731           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     732           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     733             :             }
     734             :             else
     735           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     736             :         }
     737             : 
     738             :         // MonitorVisible
     739           0 :         else if ( rProp.Name == "MonitorVisible" )
     740             :         {
     741           0 :             if( !(rProp.Value >>= bMonitor) )
     742           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     743           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     744           0 :             aCheckedArgs[nProps++].Value <<= bMonitor;
     745             :         }
     746             : 
     747             :         // Wait
     748           0 :         else if ( rProp.Name == "Wait" )
     749             :         {
     750           0 :             if ( !(rProp.Value >>= bWaitUntilEnd) )
     751           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     752           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     753           0 :             aCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
     754             :         }
     755             : 
     756           0 :         else if ( rProp.Name == "DuplexMode" )
     757             :         {
     758           0 :             if ( !(rProp.Value >>= nDuplexMode ) )
     759           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     760           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     761           0 :             aCheckedArgs[nProps++].Value <<= nDuplexMode;
     762             :         }
     763             :     }
     764             : 
     765           0 :     if ( nProps != aCheckedArgs.getLength() )
     766           0 :         aCheckedArgs.realloc(nProps);
     767             : 
     768             :     // Execute the print request every time.
     769             :     // It doesn'tmatter if it is a real printer used or we print to a local file
     770             :     // nor if we print to a temp file and move it afterwards by using the ucb.
     771             :     // That will be handled later. see pUCBPrintFile below!
     772           0 :     pView->ExecPrint( aCheckedArgs, true, false );
     773             : 
     774             :     // Ok - may be execution before has finished (or started!) printing.
     775             :     // And may it was a printing to a file.
     776             :     // Now we have to check if we can move the file (if necessary) via ucb to his right location.
     777             :     // Cases:
     778             :     //  a) printing finished                        => move the file directly and forget the watcher thread
     779             :     //  b) printing is asynchron and runs currently => start watcher thread and exit this method
     780             :     //                                                 This thread make all necessary things by itself.
     781           0 :     if (pUCBPrintTempFile)
     782             :     {
     783             :         // a)
     784           0 :         SfxPrinter* pPrinter = pView->GetPrinter();
     785           0 :         if ( ! pPrinter->IsPrinting() )
     786           0 :             ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
     787             :         // b)
     788             :         else
     789             :         {
     790             :             // Note: we create(d) some resource on the heap. (thread and tep file)
     791             :             // They will be deleted by the thread automatically if he finish his run() method.
     792           0 :             ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
     793           0 :             pWatcher->create();
     794             :         }
     795           0 :     }
     796             : }
     797             : 
     798      232926 : void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     799             : {
     800      232926 :     const SfxPrintingHint* pPrintHint = dynamic_cast<const SfxPrintingHint*>(&rHint);
     801      465852 :     if ( &rBC != m_pObjectShell
     802      232926 :         || !pPrintHint
     803      232926 :         || pPrintHint->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB )
     804      465852 :         return;
     805             : 
     806           0 :     if ( pPrintHint->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED )
     807             :     {
     808           0 :         if ( !m_xPrintJob.is() )
     809           0 :             m_xPrintJob = new SfxPrintJob_Impl( this );
     810           0 :         m_aPrintOptions = pPrintHint->GetOptions();
     811             :     }
     812             : 
     813             :     ::cppu::OInterfaceContainerHelper* pContainer = m_aInterfaceContainer.getContainer(
     814           0 :         cppu::UnoType<view::XPrintJobListener>::get());
     815           0 :     if ( !pContainer )
     816           0 :         return;
     817             : 
     818           0 :     view::PrintJobEvent aEvent;
     819           0 :     aEvent.Source = m_xPrintJob;
     820           0 :     aEvent.State = (com::sun::star::view::PrintableState) pPrintHint->GetWhich();
     821             : 
     822           0 :     ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
     823           0 :     while (pIterator.hasMoreElements())
     824           0 :         static_cast<view::XPrintJobListener*>(pIterator.next())->printJobEvent( aEvent );
     825             : }
     826             : 
     827        4114 : 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)
     828             : {
     829        4114 :     SolarMutexGuard aGuard;
     830        4114 :     m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<view::XPrintJobListener>::get(), xListener );
     831        4114 : }
     832             : 
     833           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)
     834             : {
     835           0 :     SolarMutexGuard aGuard;
     836           0 :     m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<view::XPrintJobListener>::get(), xListener );
     837         648 : }
     838             : 
     839             : 
     840             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11