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

Generated by: LCOV version 1.11