LCOV - code coverage report
Current view: top level - libreoffice/sfx2/source/dialog - mailmodel.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 407 0.0 %
Date: 2012-12-27 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/beans/PropertyValue.hpp>
      21             : #include <com/sun/star/beans/XPropertyAccess.hpp>
      22             : #include <com/sun/star/frame/XFrame.hpp>
      23             : #include <com/sun/star/frame/XModel.hpp>
      24             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      25             : #include <com/sun/star/ucb/CommandAbortedException.hpp>
      26             : #include <com/sun/star/uno/Reference.h>
      27             : #include <com/sun/star/util/URLTransformer.hpp>
      28             : #include <com/sun/star/util/XURLTransformer.hpp>
      29             : #include <com/sun/star/system/XSimpleMailClientSupplier.hpp>
      30             : #include <com/sun/star/system/SimpleMailClientFlags.hpp>
      31             : #include <com/sun/star/embed/XStorage.hpp>
      32             : #include <com/sun/star/embed/ElementModes.hpp>
      33             : #include <com/sun/star/embed/XTransactedObject.hpp>
      34             : #include <com/sun/star/container/XContainerQuery.hpp>
      35             : #include <com/sun/star/util/XModifiable.hpp>
      36             : #include <com/sun/star/frame/ModuleManager.hpp>
      37             : #include <com/sun/star/frame/XStorable.hpp>
      38             : #include <com/sun/star/beans/XPropertySet.hpp>
      39             : #include <com/sun/star/security/CertificateValidity.hpp>
      40             : #include <com/sun/star/security/DocumentSignatureInformation.hpp>
      41             : #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
      42             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      43             : #include <com/sun/star/frame/XDispatch.hpp>
      44             : #include <com/sun/star/frame/XStatusListener.hpp>
      45             : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      46             : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
      47             : #include <com/sun/star/document/XExporter.hpp>
      48             : #include <rtl/textenc.h>
      49             : #include <rtl/uri.h>
      50             : #include <rtl/uri.hxx>
      51             : #include <rtl/ustrbuf.hxx>
      52             : #include <vcl/msgbox.hxx>
      53             : 
      54             : #include <sfx2/mailmodelapi.hxx>
      55             : #include "sfxtypes.hxx"
      56             : #include "sfx2/sfxresid.hxx"
      57             : #include <sfx2/sfxsids.hrc>
      58             : #include "dialog.hrc"
      59             : 
      60             : #include <unotools/tempfile.hxx>
      61             : #include <unotools/configitem.hxx>
      62             : #include <ucbhelper/content.hxx>
      63             : #include <tools/urlobj.hxx>
      64             : #include <unotools/useroptions.hxx>
      65             : #include <comphelper/extract.hxx>
      66             : #include <comphelper/mediadescriptor.hxx>
      67             : #include <comphelper/processfactory.hxx>
      68             : #include <comphelper/sequenceashashmap.hxx>
      69             : #include <comphelper/sequenceasvector.hxx>
      70             : #include <comphelper/storagehelper.hxx>
      71             : #include <comphelper/string.hxx>
      72             : #include <toolkit/helper/vclunohelper.hxx>
      73             : #include <vcl/svapp.hxx>
      74             : #include <cppuhelper/implbase1.hxx>
      75             : 
      76             : // --------------------------------------------------------------
      77             : using namespace ::com::sun::star;
      78             : using namespace ::com::sun::star::beans;
      79             : using namespace ::com::sun::star::frame;
      80             : using namespace ::com::sun::star::io;
      81             : using namespace ::com::sun::star::lang;
      82             : using namespace ::com::sun::star::ucb;
      83             : using namespace ::com::sun::star::uno;
      84             : using namespace ::com::sun::star::util;
      85             : using namespace ::com::sun::star::system;
      86             : using namespace ::rtl;
      87             : 
      88             : // - class PrepareListener_Impl ------------------------------------------
      89             : class PrepareListener_Impl : public ::cppu::WeakImplHelper1< css::frame::XStatusListener >
      90             : {
      91             :     bool m_bState;
      92             : public:
      93             :         PrepareListener_Impl();
      94             :         virtual ~PrepareListener_Impl();
      95             : 
      96             :         // css.frame.XStatusListener
      97             :         virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& aEvent)
      98             :           throw(css::uno::RuntimeException);
      99             : 
     100             :         // css.lang.XEventListener
     101             :         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
     102             :           throw(css::uno::RuntimeException);
     103             : 
     104           0 :         bool IsSet() const {return m_bState;}
     105             : };
     106             : 
     107           0 : PrepareListener_Impl::PrepareListener_Impl() :
     108           0 :     m_bState( false )
     109             : {
     110           0 : }
     111             : 
     112           0 : PrepareListener_Impl::~PrepareListener_Impl()
     113             : {
     114           0 : }
     115             : 
     116           0 : void PrepareListener_Impl::statusChanged(const css::frame::FeatureStateEvent& rEvent) throw(css::uno::RuntimeException)
     117             : {
     118           0 :     if( rEvent.IsEnabled )
     119           0 :         rEvent.State >>= m_bState;
     120             :     else
     121           0 :         m_bState = sal_False;
     122           0 : }
     123             : 
     124           0 : void PrepareListener_Impl::disposing(const css::lang::EventObject& /*rEvent*/) throw(css::uno::RuntimeException)
     125             : {
     126           0 : }
     127             : 
     128             : // class SfxMailModel -----------------------------------------------
     129             : 
     130             : static const char       PDF_DOCUMENT_TYPE[]   = "pdf_Portable_Document_Format";
     131             : static const sal_uInt32 PDF_DOCUMENT_TYPE_LEN = 28;
     132             : 
     133           0 : void SfxMailModel::ClearList( AddressList_Impl* pList )
     134             : {
     135           0 :     if ( pList )
     136             :     {
     137           0 :         for( size_t i = 0, n = pList->size(); i < n; ++i )
     138           0 :             delete pList->at(i);
     139           0 :         pList->clear();
     140             :     }
     141           0 : }
     142             : 
     143           0 : sal_Bool HasDocumentValidSignature( const css::uno::Reference< css::frame::XModel >& xModel )
     144             : {
     145             :     try
     146             :     {
     147           0 :         css::uno::Reference< css::beans::XPropertySet > xPropSet( xModel, css::uno::UNO_QUERY );
     148           0 :         if ( xPropSet.is() )
     149             :         {
     150           0 :             Any a = xPropSet->getPropertyValue( rtl::OUString( "HasValidSignatures" ));
     151           0 :             sal_Bool bReturn = sal_Bool();
     152           0 :             if ( a >>= bReturn )
     153           0 :                 return bReturn;
     154           0 :         }
     155             :     }
     156           0 :     catch ( css::uno::RuntimeException& )
     157             :     {
     158           0 :         throw;
     159             :     }
     160           0 :     catch ( css::uno::Exception& )
     161             :     {
     162             :     }
     163             : 
     164           0 :     return sal_False;
     165             : }
     166             : 
     167           0 : SfxMailModel::SaveResult SfxMailModel::ShowFilterOptionsDialog(
     168             :     uno::Reference< lang::XMultiServiceFactory > xSMGR,
     169             :     uno::Reference< frame::XModel > xModel,
     170             :     const rtl::OUString& rFilterName,
     171             :     const rtl::OUString& rType,
     172             :     bool bModified,
     173             :     sal_Int32& rNumArgs,
     174             :     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs )
     175             : {
     176           0 :     SaveResult eRet( SAVE_ERROR );
     177             : 
     178             :     try
     179             :     {
     180           0 :         uno::Sequence < beans::PropertyValue > aProps;
     181             :             ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xFilterCFG =
     182             :                 uno::Reference< container::XNameAccess >(
     183           0 :                     xSMGR->createInstance(
     184           0 :                         ::rtl::OUString("com.sun.star.document.FilterFactory") ), uno::UNO_QUERY );
     185           0 :         css::uno::Reference< css::util::XModifiable > xModifiable( xModel, css::uno::UNO_QUERY );
     186             : 
     187           0 :         if ( !xFilterCFG.is() )
     188           0 :             return eRet;
     189             : 
     190           0 :         uno::Any aAny = xFilterCFG->getByName( rFilterName );
     191             : 
     192           0 :         if ( aAny >>= aProps )
     193             :         {
     194           0 :             sal_Int32 nPropertyCount = aProps.getLength();
     195           0 :             for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
     196             :             {
     197           0 :                 if( aProps[nProperty].Name == "UIComponent" )
     198             :                 {
     199           0 :                     ::rtl::OUString aServiceName;
     200           0 :                     aProps[nProperty].Value >>= aServiceName;
     201           0 :                     if( !aServiceName.isEmpty() )
     202             :                     {
     203             :                         uno::Reference< ui::dialogs::XExecutableDialog > xFilterDialog(
     204           0 :                             xSMGR->createInstance( aServiceName ), uno::UNO_QUERY );
     205             :                         uno::Reference< beans::XPropertyAccess > xFilterProperties(
     206           0 :                             xFilterDialog, uno::UNO_QUERY );
     207             : 
     208           0 :                         if( xFilterDialog.is() && xFilterProperties.is() )
     209             :                         {
     210           0 :                             uno::Sequence< beans::PropertyValue > aPropsForDialog(1);
     211           0 :                             uno::Reference< document::XExporter > xExporter( xFilterDialog, uno::UNO_QUERY );
     212             : 
     213           0 :                             if ( rType.equalsAsciiL( PDF_DOCUMENT_TYPE, PDF_DOCUMENT_TYPE_LEN ))
     214             :                             {
     215             :                                 //add an internal property, used to tell the dialog we want to set a different
     216             :                                 //string for the ok button
     217             :                                 //used in filter/source/pdf/impdialog.cxx
     218           0 :                                 uno::Sequence< beans::PropertyValue > aFilterDataValue(1);
     219           0 :                                 aFilterDataValue[0].Name = ::rtl::OUString( "_OkButtonString" );
     220           0 :                                 aFilterDataValue[0].Value = css::uno::makeAny(SfxResId(STR_PDF_EXPORT_SEND ).toString());
     221             : 
     222             :                                 //add to the filterdata property, the only one the PDF export filter dialog will care for
     223           0 :                                 aPropsForDialog[0].Name =  ::rtl::OUString( "FilterData" );
     224           0 :                                 aPropsForDialog[0].Value = css::uno::makeAny( aFilterDataValue );
     225             : 
     226             :                                 //when executing the dialog will merge the persistent FilterData properties
     227           0 :                                 xFilterProperties->setPropertyValues( aPropsForDialog );
     228             :                             }
     229             : 
     230           0 :                             if( xExporter.is() )
     231           0 :                                 xExporter->setSourceDocument(
     232           0 :                                     uno::Reference< lang::XComponent >( xModel, uno::UNO_QUERY ) );
     233             : 
     234           0 :                             if( xFilterDialog->execute() )
     235             :                             {
     236             :                                 //get the filter data
     237           0 :                                 uno::Sequence< beans::PropertyValue > aPropsFromDialog = xFilterProperties->getPropertyValues();
     238             : 
     239             :                                 //add them to the args
     240           0 :                                 for ( sal_Int32 nInd = 0; nInd < aPropsFromDialog.getLength(); nInd++ )
     241             :                                 {
     242           0 :                                     if( aPropsFromDialog[ nInd ].Name == "FilterData" )
     243             :                                     {
     244             :                                         //found the filterdata, add to the storing argument
     245           0 :                                         rArgs.realloc( ++rNumArgs );
     246           0 :                                         rArgs[rNumArgs-1].Name = aPropsFromDialog[ nInd ].Name;
     247           0 :                                         rArgs[rNumArgs-1].Value = aPropsFromDialog[ nInd ].Value;
     248           0 :                                         break;
     249             :                                     }
     250             :                                 }
     251           0 :                                 eRet = SAVE_SUCCESSFULL;
     252             :                             }
     253             :                             else
     254             :                             {
     255             :                                 // cancel from dialog, then do not send
     256             :                                 // If the model is not modified, it could be modified by the dispatch calls.
     257             :                                 // Therefore set back to modified = false. This should not hurt if we call
     258             :                                 // on a non-modified model.
     259           0 :                                 if ( !bModified )
     260             :                                 {
     261             :                                     try
     262             :                                     {
     263           0 :                                         xModifiable->setModified( sal_False );
     264             :                                     }
     265           0 :                                     catch( com::sun::star::beans::PropertyVetoException& )
     266             :                                     {
     267             :                                     }
     268             :                                 }
     269           0 :                                 eRet = SAVE_CANCELLED;
     270           0 :                             }
     271             :                         }
     272           0 :                         break;
     273           0 :                     }
     274             :                 }
     275             :             }
     276           0 :         }
     277             :     }
     278           0 :     catch( css::uno::RuntimeException& )
     279             :     {
     280           0 :         throw;
     281             :     }
     282           0 :     catch( uno::Exception& )
     283             :     {
     284             :     }
     285             : 
     286           0 :     return eRet;
     287             : }
     288             : 
     289           0 : sal_Bool SfxMailModel::IsEmpty() const
     290             : {
     291           0 :     return maAttachedDocuments.empty();
     292             : }
     293             : 
     294           0 : SfxMailModel::SaveResult SfxMailModel::SaveDocumentAsFormat(
     295             :     const rtl::OUString& aSaveFileName,
     296             :     const css::uno::Reference< css::uno::XInterface >& xFrameOrModel,
     297             :     const rtl::OUString& rType,
     298             :     rtl::OUString& rFileNamePath )
     299             : {
     300           0 :     SaveResult  eRet( SAVE_ERROR );
     301           0 :     bool        bSendAsPDF = (rType.equalsAsciiL( PDF_DOCUMENT_TYPE, PDF_DOCUMENT_TYPE_LEN ));
     302             : 
     303           0 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = ::comphelper::getProcessServiceFactory();
     304           0 :     css::uno::Reference< css::uno::XComponentContext > xContext  = ::comphelper::getProcessComponentContext();
     305           0 :     if (!xContext.is())
     306           0 :         return eRet;
     307             : 
     308           0 :     css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( css::frame::ModuleManager::create(xContext) );
     309             : 
     310           0 :     rtl::OUString aModule;
     311             :     try
     312             :     {
     313           0 :          aModule = xModuleManager->identify( xFrameOrModel );
     314             :     }
     315           0 :     catch ( css::uno::RuntimeException& )
     316             :     {
     317           0 :         throw;
     318             :     }
     319           0 :     catch ( css::uno::Exception& )
     320             :     {
     321             :     }
     322             : 
     323           0 :     css::uno::Reference< css::frame::XFrame > xFrame( xFrameOrModel, css::uno::UNO_QUERY );
     324           0 :     css::uno::Reference< css::frame::XModel > xModel( xFrameOrModel, css::uno::UNO_QUERY );
     325           0 :     if ( xFrame.is() )
     326             :     {
     327           0 :         css::uno::Reference< css::frame::XController > xController = xFrame->getController();
     328           0 :         if ( xController.is() )
     329           0 :             xModel = xController->getModel();
     330             :     }
     331             : 
     332             :     // We need at least a valid module name and model reference
     333           0 :     if ( !aModule.isEmpty()  && xModel.is() )
     334             :     {
     335           0 :         bool bModified( false );
     336           0 :         bool bHasLocation( false );
     337           0 :         bool bStoreTo( false );
     338             : 
     339           0 :         css::uno::Reference< css::util::XModifiable > xModifiable( xModel, css::uno::UNO_QUERY );
     340           0 :         css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY );
     341             : 
     342           0 :         if ( xModifiable.is() )
     343           0 :             bModified = xModifiable->isModified();
     344           0 :         if ( xStorable.is() )
     345             :         {
     346           0 :             rtl::OUString aLocation = xStorable->getLocation();
     347           0 :             INetURLObject aFileObj( aLocation );
     348             : 
     349           0 :             bool bPrivateProtocol = ( aFileObj.GetProtocol() == INET_PROT_PRIV_SOFFICE );
     350             : 
     351           0 :             bHasLocation =  !aLocation.isEmpty() && !bPrivateProtocol;
     352           0 :             OSL_ASSERT( !bPrivateProtocol );
     353             :         }
     354           0 :         if ( !rType.isEmpty() )
     355           0 :             bStoreTo = true;
     356             : 
     357           0 :         if ( xStorable.is() )
     358             :         {
     359           0 :             rtl::OUString aFilterName;
     360           0 :             rtl::OUString aTypeName( rType );
     361           0 :             rtl::OUString aFileName;
     362           0 :             rtl::OUString aExtension;
     363             : 
     364             :             css::uno::Reference< css::container::XContainerQuery > xContainerQuery(
     365           0 :                 xSMGR->createInstance( rtl::OUString(
     366           0 :                     "com.sun.star.document.FilterFactory" )),
     367           0 :                     css::uno::UNO_QUERY );
     368             : 
     369           0 :             if ( bStoreTo )
     370             :             {
     371             :                 // Retrieve filter from type
     372           0 :                 css::uno::Sequence< css::beans::NamedValue > aQuery( bSendAsPDF ? 3 : 2 );
     373           0 :                 aQuery[0].Name  = rtl::OUString( "Type" );
     374           0 :                 aQuery[0].Value = css::uno::makeAny( aTypeName );
     375           0 :                 aQuery[1].Name  = rtl::OUString( "DocumentService" );
     376           0 :                 aQuery[1].Value = css::uno::makeAny( aModule );
     377           0 :                 if( bSendAsPDF )
     378             :                 {
     379             :                     // #i91419#
     380             :                     // FIXME: we want just an export filter. However currently we need
     381             :                     // exact flag value as detailed in the filter configuration to get it
     382             :                     // this seems to be a bug
     383             :                     // without flags we get an import filter here, which is also unwanted
     384           0 :                     aQuery[2].Name  = rtl::OUString( "Flags" );
     385           0 :                     aQuery[2].Value = css::uno::makeAny( sal_Int32(0x80042) ); // EXPORT ALIEN 3RDPARTY
     386             :                 }
     387             : 
     388             :                 css::uno::Reference< css::container::XEnumeration > xEnumeration =
     389           0 :                     xContainerQuery->createSubSetEnumerationByProperties( aQuery );
     390             : 
     391           0 :                 if ( xEnumeration->hasMoreElements() )
     392             :                 {
     393           0 :                     ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() );
     394             :                     aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
     395             :                                                 ::rtl::OUString("Name"),
     396           0 :                                                 ::rtl::OUString() );
     397             :                 }
     398             : 
     399           0 :                 if ( bHasLocation )
     400             :                 {
     401             :                     // Retrieve filter from media descriptor
     402           0 :                     ::comphelper::SequenceAsHashMap aMediaDescrPropsHM( xModel->getArgs() );
     403             :                     rtl::OUString aOrgFilterName = aMediaDescrPropsHM.getUnpackedValueOrDefault(
     404             :                                     ::rtl::OUString( "FilterName" ),
     405           0 :                                     ::rtl::OUString() );
     406           0 :                     if ( aOrgFilterName == aFilterName )
     407             :                     {
     408             :                         // We should save the document in the original format. Therefore this
     409             :                         // is not a storeTo operation. To support signing in this case, reset
     410             :                         // bStoreTo flag.
     411           0 :                         bStoreTo = false;
     412           0 :                     }
     413           0 :                 }
     414             :             }
     415             :             else
     416             :             {
     417           0 :                 if ( bHasLocation )
     418             :                 {
     419             :                     // Retrieve filter from media descriptor
     420           0 :                     ::comphelper::SequenceAsHashMap aMediaDescrPropsHM( xModel->getArgs() );
     421             :                     aFilterName = aMediaDescrPropsHM.getUnpackedValueOrDefault(
     422             :                                     ::rtl::OUString( "FilterName" ),
     423           0 :                                     ::rtl::OUString() );
     424             :                 }
     425             : 
     426           0 :                 if ( !bHasLocation ||  aFilterName.isEmpty())
     427             :                 {
     428             :                     // Retrieve the user defined default filter
     429             :                     try
     430             :                     {
     431           0 :                         ::comphelper::SequenceAsHashMap aFilterPropsHM( xModuleManager->getByName( aModule ) );
     432             :                         aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
     433             :                                                     ::rtl::OUString("ooSetupFactoryDefaultFilter"),
     434           0 :                                                     ::rtl::OUString() );
     435             :                         css::uno::Reference< css::container::XNameAccess > xNameAccess(
     436           0 :                             xContainerQuery, css::uno::UNO_QUERY );
     437           0 :                         if ( xNameAccess.is() )
     438             :                         {
     439           0 :                             ::comphelper::SequenceAsHashMap aFilterPropsHM2( xNameAccess->getByName( aFilterName ) );
     440             :                             aTypeName = aFilterPropsHM2.getUnpackedValueOrDefault(
     441             :                                                         ::rtl::OUString("Type"),
     442           0 :                                                         ::rtl::OUString() );
     443           0 :                         }
     444             :                     }
     445           0 :                     catch ( css::container::NoSuchElementException& )
     446             :                     {
     447             :                     }
     448           0 :                     catch ( css::beans::UnknownPropertyException& )
     449             :                     {
     450             :                     }
     451             :                 }
     452             :             }
     453             : 
     454             :             // No filter found => error
     455             :             // No type and no location => error
     456           0 :             if (( aFilterName.isEmpty() ) ||
     457           0 :                 ( aTypeName.isEmpty()  && !bHasLocation ))
     458           0 :                 return eRet;
     459             : 
     460             :             // Determine filen name and extension
     461           0 :             if ( bHasLocation && !bStoreTo )
     462             :             {
     463           0 :                 INetURLObject aFileObj( xStorable->getLocation() );
     464           0 :                 aExtension = (rtl::OUString)aFileObj.getExtension();
     465             :             }
     466             :             else
     467             :             {
     468             :                 css::uno::Reference< container::XNameAccess > xTypeDetection(
     469           0 :                     xSMGR->createInstance( ::rtl::OUString(
     470           0 :                         "com.sun.star.document.TypeDetection" )),
     471           0 :                     css::uno::UNO_QUERY );
     472             : 
     473             : 
     474           0 :                 if ( xTypeDetection.is() )
     475             :                 {
     476             :                     try
     477             :                     {
     478           0 :                         ::comphelper::SequenceAsHashMap aTypeNamePropsHM( xTypeDetection->getByName( aTypeName ) );
     479             :                         uno::Sequence< ::rtl::OUString > aExtensions = aTypeNamePropsHM.getUnpackedValueOrDefault(
     480             :                                                         ::rtl::OUString("Extensions"),
     481           0 :                                                         ::uno::Sequence< ::rtl::OUString >() );
     482           0 :                         if ( aExtensions.getLength() )
     483           0 :                             aExtension = aExtensions[0];
     484             :                     }
     485           0 :                     catch ( css::container::NoSuchElementException& )
     486             :                     {
     487             :                     }
     488           0 :                 }
     489             :             }
     490             : 
     491             :             // Use provided save file name. If empty determine file name
     492           0 :             aFileName = aSaveFileName;
     493           0 :             if ( aFileName.isEmpty() )
     494             :             {
     495           0 :                 if ( !bHasLocation )
     496             :                 {
     497             :                     // Create a noname file name with the correct extension
     498           0 :                     const rtl::OUString aNoNameFileName( "noname" );
     499           0 :                     aFileName = aNoNameFileName;
     500             :                 }
     501             :                 else
     502             :                 {
     503             :                     // Determine file name from model
     504           0 :                     INetURLObject aFileObj( xStorable->getLocation() );
     505           0 :                     aFileName = aFileObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE );
     506             :                 }
     507             :             }
     508             : 
     509             :             // No file name => error
     510           0 :             if ( aFileName.isEmpty() )
     511           0 :                 return eRet;
     512             : 
     513             :             OSL_ASSERT( !aFilterName.isEmpty() );
     514             :             OSL_ASSERT( !aFileName.isEmpty() );
     515             : 
     516             :             // Creates a temporary directory to store a predefined file into it.
     517             :             // This makes it possible to store the file for "send document as e-mail"
     518             :             // with the original file name. We cannot use the original file as
     519             :             // some mail programs need exclusive access.
     520           0 :             ::utl::TempFile aTempDir( NULL, sal_True );
     521             : 
     522           0 :             INetURLObject aFilePathObj( aTempDir.GetURL() );
     523           0 :             aFilePathObj.insertName( aFileName );
     524           0 :             aFilePathObj.setExtension( aExtension );
     525             : 
     526           0 :             rtl::OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::NO_DECODE );
     527             : 
     528           0 :             sal_Int32 nNumArgs(0);
     529           0 :             const rtl::OUString aPasswordPropName( "Password" );
     530           0 :             css::uno::Sequence< css::beans::PropertyValue > aArgs( ++nNumArgs );
     531           0 :             aArgs[nNumArgs-1].Name  = rtl::OUString( "FilterName" );
     532           0 :             aArgs[nNumArgs-1].Value = css::uno::makeAny( aFilterName );
     533             : 
     534           0 :             ::comphelper::SequenceAsHashMap aMediaDescrPropsHM( xModel->getArgs() );
     535             :             rtl::OUString aPassword = aMediaDescrPropsHM.getUnpackedValueOrDefault(
     536             :                                             aPasswordPropName,
     537           0 :                                             ::rtl::OUString() );
     538           0 :             if ( !aPassword.isEmpty() )
     539             :             {
     540           0 :                 aArgs.realloc( ++nNumArgs );
     541           0 :                 aArgs[nNumArgs-1].Name = aPasswordPropName;
     542           0 :                 aArgs[nNumArgs-1].Value = css::uno::makeAny( aPassword );
     543             :             }
     544             : 
     545           0 :             bool bNeedsPreparation = false;
     546           0 :             css::util::URL aPrepareURL;
     547           0 :             css::uno::Reference< css::frame::XDispatch > xPrepareDispatch;
     548           0 :             css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( xFrame, css::uno::UNO_QUERY );
     549           0 :             css::uno::Reference< css::util::XURLTransformer > xURLTransformer( css::util::URLTransformer::create( ::comphelper::getComponentContext(xSMGR) ) );
     550           0 :             if( !bSendAsPDF )
     551             :             {
     552             :                 try
     553             :                 {
     554             :                     // check if the document needs to be prepared for sending as mail (embedding of links, removal of invisible content)
     555             : 
     556           0 :                     aPrepareURL.Complete = rtl::OUString( ".uno:PrepareMailExport" );
     557           0 :                     xURLTransformer->parseStrict( aPrepareURL );
     558             : 
     559           0 :                     if ( xDispatchProvider.is() )
     560             :                     {
     561             :                         xPrepareDispatch = css::uno::Reference< css::frame::XDispatch >(
     562           0 :                             xDispatchProvider->queryDispatch( aPrepareURL, ::rtl::OUString(), 0 ));
     563           0 :                         if ( xPrepareDispatch.is() )
     564             :                         {
     565             :                                 PrepareListener_Impl* pPrepareListener;
     566           0 :                                 uno::Reference< css::frame::XStatusListener > xStatusListener = pPrepareListener = new PrepareListener_Impl;
     567           0 :                                 xPrepareDispatch->addStatusListener( xStatusListener, aPrepareURL );
     568           0 :                                 bNeedsPreparation = pPrepareListener->IsSet();
     569           0 :                                 xPrepareDispatch->removeStatusListener( xStatusListener, aPrepareURL );
     570             :                         }
     571             :                     }
     572             :                 }
     573           0 :                 catch ( css::uno::RuntimeException& )
     574             :                 {
     575           0 :                     throw;
     576             :                 }
     577           0 :                 catch ( css::uno::Exception& )
     578             :                 {
     579             :                 }
     580             :             }
     581             : 
     582           0 :             if ( bModified || !bHasLocation || bStoreTo || bNeedsPreparation )
     583             :             {
     584             :                 // Document is modified, is newly created or should be stored in a special format
     585             :                 try
     586             :                 {
     587           0 :                     if( bNeedsPreparation && xPrepareDispatch.is() )
     588             :                     {
     589           0 :                         if ( xPrepareDispatch.is() )
     590             :                         {
     591             :                             try
     592             :                             {
     593           0 :                                 css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs;
     594           0 :                                 xPrepareDispatch->dispatch( aPrepareURL, aDispatchArgs );
     595             :                             }
     596           0 :                             catch ( css::uno::RuntimeException& )
     597             :                             {
     598           0 :                                 throw;
     599             :                             }
     600           0 :                             catch ( css::uno::Exception& )
     601             :                             {
     602             :                             }
     603             :                         }
     604             :                     }
     605             : 
     606             :                     //check if this is the pdf otput filter (i#64555)
     607           0 :                     if( bSendAsPDF )
     608             :                     {
     609             :                         SaveResult eShowPDFFilterDialog = ShowFilterOptionsDialog(
     610           0 :                                                             xSMGR, xModel, aFilterName, rType, bModified, nNumArgs, aArgs );
     611             : 
     612             :                         // don't continue on dialog cancel or error
     613           0 :                         if ( eShowPDFFilterDialog != SAVE_SUCCESSFULL )
     614           0 :                             return eShowPDFFilterDialog;
     615             :                     }
     616             : 
     617           0 :                     xStorable->storeToURL( aFileURL, aArgs );
     618           0 :                     rFileNamePath = aFileURL;
     619           0 :                     eRet = SAVE_SUCCESSFULL;
     620             : 
     621           0 :                     if( !bSendAsPDF )
     622             :                     {
     623           0 :                         css::util::URL aURL;
     624             :                         // #i30432# notify that export is finished - the Writer may want to restore removed content
     625           0 :                         aURL.Complete = rtl::OUString( ".uno:MailExportFinished" );
     626           0 :                         xURLTransformer->parseStrict( aURL );
     627             : 
     628           0 :                         if ( xDispatchProvider.is() )
     629             :                         {
     630             :                             css::uno::Reference< css::frame::XDispatch > xDispatch = css::uno::Reference< css::frame::XDispatch >(
     631           0 :                                 xDispatchProvider->queryDispatch( aURL, ::rtl::OUString(), 0 ));
     632           0 :                             if ( xDispatch.is() )
     633             :                             {
     634             :                                 try
     635             :                                 {
     636           0 :                                     css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs;
     637           0 :                                     xDispatch->dispatch( aURL, aDispatchArgs );
     638             :                                 }
     639           0 :                                 catch ( css::uno::RuntimeException& )
     640             :                                 {
     641           0 :                                     throw;
     642             :                                 }
     643           0 :                                 catch ( css::uno::Exception& )
     644             :                                 {
     645             :                                 }
     646           0 :                             }
     647           0 :                         }
     648             :                     }
     649             :                     // If the model is not modified, it could be modified by the dispatch calls.
     650             :                     // Therefore set back to modified = false. This should not hurt if we call
     651             :                     // on a non-modified model.
     652           0 :                     if ( !bModified )
     653             :                     {
     654             :                         try
     655             :                         {
     656           0 :                             xModifiable->setModified( sal_False );
     657             :                         }
     658           0 :                         catch( com::sun::star::beans::PropertyVetoException& )
     659             :                         {
     660             :                         }
     661             :                     }
     662             :                 }
     663           0 :                 catch ( com::sun::star::io::IOException& )
     664             :                 {
     665           0 :                     eRet = SAVE_ERROR;
     666           0 :                 }
     667             :             }
     668             :             else
     669             :             {
     670             :                 // We need 1:1 copy of the document to preserve an added signature.
     671           0 :                 aArgs.realloc( ++nNumArgs );
     672           0 :                 aArgs[nNumArgs-1].Name = ::rtl::OUString( "CopyStreamIfPossible"  );
     673           0 :                 aArgs[nNumArgs-1].Value = css::uno::makeAny( (sal_Bool)sal_True );
     674             : 
     675             :                 try
     676             :                 {
     677           0 :                     xStorable->storeToURL( aFileURL, aArgs );
     678           0 :                     rFileNamePath = aFileURL;
     679           0 :                     eRet = SAVE_SUCCESSFULL;
     680             :                 }
     681           0 :                 catch ( com::sun::star::io::IOException& )
     682             :                 {
     683           0 :                     eRet = SAVE_ERROR;
     684             :                 }
     685           0 :             }
     686           0 :         }
     687             :     }
     688             : 
     689           0 :     return eRet;
     690             : }
     691             : 
     692           0 : SfxMailModel::SfxMailModel() :
     693             :     mpToList    ( NULL ),
     694             :     mpCcList    ( NULL ),
     695             :     mpBccList   ( NULL ),
     696             :     mePriority  ( PRIO_NORMAL ),
     697           0 :     mbLoadDone  ( sal_True )
     698             : {
     699           0 : }
     700             : 
     701           0 : SfxMailModel::~SfxMailModel()
     702             : {
     703           0 :     ClearList( mpToList );
     704           0 :     delete mpToList;
     705           0 :     ClearList( mpCcList );
     706           0 :     delete mpCcList;
     707           0 :     ClearList( mpBccList );
     708           0 :     delete mpBccList;
     709           0 : }
     710             : 
     711           0 : void SfxMailModel::AddAddress( const String& rAddress, AddressRole eRole )
     712             : {
     713             :     // don't add a empty address
     714           0 :     if ( rAddress.Len() > 0 )
     715             :     {
     716           0 :         AddressList_Impl* pList = NULL;
     717           0 :         if ( ROLE_TO == eRole )
     718             :         {
     719           0 :             if ( !mpToList )
     720             :                 // create the list
     721           0 :                 mpToList = new AddressList_Impl();
     722           0 :             pList = mpToList;
     723             :         }
     724           0 :         else if ( ROLE_CC == eRole )
     725             :         {
     726           0 :             if ( !mpCcList )
     727             :                 // create the list
     728           0 :                 mpCcList = new AddressList_Impl();
     729           0 :             pList = mpCcList;
     730             :         }
     731           0 :         else if ( ROLE_BCC == eRole )
     732             :         {
     733           0 :             if ( !mpBccList )
     734             :                 // create the list
     735           0 :                 mpBccList = new AddressList_Impl();
     736           0 :             pList = mpBccList;
     737             :         }
     738             :         else
     739             :         {
     740             :             SAL_WARN( "sfx2.dialog", "invalid address role" );
     741             :         }
     742             : 
     743           0 :         if ( pList )
     744             :         {
     745             :             // add address to list
     746           0 :             AddressItemPtr_Impl pAddress = new String( rAddress );
     747           0 :             pList->push_back( pAddress );
     748             :         }
     749             :     }
     750           0 : }
     751             : 
     752           0 : SfxMailModel::SendMailResult SfxMailModel::AttachDocument(
     753             :     const ::rtl::OUString& sDocumentType,
     754             :     const css::uno::Reference< css::uno::XInterface >& xFrameOrModel,
     755             :     const ::rtl::OUString& sAttachmentTitle )
     756             : {
     757           0 :     rtl::OUString sFileName;
     758             : 
     759           0 :     SaveResult eSaveResult = SaveDocumentAsFormat( sAttachmentTitle, xFrameOrModel, sDocumentType, sFileName );
     760           0 :     if ( eSaveResult == SAVE_SUCCESSFULL &&  !sFileName.isEmpty() )
     761           0 :         maAttachedDocuments.push_back(sFileName);
     762           0 :     return eSaveResult == SAVE_SUCCESSFULL ? SEND_MAIL_OK : SEND_MAIL_ERROR;
     763             : }
     764             : 
     765           0 : SfxMailModel::SendMailResult SfxMailModel::Send( const css::uno::Reference< css::frame::XFrame >& xFrame )
     766             : {
     767             :     OSL_ENSURE(!maAttachedDocuments.empty(),"No document added!");
     768           0 :     SendMailResult  eResult = SEND_MAIL_ERROR;
     769           0 :     if ( !maAttachedDocuments.empty() )
     770             :     {
     771           0 :         css::uno::Reference < XMultiServiceFactory > xMgr = ::comphelper::getProcessServiceFactory();
     772           0 :         if ( xMgr.is() )
     773             :         {
     774           0 :             css::uno::Reference< XSimpleMailClientSupplier >    xSimpleMailClientSupplier;
     775             : 
     776             :             // Prefer the SimpleSystemMail service if available
     777             :             xSimpleMailClientSupplier = css::uno::Reference< XSimpleMailClientSupplier >(
     778           0 :                 xMgr->createInstance( OUString( "com.sun.star.system.SimpleSystemMail" )),
     779           0 :                 UNO_QUERY );
     780             : 
     781           0 :             if ( ! xSimpleMailClientSupplier.is() )
     782             :             {
     783             :                 xSimpleMailClientSupplier = css::uno::Reference< XSimpleMailClientSupplier >(
     784           0 :                     xMgr->createInstance( OUString( "com.sun.star.system.SimpleCommandMail" )),
     785           0 :                     UNO_QUERY );
     786             :             }
     787             : 
     788           0 :             if ( xSimpleMailClientSupplier.is() )
     789             :             {
     790           0 :                 css::uno::Reference< XSimpleMailClient > xSimpleMailClient = xSimpleMailClientSupplier->querySimpleMailClient();
     791             : 
     792           0 :                 if ( !xSimpleMailClient.is() )
     793             :                 {
     794             :                     // no mail client support => message box!
     795           0 :                     return SEND_MAIL_ERROR;
     796             :                 }
     797             : 
     798             :                 // we have a simple mail client
     799           0 :                 css::uno::Reference< XSimpleMailMessage > xSimpleMailMessage = xSimpleMailClient->createSimpleMailMessage();
     800           0 :                 if ( xSimpleMailMessage.is() )
     801             :                 {
     802           0 :                     sal_Int32 nSendFlags = SimpleMailClientFlags::DEFAULTS;
     803           0 :                     if ( maFromAddress.Len() == 0 )
     804             :                     {
     805             :                         // from address not set, try figure out users e-mail address
     806           0 :                         CreateFromAddress_Impl( maFromAddress );
     807             :                     }
     808           0 :                     xSimpleMailMessage->setOriginator( maFromAddress );
     809             : 
     810           0 :                     size_t nToCount     = mpToList ? mpToList->size() : 0;
     811           0 :                     size_t nCcCount     = mpCcList ? mpCcList->size() : 0;
     812           0 :                     size_t nCcSeqCount  = nCcCount;
     813             : 
     814             :                     // set recipient (only one) for this simple mail server!!
     815           0 :                     if ( nToCount > 1 )
     816             :                     {
     817           0 :                         nCcSeqCount = nToCount - 1 + nCcCount;
     818           0 :                         xSimpleMailMessage->setRecipient( *mpToList->at( 0 ) );
     819           0 :                         nSendFlags = SimpleMailClientFlags::NO_USER_INTERFACE;
     820             :                     }
     821           0 :                     else if ( nToCount == 1 )
     822             :                     {
     823           0 :                         xSimpleMailMessage->setRecipient( *mpToList->at( 0 ) );
     824           0 :                         nSendFlags = SimpleMailClientFlags::NO_USER_INTERFACE;
     825             :                     }
     826             : 
     827             :                     // all other recipient must be handled with CC recipients!
     828           0 :                     if ( nCcSeqCount > 0 )
     829             :                     {
     830           0 :                         size_t                  nIndex = 0;
     831           0 :                         Sequence< OUString >    aCcRecipientSeq;
     832             : 
     833           0 :                         aCcRecipientSeq.realloc( nCcSeqCount );
     834           0 :                         if ( nCcSeqCount > nCcCount )
     835             :                         {
     836           0 :                             for ( size_t i = 1; i < nToCount; ++i )
     837             :                             {
     838           0 :                                 aCcRecipientSeq[nIndex++] = *mpToList->at(i);
     839             :                             }
     840             :                         }
     841             : 
     842           0 :                         for ( size_t i = 0; i < nCcCount; i++ )
     843             :                         {
     844           0 :                             aCcRecipientSeq[nIndex++] = *mpCcList->at(i);
     845             :                         }
     846           0 :                         xSimpleMailMessage->setCcRecipient( aCcRecipientSeq );
     847             :                     }
     848             : 
     849           0 :                     size_t nBccCount = mpBccList ? mpBccList->size() : 0;
     850           0 :                     if ( nBccCount > 0 )
     851             :                     {
     852           0 :                         Sequence< OUString > aBccRecipientSeq( nBccCount );
     853           0 :                         for ( size_t i = 0; i < nBccCount; ++i )
     854             :                         {
     855           0 :                             aBccRecipientSeq[i] = *mpBccList->at(i);
     856             :                         }
     857           0 :                         xSimpleMailMessage->setBccRecipient( aBccRecipientSeq );
     858             :                     }
     859             : 
     860           0 :                     Sequence< OUString > aAttachmentSeq(&(maAttachedDocuments[0]),maAttachedDocuments.size());
     861             : 
     862           0 :                     if ( xSimpleMailMessage->getSubject().isEmpty() ) {
     863           0 :                         OUString baseName( maAttachedDocuments[0].copy( maAttachedDocuments[0].lastIndexOf( '/' ) + 1 ) );
     864           0 :                         OUString subject( baseName );
     865           0 :                         if ( maAttachedDocuments.size() > 1 )
     866           0 :                             subject += OUString(", ...");
     867           0 :                         xSimpleMailMessage->setSubject( subject );
     868             :                     }
     869           0 :                     xSimpleMailMessage->setAttachement( aAttachmentSeq );
     870             : 
     871           0 :                     sal_Bool bSend( sal_False );
     872             :                     try
     873             :                     {
     874           0 :                         xSimpleMailClient->sendSimpleMailMessage( xSimpleMailMessage, nSendFlags );
     875           0 :                         bSend = sal_True;
     876             :                     }
     877           0 :                     catch ( IllegalArgumentException& )
     878             :                     {
     879             :                     }
     880           0 :                     catch ( Exception& )
     881             :                     {
     882             :                     }
     883             : 
     884           0 :                     if ( bSend == sal_False )
     885             :                     {
     886           0 :                         css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
     887             : 
     888           0 :                         SolarMutexGuard aGuard;
     889           0 :                         Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
     890             : 
     891           0 :                         ErrorBox aBox( pParentWindow, SfxResId( RID_ERRBOX_MAIL_CONFIG ));
     892           0 :                         aBox.Execute();
     893           0 :                         eResult = SEND_MAIL_CANCELLED;
     894             :                     }
     895             :                     else
     896           0 :                         eResult = SEND_MAIL_OK;
     897           0 :                 }
     898           0 :             }
     899           0 :         }
     900             :     }
     901             :     else
     902           0 :         eResult = SEND_MAIL_CANCELLED;
     903             : 
     904           0 :     return eResult;
     905             : }
     906             : 
     907           0 : SfxMailModel::SendMailResult SfxMailModel::SaveAndSend( const css::uno::Reference< css::frame::XFrame >& xFrame, const rtl::OUString& rTypeName )
     908             : {
     909             :     SaveResult      eSaveResult;
     910           0 :     SendMailResult  eResult = SEND_MAIL_ERROR;
     911           0 :     rtl::OUString   aFileName;
     912             : 
     913           0 :     eSaveResult = SaveDocumentAsFormat( rtl::OUString(), xFrame, rTypeName, aFileName );
     914             : 
     915           0 :     if ( eSaveResult == SAVE_SUCCESSFULL )
     916             :     {
     917           0 :         maAttachedDocuments.push_back( aFileName );
     918           0 :         return Send( xFrame );
     919             :     }
     920           0 :     else if ( eSaveResult == SAVE_CANCELLED )
     921           0 :         eResult = SEND_MAIL_CANCELLED;
     922             : 
     923           0 :     return eResult;
     924             : }
     925             : 
     926             : // functions -------------------------------------------------------------
     927             : 
     928           0 : sal_Bool CreateFromAddress_Impl( String& rFrom )
     929             : 
     930             : /* [Description]
     931             : 
     932             :     This function tries to create a From-address with the help of IniManagers.
     933             :     For this the fields 'first name', 'Name' and 'Email' are read from the
     934             :     application-ini-data. If these fields are not set, FALSE is returned.
     935             : 
     936             :     [Return value]
     937             : 
     938             :     sal_True:       Address could be created.
     939             :     sal_False:      Address could not be created.
     940             : */
     941             : 
     942             : {
     943           0 :     SvtUserOptions aUserCFG;
     944           0 :     String aName        = aUserCFG.GetLastName  ();
     945           0 :     String aFirstName   = aUserCFG.GetFirstName ();
     946           0 :     if ( aFirstName.Len() || aName.Len() )
     947             :     {
     948           0 :         if ( aFirstName.Len() )
     949             :         {
     950           0 :             rFrom = comphelper::string::strip(aFirstName, ' ');
     951             : 
     952           0 :             if ( aName.Len() )
     953           0 :                 rFrom += ' ';
     954             :         }
     955           0 :         rFrom += comphelper::string::strip(aName, ' ');
     956             :         // remove illegal characters
     957           0 :         rFrom = comphelper::string::remove(rFrom, '<');
     958           0 :         rFrom = comphelper::string::remove(rFrom, '>');
     959           0 :         rFrom = comphelper::string::remove(rFrom, '@');
     960             :     }
     961           0 :     String aEmailName = aUserCFG.GetEmail();
     962             : 
     963             :     // remove illegal characters
     964           0 :     aEmailName = comphelper::string::remove(aEmailName, '<');
     965           0 :     aEmailName = comphelper::string::remove(aEmailName, '>');
     966             : 
     967           0 :     if ( aEmailName.Len() )
     968             :     {
     969           0 :         if ( rFrom.Len() )
     970           0 :             rFrom += ' ';
     971           0 :         ( ( rFrom += '<' ) += comphelper::string::strip(aEmailName, ' ') ) += '>';
     972             :     }
     973             :     else
     974           0 :         rFrom.Erase();
     975           0 :     return ( rFrom.Len() > 0 );
     976             : }
     977             : 
     978             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10