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

Generated by: LCOV version 1.10