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

Generated by: LCOV version 1.10