LCOV - code coverage report
Current view: top level - sfx2/source/doc - printhelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 33 355 9.3 %
Date: 2014-11-03 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       13894 : 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        6950 :     IMPL_PrintListener_DataContainer( ::osl::Mutex& aMutex)
      71             :             :   m_pObjectShell          ( 0 )
      72        6950 :             ,   m_aInterfaceContainer   ( aMutex )
      73             :     {
      74        6950 :     }
      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        6950 : SfxPrintHelper::SfxPrintHelper()
     147             : {
     148        6950 :     m_pData = new IMPL_PrintListener_DataContainer(m_aMutex);
     149        6950 : }
     150             : 
     151        6950 : 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        6950 :     if ( aArguments.getLength() )
     154             :     {
     155        6950 :         com::sun::star::uno::Reference < com::sun::star::frame::XModel > xModel;
     156        6950 :         aArguments[0] >>= xModel;
     157       13900 :         uno::Reference < lang::XUnoTunnel > xObj( xModel, uno::UNO_QUERY );
     158       13900 :         uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
     159        6950 :         sal_Int64 nHandle = xObj->getSomething( aSeq );
     160        6950 :         if ( nHandle )
     161             :         {
     162        6950 :             m_pData->m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
     163        6950 :             m_pData->StartListening(*m_pData->m_pObjectShell);
     164        6950 :         }
     165             :     }
     166        6950 : }
     167             : 
     168       20841 : SfxPrintHelper::~SfxPrintHelper()
     169             : {
     170        6947 :     delete m_pData;
     171       13894 : }
     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 automatically 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           0 :             osl_setThreadName("ImplUCBPrintWatcher");
     498             : 
     499             :             /* SAFE { */
     500             :             {
     501           0 :                 SolarMutexGuard aGuard;
     502           0 :                 while( m_pPrinter->IsPrinting() )
     503           0 :                     Application::Yield();
     504           0 :                 m_pPrinter = NULL; // don't delete it! It's borrowed only :-)
     505             :             }
     506             :             /* } SAFE */
     507             : 
     508             :             // lock for further using of our member isn't necessary - because
     509             :             // we truns alone by defenition. Nobody join for us nor use us ...
     510           0 :             moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
     511             : 
     512             :             // finishing of this run() method will call onTerminate() automatically
     513             :             // kill this thread there!
     514           0 :         }
     515             : 
     516             :         /* nobody wait for this thread. We must kill ourself ...
     517             :          */
     518           0 :         void SAL_CALL onTerminated() SAL_OVERRIDE
     519             :         {
     520           0 :             delete this;
     521           0 :         }
     522             : 
     523             :         /* static helper to move the temp. file to the target location by using the ucb
     524             :            It's static to be useable from outside too. So it's not really necessary to start
     525             :            the thread, if finishing of the job was detected outside this thread.
     526             :            But it must be called without using a corresponding thread for the given parameter!
     527             :          */
     528           0 :         static void moveAndDeleteTemp( ::utl::TempFile** ppTempFile, const OUString& sTargetURL )
     529             :         {
     530             :             // move the file
     531             :             try
     532             :             {
     533           0 :                 INetURLObject aSplitter(sTargetURL);
     534             :                 OUString        sFileName = aSplitter.getName(
     535             :                                             INetURLObject::LAST_SEGMENT,
     536             :                                             true,
     537           0 :                                             INetURLObject::DECODE_WITH_CHARSET);
     538           0 :                 if (aSplitter.removeSegment() && !sFileName.isEmpty())
     539             :                 {
     540             :                     ::ucbhelper::Content aSource(
     541             :                             OUString((*ppTempFile)->GetURL()),
     542             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     543           0 :                             comphelper::getProcessComponentContext());
     544             : 
     545             :                     ::ucbhelper::Content aTarget(
     546             :                             OUString(aSplitter.GetMainURL(INetURLObject::NO_DECODE)),
     547             :                             ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     548           0 :                             comphelper::getProcessComponentContext());
     549             : 
     550             :                     aTarget.transferContent(
     551             :                             aSource,
     552             :                             ::ucbhelper::InsertOperation_COPY,
     553             :                             OUString(sFileName),
     554           0 :                             ::com::sun::star::ucb::NameClash::OVERWRITE);
     555           0 :                 }
     556             :             }
     557           0 :             catch (const ::com::sun::star::ucb::ContentCreationException&)
     558             :             {
     559             :                 OSL_FAIL("content create exception");
     560             :             }
     561           0 :             catch (const ::com::sun::star::ucb::CommandAbortedException&)
     562             :             {
     563             :                 OSL_FAIL("command abort exception");
     564             :             }
     565           0 :             catch (const ::com::sun::star::uno::RuntimeException&)
     566             :             {
     567             :                 OSL_FAIL("runtime exception");
     568             :             }
     569           0 :             catch (const ::com::sun::star::uno::Exception&)
     570             :             {
     571             :                 OSL_FAIL("unknown exception");
     572             :             }
     573             : 
     574             :             // kill the temp file!
     575           0 :             delete *ppTempFile;
     576           0 :             *ppTempFile = NULL;
     577           0 :         }
     578             : };
     579             : 
     580             : 
     581             : 
     582             : 
     583             : //  XPrintable
     584             : 
     585           0 : void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
     586             :         throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     587             : {
     588           0 :     if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
     589           0 :         return;
     590             : 
     591             :     // object already disposed?
     592             :     // object already disposed?
     593           0 :     SolarMutexGuard aGuard;
     594             : 
     595             :     // get view for sfx printing capabilities
     596           0 :     SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
     597           0 :                                 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, false ) : 0;
     598           0 :     if ( !pViewFrm )
     599           0 :         return;
     600           0 :     SfxViewShell* pView = pViewFrm->GetViewShell();
     601           0 :     if ( !pView )
     602           0 :         return;
     603           0 :     bool bMonitor = false;
     604             :     // We need this information at the end of this method, if we start the vcl printer
     605             :     // by executing the slot. Because if it is a ucb relevant URL we must wait for
     606             :     // finishing the print job and move the temporary local file by using the ucb
     607             :     // to the right location. But in case of no file name is given or it is already
     608             :     // a local one we can suppress this special handling. Because then vcl makes all
     609             :     // right for us.
     610           0 :     OUString sUcbUrl;
     611           0 :     ::utl::TempFile* pUCBPrintTempFile = NULL;
     612             : 
     613           0 :     uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
     614           0 :     sal_Int32 nProps = 0;
     615           0 :     bool  bWaitUntilEnd = false;
     616           0 :     sal_Int16 nDuplexMode = ::com::sun::star::view::DuplexMode::UNKNOWN;
     617           0 :     for ( int n = 0; n < rOptions.getLength(); ++n )
     618             :     {
     619             :         // get Property-Value from options
     620           0 :         const beans::PropertyValue &rProp = rOptions.getConstArray()[n];
     621             : 
     622             :         // FileName-Property?
     623           0 :         if ( rProp.Name.equalsAscii( "FileName" ) )
     624             :         {
     625             :             // unpack th URL and check for a valid and well known protocol
     626           0 :             OUString sTemp;
     627           0 :             if (
     628           0 :                 ( rProp.Value.getValueType()!=cppu::UnoType<OUString>::get())  ||
     629           0 :                 (!(rProp.Value>>=sTemp))
     630             :                )
     631             :             {
     632           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     633             :             }
     634             : 
     635           0 :             OUString      sPath        ;
     636           0 :             OUString      sURL  (sTemp);
     637           0 :             INetURLObject aCheck(sURL );
     638           0 :             if (aCheck.GetProtocol()==INET_PROT_NOT_VALID)
     639             :             {
     640             :                 // OK - it's not a valid URL. But may it's a simple
     641             :                 // system path directly. It will be supported for historical
     642             :                 // reasons. Otherwhise we break to much external code ...
     643             :                 // We try to convert it to a file URL. If its possible
     644             :                 // we put the system path to the item set and let vcl work with it.
     645             :                 // No ucb or thread will be necessary then. In case it couldnt be
     646             :                 // converted its not an URL nor a system path. Then we can't accept
     647             :                 // this parameter and have to throw an exception.
     648           0 :                 OUString sSystemPath(sTemp);
     649           0 :                 OUString sFileURL;
     650           0 :                 if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
     651           0 :                     throw ::com::sun::star::lang::IllegalArgumentException();
     652           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     653           0 :                 aCheckedArgs[nProps++].Value <<= sFileURL;
     654             :                 // and append the local filename
     655           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     656           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     657           0 :                 aCheckedArgs[nProps++].Value <<= OUString( sTemp );
     658             :             }
     659             :             else
     660             :             // It's a valid URL. but now we must know, if it is a local one or not.
     661             :             // It's a question of using ucb or not!
     662           0 :             if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL,sPath))
     663             :             {
     664             :                 // it's a local file, we can use vcl without special handling
     665             :                 // And we have to use the system notation of the incoming URL.
     666             :                 // But it into the descriptor and let the slot be executed at
     667             :                 // the end of this method.
     668           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     669           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     670             :                 // and append the local filename
     671           0 :                 aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
     672           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     673           0 :                 aCheckedArgs[nProps++].Value <<= sPath;
     674             :             }
     675             :             else
     676             :             {
     677             :                 // it's an ucb target. So we must use a temp. file for vcl
     678             :                 // and move it after printing by using the ucb.
     679             :                 // Create a temp file on the heap (because it must delete the
     680             :                 // real file on disk automatically if it die - bt we have to share it with
     681             :                 // some other sources ... e.g. the ImplUCBPrintWatcher).
     682             :                 // And we put the name of this temp file to the descriptor instead
     683             :                 // of the URL. The URL we save for later using separately.
     684             :                 // Execution of the print job will be done later by executing
     685             :                 // a slot ...
     686           0 :                 if(!pUCBPrintTempFile)
     687           0 :                     pUCBPrintTempFile = new ::utl::TempFile();
     688           0 :                 pUCBPrintTempFile->EnableKillingFile();
     689             : 
     690             :                 //FIXME: does it work?
     691           0 :                 aCheckedArgs[nProps].Name = "LocalFileName";
     692           0 :                 aCheckedArgs[nProps++].Value <<= OUString( pUCBPrintTempFile->GetFileName() );
     693           0 :                 sUcbUrl = sURL;
     694           0 :             }
     695             :         }
     696             : 
     697             :         // CopyCount-Property
     698           0 :         else if ( rProp.Name.equalsAscii( "CopyCount" ) )
     699             :         {
     700           0 :             sal_Int32 nCopies = 0;
     701           0 :             if ( !( rProp.Value >>= nCopies ) )
     702           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     703             : 
     704           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     705           0 :             aCheckedArgs[nProps++].Value <<= nCopies;
     706             :         }
     707             : 
     708             :         // Collate-Property
     709             :         // Sort-Property (deprecated)
     710           0 :         else if ( rProp.Name.equalsAscii( "Collate" ) ||
     711           0 :                   rProp.Name.equalsAscii( "Sort" ) )
     712             :         {
     713             :             bool bTemp;
     714           0 :             if ( rProp.Value >>= bTemp )
     715             :             {
     716           0 :                 aCheckedArgs[nProps].Name = "Collate";
     717           0 :                 aCheckedArgs[nProps++].Value <<= bTemp;
     718             :             }
     719             :             else
     720           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     721             :         }
     722             : 
     723             :         // Pages-Property
     724           0 :         else if ( rProp.Name.equalsAscii( "Pages" ) )
     725             :         {
     726           0 :             OUString sTemp;
     727           0 :             if( rProp.Value >>= sTemp )
     728             :             {
     729           0 :                 aCheckedArgs[nProps].Name = rProp.Name;
     730           0 :                 aCheckedArgs[nProps++].Value <<= sTemp;
     731             :             }
     732             :             else
     733           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     734             :         }
     735             : 
     736             :         // MonitorVisible
     737           0 :         else if ( rProp.Name.equalsAscii( "MonitorVisible" ) )
     738             :         {
     739           0 :             if( !(rProp.Value >>= bMonitor) )
     740           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     741           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     742           0 :             aCheckedArgs[nProps++].Value <<= bMonitor;
     743             :         }
     744             : 
     745             :         // Wait
     746           0 :         else if ( rProp.Name.equalsAscii( "Wait" ) )
     747             :         {
     748           0 :             if ( !(rProp.Value >>= bWaitUntilEnd) )
     749           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     750           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     751           0 :             aCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
     752             :         }
     753             : 
     754           0 :         else if ( rProp.Name.equalsAscii( "DuplexMode" ) )
     755             :         {
     756           0 :             if ( !(rProp.Value >>= nDuplexMode ) )
     757           0 :                 throw ::com::sun::star::lang::IllegalArgumentException();
     758           0 :             aCheckedArgs[nProps].Name = rProp.Name;
     759           0 :             aCheckedArgs[nProps++].Value <<= nDuplexMode;
     760             :         }
     761             :     }
     762             : 
     763           0 :     if ( nProps != aCheckedArgs.getLength() )
     764           0 :         aCheckedArgs.realloc(nProps);
     765             : 
     766             :     // Execute the print request every time.
     767             :     // It doesn'tmatter if it is a real printer used or we print to a local file
     768             :     // nor if we print to a temp file and move it afterwards by using the ucb.
     769             :     // That will be handled later. see pUCBPrintFile below!
     770           0 :     pView->ExecPrint( aCheckedArgs, true, false );
     771             : 
     772             :     // Ok - may be execution before has finished (or started!) printing.
     773             :     // And may it was a printing to a file.
     774             :     // Now we have to check if we can move the file (if necessary) via ucb to his right location.
     775             :     // Cases:
     776             :     //  a) printing finished                        => move the file directly and forget the watcher thread
     777             :     //  b) printing is asynchron and runs currently => start watcher thread and exit this method
     778             :     //                                                 This thread make all necessary things by itself.
     779           0 :     if (pUCBPrintTempFile)
     780             :     {
     781             :         // a)
     782           0 :         SfxPrinter* pPrinter = pView->GetPrinter();
     783           0 :         if ( ! pPrinter->IsPrinting() )
     784           0 :             ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
     785             :         // b)
     786             :         else
     787             :         {
     788             :             // Note: we create(d) some resource on the heap. (thread and tep file)
     789             :             // They will be deleted by the thread automatically if he finish his run() method.
     790           0 :             ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
     791           0 :             pWatcher->create();
     792             :         }
     793           0 :     }
     794             : }
     795             : 
     796      303756 : void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     797             : {
     798      303756 :     const SfxPrintingHint* pPrintHint = dynamic_cast<const SfxPrintingHint*>(&rHint);
     799      607512 :     if ( &rBC != m_pObjectShell
     800      303756 :         || !pPrintHint
     801      303756 :         || pPrintHint->GetWhich() == SFX_PRINTABLESTATE_CANCELJOB )
     802      607512 :         return;
     803             : 
     804           0 :     if ( pPrintHint->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED )
     805             :     {
     806           0 :         if ( !m_xPrintJob.is() )
     807           0 :             m_xPrintJob = new SfxPrintJob_Impl( this );
     808           0 :         m_aPrintOptions = pPrintHint->GetOptions();
     809             :     }
     810             : 
     811             :     ::cppu::OInterfaceContainerHelper* pContainer = m_aInterfaceContainer.getContainer(
     812           0 :         cppu::UnoType<view::XPrintJobListener>::get());
     813           0 :     if ( !pContainer )
     814           0 :         return;
     815             : 
     816           0 :     view::PrintJobEvent aEvent;
     817           0 :     aEvent.Source = m_xPrintJob;
     818           0 :     aEvent.State = (com::sun::star::view::PrintableState) pPrintHint->GetWhich();
     819             : 
     820           0 :     ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
     821           0 :     while (pIterator.hasMoreElements())
     822           0 :         static_cast<view::XPrintJobListener*>(pIterator.next())->printJobEvent( aEvent );
     823             : }
     824             : 
     825        6950 : 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)
     826             : {
     827        6950 :     SolarMutexGuard aGuard;
     828        6950 :     m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<view::XPrintJobListener>::get(), xListener );
     829        6950 : }
     830             : 
     831           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)
     832             : {
     833           0 :     SolarMutexGuard aGuard;
     834           0 :     m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<view::XPrintJobListener>::get(), xListener );
     835         951 : }
     836             : 
     837             : 
     838             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10