LCOV - code coverage report
Current view: top level - sw/source/core/uibase/uno - unomailmerge.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 2 647 0.3 %
Date: 2014-04-11 Functions: 1 40 2.5 %
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 <vcl/svapp.hxx>
      21             : #include <osl/mutex.hxx>
      22             : #include <svl/itemprop.hxx>
      23             : #include <svl/urihelper.hxx>
      24             : #include <svx/dataaccessdescriptor.hxx>
      25             : #include <tools/shl.hxx>
      26             : #include <unotools/tempfile.hxx>
      27             : #include <sfx2/app.hxx>
      28             : #include <sfx2/docfile.hxx>
      29             : #include <sfx2/docfilt.hxx>
      30             : #include <comphelper/processfactory.hxx>
      31             : #include <comphelper/string.hxx>
      32             : #include <cppuhelper/supportsservice.hxx>
      33             : #include <vcl/timer.hxx>
      34             : #include <com/sun/star/sdb/CommandType.hpp>
      35             : #include <com/sun/star/text/MailMergeType.hpp>
      36             : #include <com/sun/star/text/MailMergeEvent.hpp>
      37             : #include <com/sun/star/text/XMailMergeListener.hpp>
      38             : #include <com/sun/star/text/XMailMergeBroadcaster.hpp>
      39             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      40             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      41             : #include <com/sun/star/sdbc/XResultSet.hpp>
      42             : #include <com/sun/star/sdbc/XConnection.hpp>
      43             : #include <com/sun/star/sdbc/XRowSet.hpp>
      44             : #include <com/sun/star/frame/Desktop.hpp>
      45             : #include <com/sun/star/frame/XComponentLoader.hpp>
      46             : #include <com/sun/star/util/XCloseable.hpp>
      47             : #include <com/sun/star/util/CloseVetoException.hpp>
      48             : #include <com/sun/star/sdbcx/XRowLocate.hpp>
      49             : #include <com/sun/star/frame/XStorable.hpp>
      50             : #include "com/sun/star/mail/XSmtpService.hpp"
      51             : #include <sfx2/viewfrm.hxx>
      52             : #include <sfx2/event.hxx>
      53             : #include <swevent.hxx>
      54             : #include <unomailmerge.hxx>
      55             : #include <swdll.hxx>
      56             : #include <swmodule.hxx>
      57             : #include <unoprnms.hxx>
      58             : #include <unomap.hxx>
      59             : #include <swunohelper.hxx>
      60             : #include <docsh.hxx>
      61             : #include <IDocumentDeviceAccess.hxx>
      62             : #include <view.hxx>
      63             : #include <dbmgr.hxx>
      64             : #include <unotxdoc.hxx>
      65             : #include <prtopt.hxx>
      66             : #include <wrtsh.hxx>
      67             : #include <shellio.hxx>
      68             : #include <mmconfigitem.hxx>
      69             : #include <mailmergehelper.hxx>
      70             : 
      71             : #include <unomid.h>
      72             : 
      73             : #include <boost/scoped_ptr.hpp>
      74             : 
      75             : using namespace ::com::sun::star;
      76             : using namespace ::com::sun::star::frame;
      77             : using namespace ::com::sun::star::uno;
      78             : using namespace ::com::sun::star::lang;
      79             : using namespace ::com::sun::star::beans;
      80             : using namespace ::com::sun::star::text;
      81             : using namespace SWUnoHelper;
      82             : 
      83             : typedef ::utl::SharedUNOComponent< XInterface > SharedComponent;
      84             : 
      85           0 : osl::Mutex &    GetMailMergeMutex()
      86             : {
      87           0 :     static osl::Mutex   aMutex;
      88           0 :     return aMutex;
      89             : }
      90             : 
      91             : enum CloseResult
      92             : {
      93             :     eSuccess,       // successfully closed
      94             :     eVetoed,        // vetoed, ownership transferred to the vetoing instance
      95             :     eFailed         // failed for some unknown reason
      96             : };
      97           0 : static CloseResult CloseModelAndDocSh(
      98             :        Reference< frame::XModel > &rxModel,
      99             :        SfxObjectShellRef &rxDocSh )
     100             : {
     101           0 :     CloseResult eResult = eSuccess;
     102             : 
     103           0 :     rxDocSh = 0;
     104             : 
     105             :     //! models/documents should never be disposed (they may still be
     106             :     //! used for printing which is called asynchronously for example)
     107             :     //! instead call close
     108           0 :     Reference< util::XCloseable > xClose( rxModel, UNO_QUERY );
     109           0 :     if (xClose.is())
     110             :     {
     111             :         try
     112             :         {
     113             :             //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
     114             :             //! I.e. now that object is responsible for closing the model and doc shell.
     115           0 :             xClose->close( sal_True );
     116             :         }
     117           0 :         catch (const util::CloseVetoException&)
     118             :         {
     119             :             //! here we have the problem that the temporary file that is
     120             :             //! currently being printed will never be deleted. :-(
     121           0 :             eResult = eVetoed;
     122             :         }
     123           0 :         catch (const uno::RuntimeException&)
     124             :         {
     125           0 :             eResult = eFailed;
     126             :         }
     127             :     }
     128           0 :     return eResult;
     129             : }
     130             : 
     131           0 : static bool LoadFromURL_impl(
     132             :         Reference< frame::XModel > &rxModel,
     133             :         SfxObjectShellRef &rxDocSh,
     134             :         const OUString &rURL,
     135             :         bool bClose )
     136             :     throw (RuntimeException)
     137             : {
     138             :     // try to open the document readonly and hidden
     139           0 :     Reference< frame::XModel > xTmpModel;
     140           0 :     Sequence < PropertyValue > aArgs( 1 );
     141           0 :     aArgs[0].Name = "Hidden";
     142           0 :     sal_Bool bVal = sal_True;
     143           0 :     aArgs[0].Value <<= bVal;
     144             :     try
     145             :     {
     146           0 :         Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     147           0 :         xTmpModel = Reference < XModel >( xDesktop->loadComponentFromURL(
     148           0 :                 rURL, "_blank", 0, aArgs ), UNO_QUERY );
     149             :     }
     150           0 :     catch (const Exception&)
     151             :     {
     152           0 :         return false;
     153             :     }
     154             : 
     155             :     // try to get the DocShell
     156           0 :     SwDocShell *pTmpDocShell = 0;
     157           0 :     Reference < XUnoTunnel > xTunnel( xTmpModel, UNO_QUERY );
     158           0 :     if (xTunnel.is())
     159             :     {
     160             :         SwXTextDocument* pTextDoc = reinterpret_cast<SwXTextDocument *>(
     161           0 :                 xTunnel->getSomething( SwXTextDocument::getUnoTunnelId() ));
     162           0 :         pTmpDocShell = pTextDoc ? pTextDoc->GetDocShell() : 0;
     163             :     }
     164             : 
     165           0 :     bool bRes = false;
     166           0 :     if (xTmpModel.is() && pTmpDocShell)    // everything available?
     167             :     {
     168           0 :         if (bClose)
     169           0 :             CloseModelAndDocSh( rxModel, rxDocSh );
     170             :         // set new stuff
     171           0 :         rxModel = xTmpModel;
     172           0 :         rxDocSh = pTmpDocShell;
     173           0 :         bRes = true;
     174             :     }
     175             :     else
     176             :     {
     177             :         // SfxObjectShellRef is ok here, since the document will be explicitly closed
     178           0 :         SfxObjectShellRef xTmpDocSh = pTmpDocShell;
     179           0 :         CloseModelAndDocSh( xTmpModel, xTmpDocSh );
     180             :     }
     181             : 
     182           0 :     return bRes;
     183             : }
     184             : 
     185             : namespace
     186             : {
     187             :     class DelayedFileDeletion : public ::cppu::WeakImplHelper1< util::XCloseListener >
     188             :     {
     189             :     protected:
     190             :         ::osl::Mutex                    m_aMutex;
     191             :         Reference< util::XCloseable >   m_xDocument;
     192             :         Timer                           m_aDeleteTimer;
     193             :         OUString                        m_sTemporaryFile;
     194             :         sal_Int32                       m_nPendingDeleteAttempts;
     195             : 
     196             :     public:
     197             :         DelayedFileDeletion( const Reference< XModel >& _rxModel,
     198             :                              const OUString& _rTemporaryFile );
     199             : 
     200             :     protected:
     201             :         virtual ~DelayedFileDeletion( );
     202             : 
     203             :         // XCloseListener
     204             :         virtual void SAL_CALL queryClosing( const EventObject& _rSource, sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException, std::exception) SAL_OVERRIDE;
     205             :         virtual void SAL_CALL notifyClosing( const EventObject& _rSource ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     206             : 
     207             :         // XEventListener
     208             :         virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     209             : 
     210             :     private:
     211             :         void implTakeOwnership( );
     212             :         DECL_LINK( OnTryDeleteFile, void* );
     213             : 
     214             :     private:
     215             :         DelayedFileDeletion( const DelayedFileDeletion& );                  // never implemented
     216             :         DelayedFileDeletion& operator=( const DelayedFileDeletion& );       // never implemented
     217             :     };
     218             : 
     219           0 :     DelayedFileDeletion::DelayedFileDeletion( const Reference< XModel >& _rxModel, const OUString& _rTemporaryFile )
     220             :         :
     221             :         m_xDocument( _rxModel, UNO_QUERY )
     222             :         ,m_sTemporaryFile( _rTemporaryFile )
     223           0 :         ,m_nPendingDeleteAttempts( 0 )
     224             :     {
     225           0 :         osl_atomic_increment( &m_refCount );
     226             :         try
     227             :         {
     228           0 :             if ( m_xDocument.is() )
     229             :             {
     230           0 :                 m_xDocument->addCloseListener( this );
     231             :                 // successfully added -> keep ourself alive
     232           0 :                 acquire();
     233             :             }
     234             :             else {
     235             :                 OSL_FAIL("DelayedFileDeletion::DelayedFileDeletion: model is no component!" );
     236             :             }
     237             :         }
     238           0 :         catch (const Exception&)
     239             :         {
     240             :             OSL_FAIL("DelayedFileDeletion::DelayedFileDeletion: could not register as event listener at the model!" );
     241             :         }
     242           0 :         osl_atomic_decrement( &m_refCount );
     243           0 :     }
     244             : 
     245           0 :     IMPL_LINK_NOARG(DelayedFileDeletion, OnTryDeleteFile)
     246             :     {
     247           0 :         ::osl::ClearableMutexGuard aGuard( m_aMutex );
     248             : 
     249           0 :         bool bSuccess = false;
     250             :         try
     251             :         {
     252           0 :             sal_Bool bDeliverOwnership = ( 0 == m_nPendingDeleteAttempts );
     253             :                 // if this is our last attemt, then anybody which vetoes this has to take the consequences
     254             :                 // (means take the ownership)
     255           0 :             m_xDocument->close( bDeliverOwnership );
     256           0 :             bSuccess = true;
     257             :         }
     258           0 :         catch (const util::CloseVetoException&)
     259             :         {
     260             :             // somebody vetoed -> next try
     261           0 :             if ( m_nPendingDeleteAttempts )
     262             :             {
     263             :                 // next attempt
     264           0 :                 --m_nPendingDeleteAttempts;
     265           0 :                 m_aDeleteTimer.Start();
     266             :             }
     267             :             else
     268           0 :                 bSuccess = true;    // can't do anything here ...
     269             :         }
     270           0 :         catch (const Exception&)
     271             :         {
     272             :             OSL_FAIL("DelayedFileDeletion::OnTryDeleteFile: caught a strange exception!" );
     273           0 :             bSuccess = true;
     274             :                 // can't do anything here ...
     275             :         }
     276             : 
     277           0 :         if ( bSuccess )
     278             :         {
     279           0 :             SWUnoHelper::UCB_DeleteFile( m_sTemporaryFile );
     280           0 :             aGuard.clear();
     281           0 :             release();  // this should be our last reference, we should be dead after this
     282             :         }
     283           0 :         return 0L;
     284             :     }
     285             : 
     286           0 :     void DelayedFileDeletion::implTakeOwnership( )
     287             :     {
     288             :         // revoke ourself as listener
     289             :         try
     290             :         {
     291           0 :             m_xDocument->removeCloseListener( this );
     292             :         }
     293           0 :         catch (const Exception&)
     294             :         {
     295             :             OSL_FAIL("DelayedFileDeletion::implTakeOwnership: could not revoke the listener!" );
     296             :         }
     297             : 
     298           0 :         m_aDeleteTimer.SetTimeout( 3000 );  // 3 seconds
     299           0 :         m_aDeleteTimer.SetTimeoutHdl( LINK( this, DelayedFileDeletion, OnTryDeleteFile ) );
     300           0 :         m_nPendingDeleteAttempts = 3;   // try 3 times at most
     301           0 :         m_aDeleteTimer.Start( );
     302           0 :     }
     303             : 
     304           0 :     void SAL_CALL DelayedFileDeletion::queryClosing( const EventObject& , sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException, std::exception)
     305             :     {
     306           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     307           0 :         if ( _bGetsOwnership )
     308           0 :             implTakeOwnership( );
     309             : 
     310             :         // always veto: We want to take the ownership ourself, as this is the only chance to delete
     311             :         // the temporary file which the model is based on
     312           0 :         throw util::CloseVetoException( );
     313             :     }
     314             : 
     315           0 :     void SAL_CALL DelayedFileDeletion::notifyClosing( const EventObject&  ) throw (RuntimeException, std::exception)
     316             :     {
     317             :         OSL_FAIL("DelayedFileDeletion::notifyClosing: how this?" );
     318             :         // this should not happen:
     319             :         // Either, a foreign instance closes the document, then we should veto this, and take the ownership
     320             :         // Or, we ourself close the document, then we should not be a listener anymore
     321           0 :     }
     322             : 
     323           0 :     void SAL_CALL DelayedFileDeletion::disposing( const EventObject&  ) throw (RuntimeException, std::exception)
     324             :     {
     325             :         OSL_FAIL("DelayedFileDeletion::disposing: how this?" );
     326             :         // this should not happen:
     327             :         // Either, a foreign instance closes the document, then we should veto this, and take the ownership
     328             :         // Or, we ourself close the document, then we should not be a listener anymore
     329           0 :     }
     330             : 
     331           0 :     DelayedFileDeletion::~DelayedFileDeletion( )
     332             :     {
     333           0 :     }
     334             : }
     335             : 
     336           0 : static bool DeleteTmpFile_Impl(
     337             :         Reference< frame::XModel > &rxModel,
     338             :         SfxObjectShellRef &rxDocSh,
     339             :         const OUString &rTmpFileURL )
     340             : {
     341           0 :     bool bRes = false;
     342           0 :     if (!rTmpFileURL.isEmpty())
     343             :     {
     344           0 :         bool bDelete = true;
     345           0 :         if ( eVetoed == CloseModelAndDocSh( rxModel, rxDocSh ) )
     346             :         {
     347             :             // somebody vetoed the closing, and took the ownership of the document
     348             :             // -> ensure that the temporary file is deleted later on
     349           0 :             Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) );
     350             :                 // note: as soon as #106931# is fixed, the whole DelayedFileDeletion is to be superseeded by
     351             :                 // a better solution
     352           0 :             bDelete = false;
     353             :         }
     354             : 
     355           0 :         rxModel = 0;
     356           0 :         rxDocSh = 0; // destroy doc shell
     357             : 
     358           0 :         if ( bDelete )
     359             :         {
     360           0 :             if ( !SWUnoHelper::UCB_DeleteFile( rTmpFileURL ) )
     361             :             {
     362           0 :                 Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) );
     363             :                     // same not as above: as soon as #106931#, ...
     364             :             }
     365             :         }
     366             :         else
     367           0 :             bRes = true;    // file will be deleted delayed
     368             :     }
     369           0 :     return bRes;
     370             : }
     371             : 
     372           0 : SwXMailMerge::SwXMailMerge() :
     373           0 :     aEvtListeners   ( GetMailMergeMutex() ),
     374           0 :     aMergeListeners ( GetMailMergeMutex() ),
     375           0 :     aPropListeners  ( GetMailMergeMutex() ),
     376           0 :     pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_MAILMERGE ) ),
     377             :     nDataCommandType(sdb::CommandType::TABLE),
     378             :     nOutputType(MailMergeType::PRINTER),
     379             :     bEscapeProcessing(sal_True),     //!! allow to process properties like "Filter", "Order", ...
     380             :     bSinglePrintJobs(sal_False),
     381             :     bFileNameFromColumn(sal_False),
     382             :     bSendAsHTML(sal_False),
     383             :     bSendAsAttachment(sal_False),
     384             :     bSaveAsSingleFile(sal_False),
     385             :     bDisposing(sal_False),
     386           0 :     m_pMgr(0)
     387             : {
     388             :     // create empty document
     389             :     // like in: SwModule::InsertEnv (appenv.cxx)
     390           0 :     xDocSh = new SwDocShell( SFX_CREATE_MODE_STANDARD );
     391           0 :     xDocSh->DoInitNew( 0 );
     392           0 :     SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 );
     393           0 :     SwView *pView = (SwView*) pFrame->GetViewShell();
     394           0 :     pView->AttrChangedNotify( &pView->GetWrtShell() ); //So that SelectShell is called.
     395           0 :     xModel = xDocSh->GetModel();
     396           0 : }
     397             : 
     398           0 : SwXMailMerge::~SwXMailMerge()
     399             : {
     400           0 :     if (!aTmpFileName.isEmpty())
     401           0 :         DeleteTmpFile_Impl( xModel, xDocSh, aTmpFileName );
     402             :     else    // there was no temporary file in use
     403             :     {
     404             :         //! we still need to close the model and doc shell manually
     405             :         //! because there is no automatism that will do that later.
     406             :         //! #120086#
     407           0 :         if ( eVetoed == CloseModelAndDocSh( xModel, xDocSh ) )
     408             :             OSL_FAIL("owner ship transfered to vetoing object!" );
     409             : 
     410           0 :         xModel = 0;
     411           0 :         xDocSh = 0; // destroy doc shell
     412             :     }
     413           0 : }
     414             : 
     415             : // Guarantee object consistence in case of an exception
     416             : class MailMergeExecuteFinalizer {
     417             : public:
     418           0 :     MailMergeExecuteFinalizer(SwXMailMerge *mailmerge)
     419           0 :         : m_pMailMerge(mailmerge)
     420             :     {
     421             :         assert(m_pMailMerge); //mailmerge object missing
     422           0 :     }
     423           0 :     ~MailMergeExecuteFinalizer()
     424             :     {
     425           0 :         osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
     426           0 :         m_pMailMerge->m_pMgr = 0;
     427           0 :     }
     428             : 
     429             : private:
     430             :     // Disallow copy
     431             :     MailMergeExecuteFinalizer(const MailMergeExecuteFinalizer&) {}
     432             : 
     433             :     SwXMailMerge *m_pMailMerge;
     434             : };
     435             : 
     436           0 : uno::Any SAL_CALL SwXMailMerge::execute(
     437             :         const uno::Sequence< beans::NamedValue >& rArguments )
     438             :     throw (IllegalArgumentException, Exception,
     439             :            RuntimeException, std::exception)
     440             : {
     441           0 :     SolarMutexGuard aGuard;
     442           0 :     MailMergeExecuteFinalizer aFinalizer(this);
     443             : 
     444             :     // get property values to be used
     445             :     // (use values from the service as default and override them with
     446             :     // the values that are provided as arguments)
     447             : 
     448           0 :     uno::Sequence< uno::Any >           aCurSelection   = aSelection;
     449           0 :     uno::Reference< sdbc::XResultSet >  xCurResultSet   = xResultSet;
     450           0 :     uno::Reference< sdbc::XConnection > xCurConnection  = xConnection;
     451           0 :     uno::Reference< frame::XModel >     xCurModel       = xModel;
     452           0 :     OUString   aCurDataSourceName       = aDataSourceName;
     453           0 :     OUString   aCurDataCommand          = aDataCommand;
     454           0 :     OUString   aCurFilter               = aFilter;
     455           0 :     OUString   aCurDocumentURL          = aDocumentURL;
     456           0 :     OUString   aCurOutputURL            = aOutputURL;
     457           0 :     OUString   aCurFileNamePrefix       = aFileNamePrefix;
     458           0 :     sal_Int32  nCurDataCommandType      = nDataCommandType;
     459           0 :     sal_Int16  nCurOutputType           = nOutputType;
     460           0 :     sal_Bool   bCurEscapeProcessing     = bEscapeProcessing;
     461           0 :     sal_Bool   bCurSinglePrintJobs      = bSinglePrintJobs;
     462           0 :     sal_Bool   bCurFileNameFromColumn   = bFileNameFromColumn;
     463             : 
     464           0 :     SfxObjectShellRef xCurDocSh = xDocSh;   // the document
     465             : 
     466           0 :     const beans::NamedValue *pArguments = rArguments.getConstArray();
     467           0 :     sal_Int32 nArgs = rArguments.getLength();
     468           0 :     for (sal_Int32 i = 0;  i < nArgs;  ++i)
     469             :     {
     470           0 :         const OUString &rName   = pArguments[i].Name;
     471           0 :         const Any &rValue       = pArguments[i].Value;
     472             : 
     473           0 :         sal_Bool bOK = sal_True;
     474           0 :         if (rName == UNO_NAME_SELECTION)
     475           0 :             bOK = rValue >>= aCurSelection;
     476           0 :         else if (rName == UNO_NAME_RESULT_SET)
     477           0 :             bOK = rValue >>= xCurResultSet;
     478           0 :         else if (rName == UNO_NAME_CONNECTION)
     479           0 :             bOK = rValue >>= xCurConnection;
     480           0 :         else if (rName == UNO_NAME_MODEL)
     481           0 :             throw PropertyVetoException("Property is read-only: " + rName, static_cast < cppu::OWeakObject * > ( this ) );
     482           0 :         else if (rName == UNO_NAME_DATA_SOURCE_NAME)
     483           0 :             bOK = rValue >>= aCurDataSourceName;
     484           0 :         else if (rName == UNO_NAME_DAD_COMMAND)
     485           0 :             bOK = rValue >>= aCurDataCommand;
     486           0 :         else if (rName == UNO_NAME_FILTER)
     487           0 :             bOK = rValue >>= aCurFilter;
     488           0 :         else if (rName == UNO_NAME_DOCUMENT_URL)
     489             :         {
     490           0 :             bOK = rValue >>= aCurDocumentURL;
     491           0 :             if (!aCurDocumentURL.isEmpty()
     492           0 :                 && !LoadFromURL_impl( xCurModel, xCurDocSh, aCurDocumentURL, false ))
     493           0 :                 throw RuntimeException("Failed to create document from URL: " + aCurDocumentURL, static_cast < cppu::OWeakObject * > ( this ) );
     494             :         }
     495           0 :         else if (rName == UNO_NAME_OUTPUT_URL)
     496             :         {
     497           0 :             bOK = rValue >>= aCurOutputURL;
     498           0 :             if (!aCurOutputURL.isEmpty())
     499             :             {
     500           0 :                 if (!UCB_IsDirectory(aCurOutputURL))
     501           0 :                     throw IllegalArgumentException("URL does not point to a directory: " + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
     502           0 :                 if (UCB_IsReadOnlyFileName(aCurOutputURL))
     503           0 :                     throw IllegalArgumentException("URL is read-only: " + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
     504             :             }
     505             :         }
     506           0 :         else if (rName == UNO_NAME_FILE_NAME_PREFIX)
     507           0 :             bOK = rValue >>= aCurFileNamePrefix;
     508           0 :         else if (rName == UNO_NAME_DAD_COMMAND_TYPE)
     509           0 :             bOK = rValue >>= nCurDataCommandType;
     510           0 :         else if (rName == UNO_NAME_OUTPUT_TYPE)
     511           0 :             bOK = rValue >>= nCurOutputType;
     512           0 :         else if (rName == UNO_NAME_ESCAPE_PROCESSING)
     513           0 :             bOK = rValue >>= bCurEscapeProcessing;
     514           0 :         else if (rName == UNO_NAME_SINGLE_PRINT_JOBS)
     515           0 :             bOK = rValue >>= bCurSinglePrintJobs;
     516           0 :         else if (rName == UNO_NAME_FILE_NAME_FROM_COLUMN)
     517           0 :             bOK = rValue >>= bCurFileNameFromColumn;
     518           0 :         else if (rName == UNO_NAME_SUBJECT)
     519           0 :             bOK = rValue >>= sSubject;
     520           0 :         else if (rName == UNO_NAME_ADDRESS_FROM_COLUMN)
     521           0 :             bOK = rValue >>= sAddressFromColumn;
     522           0 :         else if (rName == UNO_NAME_SEND_AS_HTML)
     523           0 :             bOK = rValue >>= bSendAsHTML;
     524           0 :         else if (rName == UNO_NAME_MAIL_BODY)
     525           0 :             bOK = rValue >>= sMailBody;
     526           0 :         else if (rName == UNO_NAME_ATTACHMENT_NAME)
     527           0 :             bOK = rValue >>= sAttachmentName;
     528           0 :         else if (rName == UNO_NAME_ATTACHMENT_FILTER)
     529           0 :             bOK = rValue >>= sAttachmentFilter;
     530           0 :         else if (rName == UNO_NAME_COPIES_TO)
     531           0 :             bOK = rValue >>= aCopiesTo;
     532           0 :         else if (rName == UNO_NAME_BLIND_COPIES_TO)
     533           0 :             bOK = rValue >>= aBlindCopiesTo;
     534           0 :         else if (rName == UNO_NAME_SEND_AS_ATTACHMENT)
     535           0 :             bOK = rValue >>= bSendAsAttachment;
     536           0 :         else if (rName == UNO_NAME_PRINT_OPTIONS)
     537           0 :             bOK = rValue >>= aPrintSettings;
     538           0 :         else if (rName == UNO_NAME_SAVE_AS_SINGLE_FILE)
     539           0 :             bOK = rValue >>= bSaveAsSingleFile;
     540           0 :         else if (rName == UNO_NAME_SAVE_FILTER)
     541           0 :             bOK = rValue >>= sSaveFilter;
     542           0 :         else if (rName == UNO_NAME_SAVE_FILTER_OPTIONS)
     543           0 :             bOK = rValue >>= sSaveFilterOptions;
     544           0 :         else if (rName == UNO_NAME_SAVE_FILTER_DATA)
     545           0 :             bOK = rValue >>= aSaveFilterData;
     546           0 :         else if (rName == UNO_NAME_IN_SERVER_PASSWORD)
     547           0 :             bOK = rValue >>= sInServerPassword;
     548           0 :         else if (rName == UNO_NAME_OUT_SERVER_PASSWORD)
     549           0 :             bOK = rValue >>= sOutServerPassword;
     550             :         else
     551           0 :             throw UnknownPropertyException( OUString( "Property is unknown: " ) + rName, static_cast < cppu::OWeakObject * > ( this ) );
     552             : 
     553           0 :         if (!bOK)
     554           0 :             throw IllegalArgumentException("Property type mismatch or property not set: " + rName, static_cast < cppu::OWeakObject * > ( this ), 0 );
     555             :     }
     556             : 
     557             :     // need to translate the selection: the API here requires a sequence of bookmarks, but the MergeNew
     558             :     // method we will call below requires a sequence of indicies.
     559           0 :     if ( aCurSelection.getLength() )
     560             :     {
     561           0 :         Sequence< Any > aTranslated( aCurSelection.getLength() );
     562             : 
     563           0 :         bool bValid = false;
     564           0 :         Reference< sdbcx::XRowLocate > xRowLocate( xCurResultSet, UNO_QUERY );
     565           0 :         if ( xRowLocate.is() )
     566             :         {
     567             : 
     568           0 :             const Any* pBookmarks = aCurSelection.getConstArray();
     569           0 :             const Any* pBookmarksEnd = pBookmarks + aCurSelection.getLength();
     570           0 :             Any* pTranslated = aTranslated.getArray();
     571             : 
     572             :             try
     573             :             {
     574           0 :                 bool bEverythingsFine = true;
     575           0 :                 for ( ; ( pBookmarks != pBookmarksEnd ) && bEverythingsFine; ++pBookmarks )
     576             :                 {
     577           0 :                     if ( xRowLocate->moveToBookmark( *pBookmarks ) )
     578           0 :                         *pTranslated <<= xCurResultSet->getRow();
     579             :                     else
     580           0 :                         bEverythingsFine = false;
     581             :                 }
     582           0 :                 if ( bEverythingsFine )
     583           0 :                     bValid = true;
     584             :             }
     585           0 :             catch (const Exception&)
     586             :             {
     587           0 :                 bValid = false;
     588             :             }
     589             :         }
     590             : 
     591           0 :         if ( !bValid )
     592             :         {
     593             :             throw IllegalArgumentException(
     594             :                 OUString( "The current 'Selection' does not describe a valid array of bookmarks, relative to the current 'ResultSet'." ),
     595             :                 static_cast < cppu::OWeakObject * > ( this ),
     596             :                 0
     597           0 :             );
     598             :         }
     599             : 
     600           0 :         aCurSelection = aTranslated;
     601             :     }
     602             : 
     603           0 :     SfxViewFrame*   pFrame = SfxViewFrame::GetFirst( xCurDocSh, false);
     604           0 :     SwView *pView = pFrame ? PTR_CAST( SwView, pFrame->GetViewShell() ) : NULL;
     605           0 :     if (!pView)
     606           0 :         throw RuntimeException();
     607           0 :     SwWrtShell &rSh = *pView->GetWrtShellPtr();
     608             : 
     609             :     // avoid assertion in 'Update' from Sfx by supplying a shell
     610             :     // and thus avoiding the SelectShell call in Writers GetState function
     611             :     // while still in Update of Sfx.
     612             :     // (GetSelection in Update is not allowed)
     613           0 :     if (!aCurDocumentURL.isEmpty())
     614           0 :         pView->AttrChangedNotify( &pView->GetWrtShell() );//So that SelectShell is called.
     615             : 
     616           0 :     SharedComponent aRowSetDisposeHelper;
     617           0 :     if (!xCurResultSet.is())
     618             :     {
     619           0 :         if (aCurDataSourceName.isEmpty() || aCurDataCommand.isEmpty() )
     620             :         {
     621             :             OSL_FAIL("PropertyValues missing or unset");
     622           0 :             throw IllegalArgumentException("Either the ResultSet or DataSourceName and DataCommand must be set.", static_cast < cppu::OWeakObject * > ( this ), 0 );
     623             :         }
     624             : 
     625             :         // build ResultSet from DataSourceName, DataCommand and DataCommandType
     626             : 
     627           0 :         Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
     628           0 :         if (xMgr.is())
     629             :         {
     630           0 :             Reference< XInterface > xInstance = xMgr->createInstance( "com.sun.star.sdb.RowSet" );
     631           0 :             aRowSetDisposeHelper.reset( xInstance, SharedComponent::TakeOwnership );
     632           0 :             Reference< XPropertySet > xRowSetPropSet( xInstance, UNO_QUERY );
     633             :             OSL_ENSURE( xRowSetPropSet.is(), "failed to get XPropertySet interface from RowSet" );
     634           0 :             if (xRowSetPropSet.is())
     635             :             {
     636           0 :                 if (xCurConnection.is())
     637           0 :                     xRowSetPropSet->setPropertyValue( "ActiveConnection",  makeAny( xCurConnection ) );
     638           0 :                 xRowSetPropSet->setPropertyValue( "DataSourceName",    makeAny( aCurDataSourceName ) );
     639           0 :                 xRowSetPropSet->setPropertyValue( "Command",           makeAny( aCurDataCommand ) );
     640           0 :                 xRowSetPropSet->setPropertyValue( "CommandType",       makeAny( nCurDataCommandType ) );
     641           0 :                 xRowSetPropSet->setPropertyValue( "EscapeProcessing",  makeAny( bCurEscapeProcessing ) );
     642           0 :                 xRowSetPropSet->setPropertyValue( "ApplyFilter",       makeAny( sal_True ) );
     643           0 :                 xRowSetPropSet->setPropertyValue( "Filter",            makeAny( aCurFilter ) );
     644             : 
     645           0 :                 Reference< sdbc::XRowSet > xRowSet( xInstance, UNO_QUERY );
     646           0 :                 if (xRowSet.is())
     647           0 :                     xRowSet->execute(); // build ResultSet from properties
     648           0 :                 if( !xCurConnection.is() )
     649           0 :                     xCurConnection.set( xRowSetPropSet->getPropertyValue( "ActiveConnection" ), UNO_QUERY );
     650           0 :                 xCurResultSet = Reference< sdbc::XResultSet >( xRowSet, UNO_QUERY );
     651           0 :                 OSL_ENSURE( xCurResultSet.is(), "failed to build ResultSet" );
     652           0 :             }
     653           0 :         }
     654             :     }
     655             : 
     656           0 :     svx::ODataAccessDescriptor aDescriptor;
     657           0 :     aDescriptor.setDataSource(aCurDataSourceName);
     658           0 :     aDescriptor[ svx::daConnection ]         <<= xCurConnection;
     659           0 :     aDescriptor[ svx::daCommand ]            <<= aCurDataCommand;
     660           0 :     aDescriptor[ svx::daCommandType ]        <<= nCurDataCommandType;
     661           0 :     aDescriptor[ svx::daEscapeProcessing ]   <<= bCurEscapeProcessing;
     662           0 :     aDescriptor[ svx::daCursor ]             <<= xCurResultSet;
     663             :     // aDescriptor[ svx::daColumnName ]      not used
     664             :     // aDescriptor[ svx::daColumnObject ]    not used
     665           0 :     aDescriptor[ svx::daSelection ]          <<= aCurSelection;
     666             : 
     667             :     sal_uInt16 nMergeType;
     668           0 :     switch (nCurOutputType)
     669             :     {
     670           0 :         case MailMergeType::PRINTER : nMergeType = DBMGR_MERGE_MAILMERGE; break;
     671           0 :         case MailMergeType::FILE    : nMergeType = DBMGR_MERGE_MAILFILES; break;
     672           0 :         case MailMergeType::MAIL    : nMergeType = DBMGR_MERGE_MAILING; break;
     673             :         default:
     674           0 :             throw IllegalArgumentException("Invalid value of property: OutputType", static_cast < cppu::OWeakObject * > ( this ), 0 );
     675             :     }
     676             : 
     677           0 :     SwNewDBMgr* pMgr = rSh.GetNewDBMgr();
     678             :     //force layout creation
     679           0 :     rSh.CalcLayout();
     680             :     OSL_ENSURE( pMgr, "database manager missing" );
     681           0 :     m_pMgr = pMgr;
     682             : 
     683           0 :     SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor );
     684             : 
     685           0 :     boost::scoped_ptr< SwMailMergeConfigItem > pMMConfigItem;
     686           0 :     uno::Reference< mail::XMailService > xInService;
     687           0 :     if (MailMergeType::PRINTER == nCurOutputType)
     688             :     {
     689           0 :         IDocumentDeviceAccess* pIDDA = rSh.getIDocumentDeviceAccess();
     690           0 :         SwPrintData aPrtData( pIDDA->getPrintData() );
     691           0 :         aPrtData.SetPrintSingleJobs( bCurSinglePrintJobs );
     692           0 :         pIDDA->setPrintData( aPrtData );
     693             :         // #i25686# printing should not be done asynchronously to prevent dangling offices
     694             :         // when mail merge is called as command line macro
     695           0 :         aMergeDesc.bPrintAsync = sal_False;
     696           0 :         aMergeDesc.aPrintOptions = aPrintSettings;
     697           0 :         aMergeDesc.bCreateSingleFile = true;
     698             :     }
     699             :     else /* FILE and MAIL*/
     700             :     {
     701           0 :         INetURLObject aURLObj;
     702           0 :         aURLObj.SetSmartProtocol( INET_PROT_FILE );
     703             : 
     704           0 :         if (!aCurDocumentURL.isEmpty())
     705             :         {
     706             :             // if OutputURL or FileNamePrefix are missing get
     707             :             // them from DocumentURL
     708           0 :             aURLObj.SetSmartURL( aCurDocumentURL );
     709           0 :             if (aCurFileNamePrefix.isEmpty())
     710           0 :                 aCurFileNamePrefix = aURLObj.GetBase(); // filename without extension
     711           0 :             if (aCurOutputURL.isEmpty())
     712             :             {
     713           0 :                 aURLObj.removeSegment();
     714           0 :                 aCurOutputURL = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
     715             :             }
     716             :         }
     717             :         else    // default empty document without URL
     718             :         {
     719           0 :             if (aCurOutputURL.isEmpty())
     720           0 :                 throw RuntimeException("OutputURL is not set and can not be obtained.", static_cast < cppu::OWeakObject * > ( this ) );
     721             :         }
     722             : 
     723           0 :         aURLObj.SetSmartURL( aCurOutputURL );
     724           0 :         OUString aPath = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
     725             : 
     726           0 :         const OUString aDelim( "/" );
     727           0 :         if (!aPath.isEmpty() && !aPath.endsWith(aDelim))
     728           0 :             aPath += aDelim;
     729           0 :         if (bCurFileNameFromColumn)
     730           0 :             pMgr->SetEMailColumn( aCurFileNamePrefix );
     731             :         else
     732             :         {
     733           0 :             aPath += aCurFileNamePrefix;
     734           0 :             pMgr->SetEMailColumn( OUString() );
     735             :         }
     736           0 :         pMgr->SetSubject( aPath );
     737           0 :         if(MailMergeType::FILE == nCurOutputType)
     738             :         {
     739           0 :             aMergeDesc.sSaveToFilter = sSaveFilter;
     740           0 :             aMergeDesc.sSaveToFilterOptions = sSaveFilterOptions;
     741           0 :             aMergeDesc.aSaveToFilterData = aSaveFilterData;
     742           0 :             aMergeDesc.bCreateSingleFile = bSaveAsSingleFile;
     743             :         }
     744             :         else
     745             :         {
     746           0 :             pMgr->SetEMailColumn( sAddressFromColumn );
     747           0 :             if(sAddressFromColumn.isEmpty())
     748           0 :                 throw RuntimeException("Mail address column not set.", static_cast < cppu::OWeakObject * > ( this ) );
     749           0 :             aMergeDesc.sSaveToFilter     = sAttachmentFilter;
     750           0 :             aMergeDesc.sSubject          = sSubject;
     751           0 :             aMergeDesc.sMailBody         = sMailBody;
     752           0 :             aMergeDesc.sAttachmentName   = sAttachmentName;
     753           0 :             aMergeDesc.aCopiesTo         = aCopiesTo;
     754           0 :             aMergeDesc.aBlindCopiesTo    = aBlindCopiesTo;
     755           0 :             aMergeDesc.bSendAsHTML       = bSendAsHTML;
     756           0 :             aMergeDesc.bSendAsAttachment = bSendAsAttachment;
     757             : 
     758           0 :             aMergeDesc.bCreateSingleFile = sal_False;
     759           0 :             pMMConfigItem.reset(new SwMailMergeConfigItem);
     760           0 :             aMergeDesc.pMailMergeConfigItem = pMMConfigItem.get();
     761           0 :             aMergeDesc.xSmtpServer = SwMailMergeHelper::ConnectToSmtpServer(
     762           0 :                     *pMMConfigItem,
     763             :                     xInService,
     764           0 :                     sInServerPassword, sOutServerPassword );
     765           0 :             if( !aMergeDesc.xSmtpServer.is() || !aMergeDesc.xSmtpServer->isConnected())
     766           0 :                 throw RuntimeException("Failed to connect to mail server.", static_cast < cppu::OWeakObject * > ( this ) );
     767           0 :         }
     768             :     }
     769             : 
     770             :     // save document with temporary filename
     771             :     const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
     772             :             OUString( FILTER_XML ),
     773           0 :             SwDocShell::Factory().GetFilterContainer() );
     774           0 :     OUString aExtension(comphelper::string::stripStart(pSfxFlt->GetDefaultExtension(), '*'));
     775           0 :     utl::TempFile aTempFile( OUString("SwMM"), &aExtension );
     776           0 :     aTmpFileName = aTempFile.GetURL();
     777             : 
     778           0 :     Reference< XStorable > xStorable( xCurModel, UNO_QUERY );
     779           0 :     bool bStoredAsTemporary = false;
     780           0 :     if ( xStorable.is() )
     781             :     {
     782             :         try
     783             :         {
     784           0 :             xStorable->storeAsURL( aTmpFileName, Sequence< PropertyValue >() );
     785           0 :             bStoredAsTemporary = true;
     786             :         }
     787           0 :         catch (const Exception&)
     788             :         {
     789             :         }
     790             :     }
     791           0 :     if ( !bStoredAsTemporary )
     792           0 :         throw RuntimeException("Failed to save temporary file.", static_cast < cppu::OWeakObject * > ( this ) );
     793             : 
     794           0 :     pMgr->SetMergeSilent( sal_True );       // suppress dialogs, message boxes, etc.
     795           0 :     const SwXMailMerge *pOldSrc = pMgr->GetMailMergeEvtSrc();
     796             :     OSL_ENSURE( !pOldSrc || pOldSrc == this, "Ooops... different event source already set." );
     797           0 :     pMgr->SetMailMergeEvtSrc( this );   // launch events for listeners
     798             : 
     799           0 :     SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xCurDocSh));
     800           0 :     sal_Bool bSucc = pMgr->MergeNew( aMergeDesc );
     801           0 :     SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), xCurDocSh));
     802             : 
     803           0 :     pMgr->SetMailMergeEvtSrc( pOldSrc );
     804             : 
     805           0 :     if ( xCurModel.get() != xModel.get() )
     806             :     {   // in case it was a temporary model -> close it, and delete the file
     807           0 :         DeleteTmpFile_Impl( xCurModel, xCurDocSh, aTmpFileName );
     808           0 :         aTmpFileName = "";
     809             :     }
     810             :     // (in case it wasn't a temporary model, it will be closed in the dtor, at the latest)
     811             : 
     812           0 :     if (!bSucc)
     813           0 :         throw Exception("Mail merge failed. Sorry, no further information available.", static_cast < cppu::OWeakObject * > ( this ) );
     814             : 
     815             :     //de-initialize services
     816           0 :     if(xInService.is() && xInService->isConnected())
     817           0 :         xInService->disconnect();
     818           0 :     if(aMergeDesc.xSmtpServer.is() && aMergeDesc.xSmtpServer->isConnected())
     819           0 :         aMergeDesc.xSmtpServer->disconnect();
     820             : 
     821           0 :     return makeAny( sal_True );
     822             : }
     823             : 
     824           0 : void SAL_CALL SwXMailMerge::cancel() throw (com::sun::star::uno::RuntimeException, std::exception)
     825             : {
     826             :     // Cancel may be called from a second thread, so this protects from m_pMgr
     827             :     /// cleanup in the execute function.
     828           0 :     osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
     829           0 :     if (m_pMgr)
     830           0 :         m_pMgr->MergeCancel();
     831           0 : }
     832             : 
     833           0 : void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const
     834             : {
     835           0 :     cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners );
     836           0 :     while (aIt.hasMoreElements())
     837             :     {
     838           0 :         Reference< XMailMergeListener > xRef( aIt.next(), UNO_QUERY );
     839           0 :         if (xRef.is())
     840           0 :             xRef->notifyMailMergeEvent( rEvt );
     841           0 :     }
     842           0 : }
     843             : 
     844           0 : void SwXMailMerge::launchEvent( const PropertyChangeEvent &rEvt ) const
     845             : {
     846             :     cppu::OInterfaceContainerHelper *pContainer =
     847           0 :             aPropListeners.getContainer( rEvt.PropertyHandle );
     848           0 :     if (pContainer)
     849             :     {
     850           0 :         cppu::OInterfaceIteratorHelper aIt( *pContainer );
     851           0 :         while (aIt.hasMoreElements())
     852             :         {
     853           0 :             Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
     854           0 :             if (xRef.is())
     855           0 :                 xRef->propertyChange( rEvt );
     856           0 :         }
     857             :     }
     858           0 : }
     859             : 
     860           0 : uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXMailMerge::getPropertySetInfo(  )
     861             :     throw (RuntimeException, std::exception)
     862             : {
     863           0 :     SolarMutexGuard aGuard;
     864           0 :     static Reference< XPropertySetInfo > aRef = pPropSet->getPropertySetInfo();
     865           0 :     return aRef;
     866             : }
     867             : 
     868           0 : void SAL_CALL SwXMailMerge::setPropertyValue(
     869             :         const OUString& rPropertyName, const uno::Any& rValue )
     870             :     throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
     871             : {
     872           0 :     SolarMutexGuard aGuard;
     873             : 
     874           0 :     const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap().getByName( rPropertyName );
     875           0 :     if (!pCur)
     876           0 :         throw UnknownPropertyException();
     877           0 :     else if (pCur->nFlags & PropertyAttribute::READONLY)
     878           0 :         throw PropertyVetoException();
     879             :     else
     880             :     {
     881           0 :         void *pData = NULL;
     882           0 :         switch (pCur->nWID)
     883             :         {
     884           0 :             case WID_SELECTION :                pData = &aSelection;  break;
     885           0 :             case WID_RESULT_SET :               pData = &xResultSet;  break;
     886           0 :             case WID_CONNECTION :               pData = &xConnection;  break;
     887           0 :             case WID_MODEL :                    pData = &xModel;  break;
     888           0 :             case WID_DATA_SOURCE_NAME :         pData = &aDataSourceName;  break;
     889           0 :             case WID_DATA_COMMAND :             pData = &aDataCommand;  break;
     890           0 :             case WID_FILTER :                   pData = &aFilter;  break;
     891           0 :             case WID_DOCUMENT_URL :             pData = &aDocumentURL;  break;
     892           0 :             case WID_OUTPUT_URL :               pData = &aOutputURL;  break;
     893           0 :             case WID_DATA_COMMAND_TYPE :        pData = &nDataCommandType;  break;
     894           0 :             case WID_OUTPUT_TYPE :              pData = &nOutputType;  break;
     895           0 :             case WID_ESCAPE_PROCESSING :        pData = &bEscapeProcessing;  break;
     896           0 :             case WID_SINGLE_PRINT_JOBS :        pData = &bSinglePrintJobs;  break;
     897           0 :             case WID_FILE_NAME_FROM_COLUMN :    pData = &bFileNameFromColumn;  break;
     898           0 :             case WID_FILE_NAME_PREFIX :         pData = &aFileNamePrefix;  break;
     899           0 :             case WID_MAIL_SUBJECT:              pData = &sSubject; break;
     900           0 :             case WID_ADDRESS_FROM_COLUMN:       pData = &sAddressFromColumn; break;
     901           0 :             case WID_SEND_AS_HTML:              pData = &bSendAsHTML; break;
     902           0 :             case WID_SEND_AS_ATTACHMENT:        pData = &bSendAsAttachment; break;
     903           0 :             case WID_MAIL_BODY:                 pData = &sMailBody; break;
     904           0 :             case WID_ATTACHMENT_NAME:           pData = &sAttachmentName; break;
     905           0 :             case WID_ATTACHMENT_FILTER:         pData = &sAttachmentFilter;break;
     906           0 :             case WID_PRINT_OPTIONS:             pData = &aPrintSettings; break;
     907           0 :             case WID_SAVE_AS_SINGLE_FILE:       pData = &bSaveAsSingleFile; break;
     908           0 :             case WID_SAVE_FILTER:               pData = &sSaveFilter; break;
     909           0 :             case WID_SAVE_FILTER_OPTIONS:       pData = &sSaveFilterOptions; break;
     910           0 :             case WID_SAVE_FILTER_DATA:          pData = &aSaveFilterData; break;
     911           0 :             case WID_COPIES_TO:                 pData = &aCopiesTo; break;
     912           0 :             case WID_BLIND_COPIES_TO:           pData = &aBlindCopiesTo;break;
     913           0 :             case WID_IN_SERVER_PASSWORD:        pData = &sInServerPassword; break;
     914           0 :             case WID_OUT_SERVER_PASSWORD:       pData = &sOutServerPassword; break;
     915             :             default :
     916             :                 OSL_FAIL("unknown WID");
     917             :         }
     918           0 :         Any aOld( pData, pCur->aType );
     919             : 
     920           0 :         bool bChanged = false;
     921           0 :         sal_Bool bOK = sal_True;
     922           0 :         if (aOld != rValue)
     923             :         {
     924           0 :             if (pData == &aSelection)
     925           0 :                 bOK = rValue >>= aSelection;
     926           0 :             else if (pData == &xResultSet)
     927           0 :                 bOK = rValue >>= xResultSet;
     928           0 :             else if (pData == &xConnection)
     929           0 :                 bOK = rValue >>= xConnection;
     930           0 :             else if (pData == &xModel)
     931           0 :                 bOK = rValue >>= xModel;
     932           0 :             else if (pData == &aDataSourceName)
     933           0 :                 bOK = rValue >>= aDataSourceName;
     934           0 :             else if (pData == &aDataCommand)
     935           0 :                 bOK = rValue >>= aDataCommand;
     936           0 :             else if (pData == &aFilter)
     937           0 :                 bOK = rValue >>= aFilter;
     938           0 :             else if (pData == &aDocumentURL)
     939             :             {
     940           0 :                 OUString aText;
     941           0 :                 bOK = rValue >>= aText;
     942           0 :                 if (!aText.isEmpty()
     943           0 :                     && !LoadFromURL_impl( xModel, xDocSh, aText, true ))
     944           0 :                     throw RuntimeException("Failed to create document from URL: " + aText, static_cast < cppu::OWeakObject * > ( this ) );
     945           0 :                 aDocumentURL = aText;
     946             :             }
     947           0 :             else if (pData == &aOutputURL)
     948             :             {
     949           0 :                 OUString aText;
     950           0 :                 bOK = rValue >>= aText;
     951           0 :                 if (!aText.isEmpty())
     952             :                 {
     953           0 :                     if (!UCB_IsDirectory(aText))
     954           0 :                         throw IllegalArgumentException("URL does not point to a directory: " + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
     955           0 :                     if (UCB_IsReadOnlyFileName(aText))
     956           0 :                         throw IllegalArgumentException("URL is read-only: " + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
     957             :                 }
     958           0 :                 aOutputURL = aText;
     959             :             }
     960           0 :             else if (pData == &nDataCommandType)
     961           0 :                 bOK = rValue >>= nDataCommandType;
     962           0 :             else if (pData == &nOutputType)
     963           0 :                 bOK = rValue >>= nOutputType;
     964           0 :             else if (pData == &bEscapeProcessing)
     965           0 :                 bOK = rValue >>= bEscapeProcessing;
     966           0 :             else if (pData == &bSinglePrintJobs)
     967           0 :                 bOK = rValue >>= bSinglePrintJobs;
     968           0 :             else if (pData == &bFileNameFromColumn)
     969           0 :                 bOK = rValue >>= bFileNameFromColumn;
     970           0 :             else if (pData == &aFileNamePrefix)
     971           0 :                 bOK = rValue >>= aFileNamePrefix;
     972           0 :             else if (pData == &sSubject)
     973           0 :                 bOK = rValue >>= sSubject;
     974           0 :             else if (pData == &sAddressFromColumn)
     975           0 :                 bOK = rValue >>= sAddressFromColumn;
     976           0 :             else if (pData == &bSendAsHTML)
     977           0 :                 bOK = rValue >>= bSendAsHTML;
     978           0 :             else if (pData == &bSendAsAttachment)
     979           0 :                 bOK = rValue >>= bSendAsAttachment;
     980           0 :             else if (pData == &sMailBody)
     981           0 :                 bOK = rValue >>= sMailBody;
     982           0 :             else if (pData == &sAttachmentName)
     983           0 :                 bOK = rValue >>= sAttachmentName;
     984           0 :             else if (pData == &sAttachmentFilter)
     985           0 :                 bOK = rValue >>= sAttachmentFilter;
     986           0 :             else if (pData == &aPrintSettings)
     987           0 :                 bOK = rValue >>= aPrintSettings;
     988           0 :             else if (pData == &bSaveAsSingleFile)
     989           0 :                 bOK = rValue >>= bSaveAsSingleFile;
     990           0 :             else if (pData == &sSaveFilter)
     991           0 :                 bOK = rValue >>= sSaveFilter;
     992           0 :             else if (pData == &sSaveFilterOptions)
     993           0 :                 bOK = rValue >>= sSaveFilterOptions;
     994           0 :             else if (pData == &aSaveFilterData)
     995           0 :                 bOK = rValue >>= aSaveFilterData;
     996           0 :             else if (pData == &aCopiesTo)
     997           0 :                 bOK = rValue >>= aCopiesTo;
     998           0 :             else if (pData == &aBlindCopiesTo)
     999           0 :                 bOK = rValue >>= aBlindCopiesTo;
    1000           0 :             else if(pData == &sInServerPassword)
    1001           0 :                 bOK = rValue >>= sInServerPassword;
    1002           0 :             else if(pData == &sOutServerPassword)
    1003           0 :                 bOK = rValue >>= sInServerPassword;
    1004             :             else {
    1005             :                 OSL_FAIL("invalid pointer" );
    1006             :             }
    1007             :             OSL_ENSURE( bOK, "set value failed" );
    1008           0 :             bChanged = true;
    1009             :         }
    1010           0 :         if (!bOK)
    1011           0 :             throw IllegalArgumentException("Property type mismatch or property not set: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ), 0 );
    1012             : 
    1013           0 :         if (bChanged)
    1014             :         {
    1015             :             PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName,
    1016           0 :                     sal_False, pCur->nWID, aOld, rValue );
    1017           0 :             launchEvent( aChgEvt );
    1018           0 :         }
    1019           0 :     }
    1020           0 : }
    1021             : 
    1022           0 : uno::Any SAL_CALL SwXMailMerge::getPropertyValue(
    1023             :         const OUString& rPropertyName )
    1024             :     throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1025             : {
    1026           0 :     SolarMutexGuard aGuard;
    1027             : 
    1028           0 :     Any aRet;
    1029             : 
    1030           0 :     const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap().getByName( rPropertyName );
    1031           0 :     if (!pCur)
    1032           0 :         throw UnknownPropertyException();
    1033             :     else
    1034             :     {
    1035           0 :         switch (pCur->nWID)
    1036             :         {
    1037           0 :             case WID_SELECTION :                aRet <<= aSelection;  break;
    1038           0 :             case WID_RESULT_SET :               aRet <<= xResultSet;  break;
    1039           0 :             case WID_CONNECTION :               aRet <<= xConnection;  break;
    1040           0 :             case WID_MODEL :                    aRet <<= xModel;  break;
    1041           0 :             case WID_DATA_SOURCE_NAME :         aRet <<= aDataSourceName;  break;
    1042           0 :             case WID_DATA_COMMAND :             aRet <<= aDataCommand;  break;
    1043           0 :             case WID_FILTER :                   aRet <<= aFilter;  break;
    1044           0 :             case WID_DOCUMENT_URL :             aRet <<= aDocumentURL;  break;
    1045           0 :             case WID_OUTPUT_URL :               aRet <<= aOutputURL;  break;
    1046           0 :             case WID_DATA_COMMAND_TYPE :        aRet <<= nDataCommandType;  break;
    1047           0 :             case WID_OUTPUT_TYPE :              aRet <<= nOutputType;  break;
    1048           0 :             case WID_ESCAPE_PROCESSING :        aRet <<= bEscapeProcessing;  break;
    1049           0 :             case WID_SINGLE_PRINT_JOBS :        aRet <<= bSinglePrintJobs;  break;
    1050           0 :             case WID_FILE_NAME_FROM_COLUMN :    aRet <<= bFileNameFromColumn;  break;
    1051           0 :             case WID_FILE_NAME_PREFIX :         aRet <<= aFileNamePrefix;  break;
    1052           0 :             case WID_MAIL_SUBJECT:              aRet <<= sSubject; break;
    1053           0 :             case WID_ADDRESS_FROM_COLUMN:       aRet <<= sAddressFromColumn; break;
    1054           0 :             case WID_SEND_AS_HTML:              aRet <<= bSendAsHTML; break;
    1055           0 :             case WID_SEND_AS_ATTACHMENT:        aRet <<= bSendAsAttachment; break;
    1056           0 :             case WID_MAIL_BODY:                 aRet <<= sMailBody; break;
    1057           0 :             case WID_ATTACHMENT_NAME:           aRet <<= sAttachmentName; break;
    1058           0 :             case WID_ATTACHMENT_FILTER:         aRet <<= sAttachmentFilter;break;
    1059           0 :             case WID_PRINT_OPTIONS:             aRet <<= aPrintSettings; break;
    1060           0 :             case WID_SAVE_AS_SINGLE_FILE:       aRet <<= bSaveAsSingleFile; break;
    1061           0 :             case WID_SAVE_FILTER:               aRet <<= sSaveFilter; break;
    1062           0 :             case WID_SAVE_FILTER_OPTIONS:       aRet <<= sSaveFilterOptions; break;
    1063           0 :             case WID_SAVE_FILTER_DATA:          aRet <<= aSaveFilterData; break;
    1064           0 :             case WID_COPIES_TO:                 aRet <<= aCopiesTo; break;
    1065           0 :             case WID_BLIND_COPIES_TO:           aRet <<= aBlindCopiesTo;break;
    1066           0 :             case WID_IN_SERVER_PASSWORD:        aRet <<= sInServerPassword; break;
    1067           0 :             case WID_OUT_SERVER_PASSWORD:       aRet <<= sOutServerPassword; break;
    1068             :             default :
    1069             :                 OSL_FAIL("unknown WID");
    1070             :         }
    1071             :     }
    1072             : 
    1073           0 :     return aRet;
    1074             : }
    1075             : 
    1076           0 : void SAL_CALL SwXMailMerge::addPropertyChangeListener(
    1077             :         const OUString& rPropertyName,
    1078             :         const uno::Reference< beans::XPropertyChangeListener >& rListener )
    1079             :     throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1080             : {
    1081           0 :     SolarMutexGuard aGuard;
    1082           0 :     if (!bDisposing && rListener.is())
    1083             :     {
    1084           0 :         const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap().getByName( rPropertyName );
    1085           0 :         if (pCur)
    1086           0 :             aPropListeners.addInterface( pCur->nWID, rListener );
    1087             :         else
    1088           0 :             throw UnknownPropertyException();
    1089           0 :     }
    1090           0 : }
    1091             : 
    1092           0 : void SAL_CALL SwXMailMerge::removePropertyChangeListener(
    1093             :         const OUString& rPropertyName,
    1094             :         const uno::Reference< beans::XPropertyChangeListener >& rListener )
    1095             :     throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1096             : {
    1097           0 :     SolarMutexGuard aGuard;
    1098           0 :     if (!bDisposing && rListener.is())
    1099             :     {
    1100           0 :         const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap().getByName( rPropertyName );
    1101           0 :         if (pCur)
    1102           0 :             aPropListeners.removeInterface( pCur->nWID, rListener );
    1103             :         else
    1104           0 :             throw UnknownPropertyException();
    1105           0 :     }
    1106           0 : }
    1107             : 
    1108           0 : void SAL_CALL SwXMailMerge::addVetoableChangeListener(
    1109             :         const OUString& /*rPropertyName*/,
    1110             :         const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
    1111             :     throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1112             : {
    1113             :     // no vetoable property, thus no support for vetoable change listeners
    1114             :     OSL_FAIL("not implemented");
    1115           0 : }
    1116             : 
    1117           0 : void SAL_CALL SwXMailMerge::removeVetoableChangeListener(
    1118             :         const OUString& /*rPropertyName*/,
    1119             :         const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
    1120             :     throw (UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
    1121             : {
    1122             :     // no vetoable property, thus no support for vetoable change listeners
    1123             :     OSL_FAIL("not implemented");
    1124           0 : }
    1125             : 
    1126           0 : void SAL_CALL SwXMailMerge::dispose()
    1127             :     throw(RuntimeException, std::exception)
    1128             : {
    1129           0 :     SolarMutexGuard aGuard;
    1130             : 
    1131           0 :     if (!bDisposing)
    1132             :     {
    1133           0 :         bDisposing = sal_True;
    1134             : 
    1135           0 :         EventObject aEvtObj( (XPropertySet *) this );
    1136           0 :         aEvtListeners.disposeAndClear( aEvtObj );
    1137           0 :         aMergeListeners.disposeAndClear( aEvtObj );
    1138           0 :         aPropListeners.disposeAndClear( aEvtObj );
    1139           0 :     }
    1140           0 : }
    1141             : 
    1142           0 : void SAL_CALL SwXMailMerge::addEventListener(
    1143             :         const Reference< XEventListener >& rxListener )
    1144             :     throw(RuntimeException, std::exception)
    1145             : {
    1146           0 :     SolarMutexGuard aGuard;
    1147           0 :     if (!bDisposing && rxListener.is())
    1148           0 :         aEvtListeners.addInterface( rxListener );
    1149           0 : }
    1150             : 
    1151           0 : void SAL_CALL SwXMailMerge::removeEventListener(
    1152             :         const Reference< XEventListener >& rxListener )
    1153             :     throw(RuntimeException, std::exception)
    1154             : {
    1155           0 :     SolarMutexGuard aGuard;
    1156           0 :     if (!bDisposing && rxListener.is())
    1157           0 :         aEvtListeners.removeInterface( rxListener );
    1158           0 : }
    1159             : 
    1160           0 : void SAL_CALL SwXMailMerge::addMailMergeEventListener(
    1161             :         const uno::Reference< XMailMergeListener >& rxListener )
    1162             :     throw (RuntimeException, std::exception)
    1163             : {
    1164           0 :     SolarMutexGuard aGuard;
    1165           0 :     if (!bDisposing && rxListener.is())
    1166           0 :         aMergeListeners.addInterface( rxListener );
    1167           0 : }
    1168             : 
    1169           0 : void SAL_CALL SwXMailMerge::removeMailMergeEventListener(
    1170             :         const uno::Reference< XMailMergeListener >& rxListener )
    1171             :     throw (RuntimeException, std::exception)
    1172             : {
    1173           0 :     SolarMutexGuard aGuard;
    1174           0 :     if (!bDisposing && rxListener.is())
    1175           0 :         aMergeListeners.removeInterface( rxListener );
    1176           0 : }
    1177             : 
    1178           0 : OUString SAL_CALL SwXMailMerge::getImplementationName()
    1179             :     throw(RuntimeException, std::exception)
    1180             : {
    1181           0 :     SolarMutexGuard aGuard;
    1182           0 :     return SwXMailMerge_getImplementationName();
    1183             : }
    1184             : 
    1185           0 : sal_Bool SAL_CALL SwXMailMerge::supportsService( const OUString& rServiceName )
    1186             :     throw(RuntimeException, std::exception)
    1187             : {
    1188           0 :     return cppu::supportsService(this, rServiceName);
    1189             : }
    1190             : 
    1191           0 : uno::Sequence< OUString > SAL_CALL SwXMailMerge::getSupportedServiceNames()
    1192             :     throw(RuntimeException, std::exception)
    1193             : {
    1194           0 :     SolarMutexGuard aGuard;
    1195           0 :     return SwXMailMerge_getSupportedServiceNames();
    1196             : }
    1197             : 
    1198           0 : uno::Sequence< OUString > SAL_CALL SwXMailMerge_getSupportedServiceNames()
    1199             :     throw()
    1200             : {
    1201           0 :     uno::Sequence< OUString > aNames(2);
    1202           0 :     OUString *pName = aNames.getArray();
    1203           0 :     pName[0] = "com.sun.star.text.MailMerge";
    1204           0 :     pName[1] = "com.sun.star.sdb.DataAccessDescriptor";
    1205           0 :     return aNames;
    1206             : }
    1207             : 
    1208          39 : OUString SAL_CALL SwXMailMerge_getImplementationName()
    1209             :     throw()
    1210             : {
    1211          39 :     return OUString( "SwXMailMerge" );
    1212             : }
    1213             : 
    1214           0 : uno::Reference< uno::XInterface > SAL_CALL SwXMailMerge_createInstance(
    1215             :         const uno::Reference< XMultiServiceFactory > & /*rSMgr*/)
    1216             :     throw( uno::Exception )
    1217             : {
    1218           0 :     SolarMutexGuard aGuard;
    1219             : 
    1220             :     //the module may not be loaded
    1221           0 :     SwGlobals::ensure();
    1222           0 :     uno::Reference< uno::XInterface > xRef = (cppu::OWeakObject *) new SwXMailMerge();
    1223           0 :     return xRef;
    1224             : }
    1225             : 
    1226             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10