/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif
#include <mmoutputpage.hxx>
#include <mailmergewizard.hxx>
#include <mmconfigitem.hxx>
#include <mailmergechildwindow.hxx>
#include <mailconfigpage.hxx>
#include <cmdid.h>
#include <swtypes.hxx>
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#include <wrtsh.hxx>
#ifndef _DOCSH_HXX
#include <docsh.hxx>
#endif
#ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
#include <IDocumentDeviceAccess.hxx>
#endif
#include <hintids.hxx>
#include <editeng/scripttypeitem.hxx>
#include <editeng/langitem.hxx>
#include <svl/itemset.hxx>
#include <svl/stritem.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/msgbox.hxx>
#include <sfx2/dinfdlg.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
//#ifndef _SFX_DOCFILT_HACK_HXX
//#include <sfx2/docfilt.hxx>
//#endif
#include <tools/urlobj.hxx>
#include <svl/urihelper.hxx>
#ifndef _VCL_PRINT_HXX
#include <vcl/print.hxx>
#endif
#include <unotools/tempfile.hxx>
#include <osl/file.hxx>
#include <mmgreetingspage.hxx>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdb/XColumn.hpp>
//#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
//#include <com/sun/star/beans/PropertyValue.hpp>
//#endif
//#ifndef _BASEDLGS_HXX
//#include <sfx2/basedlgs.hxx>
//#endif
#ifndef _DBMGR_HXX
#include <dbmgr.hxx>
#endif
#include <swunohelper.hxx>
#include <vos/mutex.hxx>
#include <shellio.hxx>
#include <svtools/htmlcfg.hxx>
#include <sfx2/event.hxx>
#include <swevent.hxx>
#include <mmoutputpage.hrc>
#include <dbui.hxx>
#include <dbui.hrc>
#include <helpid.h>
#include <sfx2/app.hxx>
#include <statstr.hrc>
#include <unomid.h>

using namespace svt;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

/*-- 01.07.2004 16:47:49---------------------------------------------------

  -----------------------------------------------------------------------*/
String lcl_GetExtensionForDocType(sal_uLong nDocType)
{
    String sExtension;
    switch( nDocType )
    {
        case MM_DOCTYPE_OOO : sExtension = String::CreateFromAscii( "odt" ); break;
        case MM_DOCTYPE_PDF : sExtension = String::CreateFromAscii( "pdf" ); break;
        case MM_DOCTYPE_WORD: sExtension = String::CreateFromAscii( "doc" ); break;
        case MM_DOCTYPE_HTML: sExtension = String::CreateFromAscii( "html" ); break;
        case MM_DOCTYPE_TEXT: sExtension = String::CreateFromAscii( "txt" ); break;
    }
    return sExtension;
}
/*-- 28.06.2004 11:49:21---------------------------------------------------

  -----------------------------------------------------------------------*/
::rtl::OUString lcl_GetColumnValueOf(const ::rtl::OUString& rColumn, Reference < container::XNameAccess>& rxColAccess )
{
    ::rtl::OUString sRet;
    if(rxColAccess->hasByName(rColumn))
    {
        Any aCol = rxColAccess->getByName(rColumn);
        Reference< sdb::XColumn > xColumn;
        aCol >>= xColumn;
        if(xColumn.is())
            sRet = xColumn->getString();
    }
    return sRet;
}
/*-- 21.06.2004 14:01:13---------------------------------------------------

  -----------------------------------------------------------------------*/
class SwSaveWarningBox_Impl : public ModalDialog
{
    FixedImage      aWarningImageIM;
    FixedInfo       aWarningFI;

    FixedText       aFileNameFT;
    Edit            aFileNameED;

    FixedLine       aSeparatorFL;
    OKButton        aOKPB;
    CancelButton    aCancelPB;

    DECL_LINK( ModifyHdl, Edit*);
public:
    SwSaveWarningBox_Impl(Window* pParent, const String& rFileName);
    ~SwSaveWarningBox_Impl();

    String          GetFileName() const {return aFileNameED.GetText();}
};
/*-- 02.07.2004 08:54:42---------------------------------------------------

  -----------------------------------------------------------------------*/
class SwSendQueryBox_Impl : public ModalDialog
{
    FixedImage      aQueryImageIM;
    FixedInfo       aQueryFI;

    Edit            aTextED;

    FixedLine       aSeparatorFL;
    OKButton        aOKPB;
    CancelButton    aCancelPB;

    bool            bIsEmptyAllowed;
    DECL_LINK( ModifyHdl, Edit*);
public:
    SwSendQueryBox_Impl(Window* pParent, const String& rQueryText);
    ~SwSendQueryBox_Impl();

    void            SetValue(const String& rSet)
                        {
                            aTextED.SetText(rSet);
                            ModifyHdl( &aTextED );
                        }
    String          GetValue() const {return aTextED.GetText();}

    void            SetIsEmptyTextAllowed(bool bSet)
                        {
                            bIsEmptyAllowed = bSet;
                            ModifyHdl( &aTextED );
                        }
};

/*-- 21.06.2004 14:11:58---------------------------------------------------

  -----------------------------------------------------------------------*/
SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(Window* pParent, const String& rFileName) :
    ModalDialog(pParent, SW_RES(   DLG_MM_SAVEWARNING )),
    aWarningImageIM(this,   SW_RES( IM_WARNING   )),
    aWarningFI(this,        SW_RES( FI_WARNING   )),
    aFileNameFT(this,       SW_RES( FT_FILENAME  )),
    aFileNameED(this,       SW_RES( ED_FILENAME  )),
    aSeparatorFL(this,      SW_RES( FL_SEPARATOR )),
    aOKPB(this,             SW_RES( PB_OK        )),
    aCancelPB(this,         SW_RES( PB_CANCEL    ))
{
    FreeResource();
    aWarningImageIM.SetImage(WarningBox::GetStandardImage());
    aFileNameED.SetText(rFileName);
    aFileNameED.SetModifyHdl(LINK(this, SwSaveWarningBox_Impl, ModifyHdl));
    ModifyHdl( &aFileNameED );
}
/*-- 21.06.2004 14:11:58---------------------------------------------------

  -----------------------------------------------------------------------*/
SwSaveWarningBox_Impl::~SwSaveWarningBox_Impl()
{
}
/*-- 21.06.2004 14:11:58---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK( SwSaveWarningBox_Impl, ModifyHdl, Edit*, pEdit)
{
    aOKPB.Enable(pEdit->GetText().Len() > 0);
    return 0;
}
/*-- 02.07.2004 09:02:53---------------------------------------------------

  -----------------------------------------------------------------------*/
SwSendQueryBox_Impl::SwSendQueryBox_Impl(Window* pParent, const String& rText) :
    ModalDialog(pParent, SW_RES(   DLG_MM_QUERY )),
    aQueryImageIM( this,    SW_RES( IM_QUERY     )),
    aQueryFI( this,         SW_RES( FI_QUERY     )),
    aTextED( this,          SW_RES( ED_TEXT      )),
    aSeparatorFL(this,      SW_RES( FL_SEPARATOR )),
    aOKPB(this,             SW_RES( PB_OK        )),
    aCancelPB(this,         SW_RES( PB_CANCEL    )),
    bIsEmptyAllowed(true)
{
    FreeResource();
    aQueryFI.SetText(rText);
    aQueryImageIM.SetImage(QueryBox::GetStandardImage());
    aTextED.SetModifyHdl(LINK(this, SwSendQueryBox_Impl, ModifyHdl));
    ModifyHdl( &aTextED );
}
/*-- 02.07.2004 08:58:45---------------------------------------------------

  -----------------------------------------------------------------------*/
SwSendQueryBox_Impl::~SwSendQueryBox_Impl()
{
}
/*-- 02.07.2004 08:58:25---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, Edit*, pEdit)
{
    aOKPB.Enable(bIsEmptyAllowed  || (pEdit->GetText().Len() > 0));
    return 0;
}

/*-- 16.04.2004 16:34:48---------------------------------------------------

  -----------------------------------------------------------------------*/
class SwCopyToDialog : public SfxModalDialog
{
    FixedInfo       m_aDescriptionFI;
    FixedText       m_aCCFT;
    Edit            m_aCCED;
    FixedText       m_aBCCFT;
    Edit            m_aBCCED;

    FixedInfo       m_aNoteFI;
    FixedLine       m_aSeparatorFL;

    OKButton        m_aOK;
    CancelButton    m_aCancel;
    HelpButton      m_aHelp;

public:
    SwCopyToDialog(Window* pParent);
    ~SwCopyToDialog();

    String          GetCC() {return m_aCCED.GetText();}
    void            SetCC(const String& rSet) {m_aCCED.SetText(rSet);}

    String          GetBCC() {return m_aBCCED.GetText();}
    void            SetBCC(const String& rSet) {m_aBCCED.SetText(rSet);}
};

/*-- 16.04.2004 16:43:18---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCopyToDialog::SwCopyToDialog(Window* pParent) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_COPYTO)),
#ifdef MSC
#pragma warning (disable : 4355)
#endif
    m_aDescriptionFI( this, SW_RES(       FI_DESCRIPTION )),
    m_aCCFT( this, SW_RES(                FT_CC          )),
    m_aCCED( this, SW_RES(                ED_CC          )),
    m_aBCCFT( this, SW_RES(               FT_BCC         )),
    m_aBCCED( this, SW_RES(               ED_BCC         )),
    m_aNoteFI( this, SW_RES(              FI_NOTE        )),
    m_aSeparatorFL( this, SW_RES(         FL_SEPARATOR   )),
    m_aOK( this, SW_RES(                  PB_OK          )),
    m_aCancel( this, SW_RES(              PB_CANCEL      )),
    m_aHelp( this, SW_RES(                PB_HELP        ))
#ifdef MSC
#pragma warning (default : 4355)
#endif
{
    FreeResource();
}
/*-- 16.04.2004 16:43:10---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCopyToDialog::~SwCopyToDialog()
{
}

/*-- 02.04.2004 13:15:54---------------------------------------------------

  -----------------------------------------------------------------------*/
SwMailMergeOutputPage::SwMailMergeOutputPage( SwMailMergeWizard* _pParent) :
    svt::OWizardPage( _pParent, SW_RES(DLG_MM_OUTPUT_PAGE)),
#ifdef MSC
#pragma warning (disable : 4355)
#endif
    m_aHeaderFI(this,           SW_RES(  FI_HEADER           ) ),
    m_aOptionsFI(this,          SW_RES(  FI_OPTIONS          ) ),
    m_aSaveStartDocRB(this,     SW_RES(  RB_SAVESTARTDOC     ) ),
    m_aSaveMergedDocRB(this,    SW_RES(  RB_SAVEMERGEDDOC    ) ),
    m_aPrintRB(this,            SW_RES(  RB_PRINT            ) ),
    m_aSendMailRB(this,         SW_RES(  RB_SENDMAIL         ) ),

    m_aSeparatorFL(this,        SW_RES(  FL_SEPARATOR        ) ),

    m_aSaveStartDocPB(this,     SW_RES(  PB_SAVESTARTDOC     ) ),

    m_aSaveAsOneRB(this,        SW_RES(  RB_SAVEASONE        ) ),
    m_aSaveIndividualRB(this,   SW_RES(  RB_SAVEINDIVIDUAL   ) ),
    m_aPrintAllRB(this,         SW_RES(  RB_PRINTALL         ) ),
    m_aSendAllRB( this, SW_RES(       RB_SENDALL             ) ),

    m_aFromRB(this,             SW_RES(  RB_FROM             ) ),
    m_aFromNF(this,             SW_RES(  NF_FROM             ) ),
    m_aToFT(this,               SW_RES(  FT_TO               ) ),
    m_aToNF(this,               SW_RES(  NF_TO               ) ),
    m_aSaveNowPB(this,          SW_RES(  PB_SAVENOW          ) ),

    m_aPrinterFT(this,          SW_RES(  FT_PRINT            ) ),
    m_aPrinterLB(this,          SW_RES(  LB_PRINT            ) ),
    m_aPrinterSettingsPB(this,  SW_RES(  PB_PRINTERSETTINGS  ) ),
    m_aPrintNowPB(this,         SW_RES(  PB_PRINTNOW         ) ),

    m_aMailToFT( this, SW_RES(        FT_MAILTO              ) ),
    m_aMailToLB( this, SW_RES(        LB_MAILTO              ) ),
    m_aCopyToPB( this, SW_RES(        PB_COPYTO              ) ),
    m_aSubjectFT( this, SW_RES(       FT_SUBJECT             ) ),
    m_aSubjectED( this, SW_RES(       ED_SUBJECT             ) ),
    m_aSendAsFT( this, SW_RES(        FT_SENDAS              ) ),
    m_aSendAsLB( this, SW_RES(        LB_SENDAS              ) ),
    m_aAttachmentFT( this, SW_RES(    FT_ATTACHMENT              ) ),
    m_aAttachmentED( this, SW_RES(    ED_ATTACHMENT              ) ),
    m_aSendAsPB( this, SW_RES(        PB_SENDAS              ) ),
    m_aSendDocumentsPB( this, SW_RES( PB_SENDDOCUMENTS       ) ),

    m_sSaveStartST(SW_RES(           ST_SAVESTART  ) ),
    m_sSaveMergedST(SW_RES(          ST_SAVEMERGED ) ),
    m_sPrintST(SW_RES(               ST_PRINT      ) ),
    m_sSendMailST(SW_RES(            ST_SENDMAIL   ) ),

    m_sDefaultAttachmentST(SW_RES(   ST_DEFAULTATTACHMENT )),
    m_sNoSubjectQueryST(SW_RES(      ST_SUBJECTQUERY      )),
    m_sNoSubjectST(SW_RES(           ST_NOSUBJECT )),
    m_sNoAttachmentNameST(SW_RES(    ST_NOATTACHMENTNAME )),
    m_sConfigureMail(SW_RES(         ST_CONFIGUREMAIL)),
#ifdef MSC
#pragma warning (default : 4355)
#endif
    m_bCancelSaving( false ),
    m_pWizard(_pParent),
    m_pTempPrinter( 0 ),
    m_pDocumentPrinterCopy(0)
{
    FreeResource();

    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
    // #i51949# hide e-Mail option if e-Mail is not supported
    if(!rConfigItem.IsMailAvailable())
        m_aSendMailRB.Hide();

    Link aLink = LINK(this, SwMailMergeOutputPage, OutputTypeHdl_Impl);
    m_aSaveStartDocRB.SetClickHdl(aLink);
    m_aSaveMergedDocRB.SetClickHdl(aLink);
    m_aPrintRB.SetClickHdl(aLink);
    m_aSendMailRB.SetClickHdl(aLink);
    m_aSaveStartDocRB.Check();
    m_aPrintAllRB.Check();
    m_aSaveAsOneRB.Check();
    m_aSendAllRB.Check();

    m_aSaveStartDocPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, SaveStartHdl_Impl));
    m_aSaveNowPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, SaveOutputHdl_Impl));
    m_aPrinterLB.SetSelectHdl(LINK(this, SwMailMergeOutputPage, PrinterChangeHdl_Impl));
    m_aPrintNowPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, PrintHdl_Impl));
    m_aPrinterSettingsPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, PrinterSetupHdl_Impl));

    m_aSendAsPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, SendAsHdl_Impl)),
    m_aSendDocumentsPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, SendDocumentsHdl_Impl)),
    m_aSendAsLB.SetSelectHdl(LINK(this, SwMailMergeOutputPage, SendTypeHdl_Impl));

    m_nFromToRBPos = m_aFromRB.GetPosPixel().Y();
    m_nFromToFTPos = m_aToFT.GetPosPixel().Y();
    m_nFromToNFPos = m_aFromNF.GetPosPixel().Y();

    m_nRBOffset = m_nFromToRBPos - m_aSaveIndividualRB.GetPosPixel().Y();

    OutputTypeHdl_Impl(&m_aSaveStartDocRB);

    m_aCopyToPB.SetClickHdl(LINK(this, SwMailMergeOutputPage, CopyToHdl_Impl));

    m_aSaveAsOneRB.SetClickHdl(LINK(this, SwMailMergeOutputPage, DocumentSelectionHdl_Impl));
    m_aSaveIndividualRB.SetClickHdl(LINK(this, SwMailMergeOutputPage, DocumentSelectionHdl_Impl));
    m_aPrintAllRB.SetClickHdl(LINK(this, SwMailMergeOutputPage, DocumentSelectionHdl_Impl));
    m_aSendAllRB.SetClickHdl(LINK(this, SwMailMergeOutputPage, DocumentSelectionHdl_Impl));

    m_aFromRB.SetClickHdl(LINK(this, SwMailMergeOutputPage, DocumentSelectionHdl_Impl));
    //#i63267# printing might be disabled
    m_aPrintRB.Enable(!Application::GetSettings().GetMiscSettings().GetDisablePrinting());
}

/*-- 02.04.2004 13:15:44---------------------------------------------------

  -----------------------------------------------------------------------*/
SwMailMergeOutputPage::~SwMailMergeOutputPage()
{
    delete m_pTempPrinter;
    delete m_pDocumentPrinterCopy;
}
/*-- 31.01.2005 08:38:14---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwMailMergeOutputPage::ActivatePage()
{
    //fill printer ListBox
    const std::vector<rtl::OUString>& rPrinters = Printer::GetPrinterQueues();
    unsigned int nCount = rPrinters.size();
    if ( nCount )
    {
        for( unsigned int i = 0; i < nCount; i++ )
        {
            m_aPrinterLB.InsertEntry( rPrinters[i] );
        }

    }
    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();

    SwView* pTargetView = rConfigItem.GetTargetView();
    DBG_ASSERT(pTargetView, "no target view exists");
    if(pTargetView)
    {
        SfxPrinter* pPrinter = pTargetView->GetWrtShell().getIDocumentDeviceAccess()->getPrinter( true );
        m_aPrinterLB.SelectEntry( pPrinter->GetName() );
        m_aToNF.SetValue( rConfigItem.GetMergedDocumentCount() );
        m_aToNF.SetMax( rConfigItem.GetMergedDocumentCount() );
        m_pDocumentPrinterCopy = pTargetView->GetWrtShell().getIDocumentDeviceAccess()->getPrinter( true )->Clone();
    }
    m_aPrinterLB.SelectEntry( rConfigItem.GetSelectedPrinter() );

    SwView* pSourceView = rConfigItem.GetSourceView();
    DBG_ASSERT(pSourceView, "no source view exists");
    if(pSourceView)
    {
        SwDocShell* pDocShell = pSourceView->GetDocShell();
        if ( pDocShell->HasName() )
        {
            INetURLObject aTmp( pDocShell->GetMedium()->GetName() );
            m_aAttachmentED.SetText(aTmp.getName(
                    INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ));
        }
    }
}
/*-- 05.07.2004 13:54:11---------------------------------------------------

  -----------------------------------------------------------------------*/
bool SwMailMergeOutputPage::canAdvance() const
{
    return false;
}
/*-- 02.04.2004 13:15:44---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, OutputTypeHdl_Impl, RadioButton*, pButton)
{
    Control* aControls[] =
    {
        &m_aSaveStartDocPB,
        &m_aSaveAsOneRB, &m_aSaveIndividualRB,
        &m_aFromRB, &m_aFromNF, &m_aToFT, &m_aToNF,
        &m_aSaveNowPB,
        &m_aPrinterFT, &m_aPrinterLB, &m_aPrinterSettingsPB, &m_aPrintAllRB,
        &m_aPrintNowPB,
        &m_aMailToFT, &m_aMailToLB, &m_aCopyToPB,
        &m_aSubjectFT, &m_aSubjectED,
        &m_aSendAsFT, &m_aSendAsLB, &m_aSendAsPB,
        &m_aAttachmentFT, &m_aAttachmentED,
        &m_aSendAllRB, &m_aSendDocumentsPB,
        0
    };
    SetUpdateMode(sal_True);
    Control** pControl = aControls;
    do
    {
        (*pControl)->Show(sal_False);

    } while(*(++pControl));

    if(&m_aSaveStartDocRB == pButton)
    {
        m_aSaveStartDocPB.Show();
        m_aSeparatorFL.SetText(m_sSaveStartST);

    }
    else if(&m_aSaveMergedDocRB == pButton)
    {
        Control* aSaveMergedControls[] =
        {
            &m_aSaveAsOneRB, &m_aSaveIndividualRB,
            &m_aFromRB, &m_aFromNF, &m_aToFT, &m_aToNF,
            &m_aSaveNowPB,
            0
        };
        Control** pSaveMergeControl = aSaveMergedControls;
        do
        {
            (*pSaveMergeControl)->Show(sal_True);

        } while(*(++pSaveMergeControl));
        if(!m_aFromRB.IsChecked() && !m_aSaveAsOneRB.IsChecked())
        {
            m_aSaveIndividualRB.Check();
        }
        m_aSeparatorFL.SetText(m_sSaveMergedST);
        //reposition the from/to line
        if(m_aFromRB.GetPosPixel().Y() != m_nFromToRBPos)
        {
            Point aPos(m_aFromRB.GetPosPixel()); aPos.Y() = m_nFromToRBPos; m_aFromRB.SetPosPixel(aPos);
            aPos =   m_aToFT.GetPosPixel();      aPos.Y() = m_nFromToFTPos; m_aToFT.SetPosPixel(aPos);
            aPos =   m_aFromNF.GetPosPixel();    aPos.Y() = m_nFromToNFPos; m_aFromNF.SetPosPixel(aPos);
            aPos =   m_aToNF.GetPosPixel();      aPos.Y() = m_nFromToNFPos; m_aToNF.SetPosPixel(aPos);
        }
    }
    else if(&m_aPrintRB == pButton)
    {
        Control* aPrintControls[] =
        {
            &m_aFromRB, &m_aFromNF, &m_aToFT, &m_aToNF,
            &m_aPrinterFT, &m_aPrinterLB, &m_aPrinterSettingsPB, &m_aPrintAllRB,
            &m_aPrintNowPB,
            0
        };
        Control** pPrinterControl = aPrintControls;
        do
        {
            (*pPrinterControl)->Show(sal_True);

        } while(*(++pPrinterControl));
        if(!m_aFromRB.IsChecked())
            m_aPrintAllRB.Check();

        m_aSeparatorFL.SetText(m_sPrintST);
        //reposition the from/to line
        long nRB_FT_Offset = m_nFromToRBPos - m_nFromToFTPos;
        long nNewRBXPos = m_aPrintAllRB.GetPosPixel().Y() + m_nRBOffset;

        Point aPos(m_aFromRB.GetPosPixel());aPos.Y() = nNewRBXPos;                 m_aFromRB.SetPosPixel(aPos);
        aPos = m_aToFT.GetPosPixel();       aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aToFT.SetPosPixel(aPos);
        aPos = m_aFromNF.GetPosPixel();     aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aFromNF.SetPosPixel(aPos);
        aPos = m_aToNF.GetPosPixel();       aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aToNF.SetPosPixel(aPos);
    }
    else /*if(&m_aSendMailRB == pButton)*/
    {
        Control* aMailControls[] =
        {
            &m_aFromRB, &m_aFromNF, &m_aToFT, &m_aToNF,
            &m_aMailToFT, &m_aMailToLB, &m_aCopyToPB,
            &m_aSubjectFT, &m_aSubjectED,
            &m_aSendAsFT, &m_aSendAsLB, &m_aSendAsPB,
            &m_aAttachmentFT, &m_aAttachmentED,
            &m_aSendAllRB, &m_aSendDocumentsPB, 0
        };
        Control** pMailControl = aMailControls;
        do
        {
            (*pMailControl)->Show(sal_True);

        } while(*(++pMailControl));

        if(!m_aFromRB.IsChecked())
            m_aSendAllRB.Check();
        if(!m_aAttachmentED.GetText().Len())
        {
            String sAttach( m_sDefaultAttachmentST );
            sAttach += '.';
            sAttach += lcl_GetExtensionForDocType(
                        (sal_uLong)m_aSendAsLB.GetEntryData(m_aSendAsLB.GetSelectEntryPos()));
            m_aAttachmentED.SetText( sAttach );

        }
        m_aSeparatorFL.SetText(m_sSendMailST);
        //fill mail address ListBox
        if(!m_aMailToLB.GetEntryCount())
        {
            SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
            //select first column
            uno::Reference< sdbcx::XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), uno::UNO_QUERY);
            //get the name of the actual columns
            uno::Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
            uno::Sequence< ::rtl::OUString > aFields;
            if(xColAccess.is())
                aFields = xColAccess->getElementNames();
            const ::rtl::OUString* pFields = aFields.getConstArray();
            for(sal_Int32 nField = 0; nField < aFields.getLength(); ++nField)
                m_aMailToLB.InsertEntry(pFields[nField]);

            m_aMailToLB.SelectEntryPos(0);
            // then select the right one - may not be available
            const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
            String sEMailColumn = rHeaders.GetString( MM_PART_E_MAIL );
            Sequence< ::rtl::OUString> aAssignment =
                            rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
            if(aAssignment.getLength() > MM_PART_E_MAIL && aAssignment[MM_PART_E_MAIL].getLength())
                sEMailColumn = aAssignment[MM_PART_E_MAIL];
            m_aMailToLB.SelectEntry(sEMailColumn);
            // HTML format pre-selected
            m_aSendAsLB.SelectEntryPos(3);
            SendTypeHdl_Impl(&m_aSendAsLB);
        }
        if(m_aSendAllRB.GetPosPixel().Y() + m_nRBOffset != m_aFromRB.GetPosPixel().Y())
        {
            long nRB_FT_Offset = m_nFromToRBPos - m_nFromToFTPos;
            long nNewRBXPos = m_aSendAllRB.GetPosPixel().Y() + m_nRBOffset;

            Point aPos(m_aFromRB.GetPosPixel());aPos.Y() = nNewRBXPos;                 m_aFromRB.SetPosPixel(aPos);
            aPos = m_aToFT.GetPosPixel();       aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aToFT.SetPosPixel(aPos);
            aPos = m_aFromNF.GetPosPixel();     aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aFromNF.SetPosPixel(aPos);
            aPos = m_aToNF.GetPosPixel();       aPos.Y() = nNewRBXPos + nRB_FT_Offset; m_aToNF.SetPosPixel(aPos);
        }
    }
    m_aFromRB.GetClickHdl().Call(m_aFromRB.IsChecked() ? &m_aFromRB : 0);

    SetUpdateMode(sal_False);
    return 0;
}
/*-- 22.08.2005 12:15:10---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, DocumentSelectionHdl_Impl, RadioButton*, pButton)
{
    sal_Bool bEnableFromTo = pButton == &m_aFromRB;
    m_aFromNF.Enable(bEnableFromTo);
    m_aToFT.Enable(bEnableFromTo);
    m_aToNF.Enable(bEnableFromTo);
    return 0;
}

/*-- 16.04.2004 16:45:10---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, CopyToHdl_Impl, PushButton*, pButton)
{
    SwCopyToDialog* pDlg = new SwCopyToDialog(pButton);
    pDlg->SetCC(m_sCC );
    pDlg->SetBCC(m_sBCC);
    if(RET_OK == pDlg->Execute())
    {
        m_sCC =     pDlg->GetCC() ;
        m_sBCC =    pDlg->GetBCC();
    }
    delete pDlg;
    return 0;
}
/*-- 17.05.2004 13:51:02---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SaveStartHdl_Impl, PushButton*, pButton)
{
    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
    SwView* pSourceView = rConfigItem.GetSourceView();
    DBG_ASSERT( pSourceView, "source view missing");
    if(pSourceView)
    {
        SfxViewFrame* pSourceViewFrm = pSourceView->GetViewFrame();
        uno::Reference< frame::XFrame > xFrame =
                pSourceViewFrm->GetFrame().GetFrameInterface();
        xFrame->getContainerWindow()->setVisible(sal_True);
        pSourceViewFrm->GetDispatcher()->Execute(SID_SAVEDOC, SFX_CALLMODE_SYNCHRON);
        xFrame->getContainerWindow()->setVisible(sal_False);
        SwDocShell* pDocShell = pSourceView->GetDocShell();
        //if the document has been saved it's URL has to be stored for
        // later use and it can be closed now
        if(pDocShell->HasName() && !pDocShell->IsModified())
        {
            INetURLObject aURL = pDocShell->GetMedium()->GetURLObject();
            //update the attachment name
            if(!m_aAttachmentED.GetText().Len())
            {
                if ( pDocShell->HasName() )
                {
                    m_aAttachmentED.SetText(aURL.getName(
                            INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ));
                }
            }

            rConfigItem.AddSavedDocument(
                    aURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
            pButton->Enable(sal_False);
            m_pWizard->enableButtons(WZB_FINISH, sal_True);
            pButton->Enable(sal_False);

        }
    }
    return 0;
}
/*-- 17.07.2008 08:09:06---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SaveCancelHdl_Impl, Button*, EMPTYARG )
{
    m_bCancelSaving = true;
    return 0;
}
/*-- 17.05.2004 13:51:02---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SaveOutputHdl_Impl, PushButton*, pButton)
{
    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
    SwView* pTargetView = rConfigItem.GetTargetView();
    DBG_ASSERT(pTargetView, "no target view exists");
    if(!pTargetView)
        return 0;

    if(m_aSaveAsOneRB.IsChecked())
    {
        String sFilter;
        String sPath = SwMailMergeHelper::CallSaveAsDialog(sFilter);
        if(!sPath.Len())
            return 0;
        uno::Sequence< beans::PropertyValue > aValues(1);
        beans::PropertyValue* pValues = aValues.getArray();
        pValues[0].Name = C2U("FilterName");
        pValues[0].Value <<= ::rtl::OUString(sFilter);

        uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
        sal_uInt32 nErrorCode = ERRCODE_NONE;
        try
        {
            xStore->storeToURL( sPath, aValues );
        }
        catch( task::ErrorCodeIOException& aErrorEx )
        {
            nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
        }
        catch( Exception& )
        {
            nErrorCode = ERRCODE_IO_GENERAL;
        }
        if( nErrorCode != ERRCODE_NONE )
        {
            SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle());
            ErrorHandler::HandleError( nErrorCode );
        }
    }
    else
    {
        sal_uInt32 nBegin = 0;
        sal_uInt32 nEnd = 0;
        if(m_aSaveIndividualRB.IsChecked())
        {
            nBegin = 0;
            nEnd = rConfigItem.GetMergedDocumentCount();
        }
        else
        {
            nBegin  = static_cast< sal_Int32 >(m_aFromNF.GetValue() - 1);
            nEnd    = static_cast< sal_Int32 >(m_aToNF.GetValue());
            if(nEnd > rConfigItem.GetMergedDocumentCount())
                nEnd = rConfigItem.GetMergedDocumentCount();
        }
        String sFilter;
        String sPath = SwMailMergeHelper::CallSaveAsDialog(sFilter);
        if(!sPath.Len())
            return 0;
        String sTargetTempURL = URIHelper::SmartRel2Abs(
            INetURLObject(), utl::TempFile::CreateTempName(),
            URIHelper::GetMaybeFileHdl());
        const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
                String::CreateFromAscii( FILTER_XML ),
                SwDocShell::Factory().GetFilterContainer() );

        uno::Sequence< beans::PropertyValue > aValues(1);
        beans::PropertyValue* pValues = aValues.getArray();
        pValues[0].Name = C2U("FilterName");
        pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName());

        uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
        sal_uInt32 nErrorCode = ERRCODE_NONE;
        try
        {
            xStore->storeToURL( sTargetTempURL, aValues );
        }
        catch( task::ErrorCodeIOException& aErrorEx )
        {
            nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
        }
        catch( Exception& )
        {
            nErrorCode = ERRCODE_IO_GENERAL;
        }
        if( nErrorCode != ERRCODE_NONE )
        {
            SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle());
            ErrorHandler::HandleError( nErrorCode );
        }

        SwView* pSourceView = rConfigItem.GetSourceView();
        PrintMonitor aSaveMonitor(this, PrintMonitor::MONITOR_TYPE_SAVE);
        aSaveMonitor.aDocName.SetText(pSourceView->GetDocShell()->GetTitle(22));
        aSaveMonitor.aCancel.SetClickHdl(LINK(this, SwMailMergeOutputPage, SaveCancelHdl_Impl));
        aSaveMonitor.aPrinter.SetText( INetURLObject( sPath ).getFSysPath( INetURLObject::FSYS_DETECT ) );
	    aSaveMonitor.ResizeControls();

        m_bCancelSaving = false;
        aSaveMonitor.Show();
        m_pWizard->enableButtons(WZB_CANCEL, sal_False);

        for(sal_uInt32 nDoc = nBegin; nDoc < nEnd && !m_bCancelSaving; ++nDoc)
        {
            SwDocMergeInfo& rInfo = rConfigItem.GetDocumentMergeInfo(nDoc);
            INetURLObject aURL(sPath);
            String sFile = aURL.GetBase();
            String sExtension = aURL.getExtension();
            if(!sExtension.Len())
            {
                sExtension = pSfxFlt->GetWildcard()().GetToken(1, '.');
                sPath += '.';
                sPath += sExtension;
            }
            String sStat(SW_RES(STR_STATSTR_LETTER));
            sStat += ' ';
            sStat += String::CreateFromInt32( nDoc );
            aSaveMonitor.aPrintInfo.SetText(sStat);

            //now extract a document from the target document
            // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
            SfxObjectShellLock xTempDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
            xTempDocShell->DoInitNew( 0 );
            SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, 0 );
//            pTempFrame->GetFrame().Appear();
            SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
            pTargetView->GetWrtShell().StartAction();
            SwgReaderOption aOpt;
            aOpt.SetTxtFmts( sal_True );
            aOpt.SetFrmFmts( sal_True );
            aOpt.SetPageDescs( sal_True );
            aOpt.SetNumRules( sal_True );
            aOpt.SetMerge( sal_False );
            pTempView->GetDocShell()->LoadStylesFromFile(
                    sTargetTempURL, aOpt, sal_True );

            pTargetView->GetWrtShell().PastePages(pTempView->GetWrtShell(),
                    (sal_uInt16)rInfo.nStartPageInTarget, (sal_uInt16)rInfo.nEndPageInTarget );
            pTargetView->GetWrtShell().EndAction();
            //then save it
            String sOutPath = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
            String sCounter('_');
            sCounter += String::CreateFromInt32(nDoc);
            sOutPath.Insert(sCounter, sOutPath.Len() - sExtension.Len() - 1);
            //SfxStringItem aName(SID_FILE_NAME, sOutPath);
            //SfxStringItem aFilter(SID_FILTER_NAME, sFilter);

            while(true)
            {
                //time for other slots is needed
                for(sal_Int16 r = 0; r < 10; ++r)
                    Application::Reschedule();
                bool bFailed = false;
                try
                {
                    pValues[0].Value <<= ::rtl::OUString(sFilter);
                    uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY);
                    xTempStore->storeToURL( sOutPath, aValues   );
                }
                catch( const uno::Exception& )
                {
                    bFailed = true;
                }

                if(bFailed)
                {
                    SwSaveWarningBox_Impl aWarning( pButton, sOutPath );
                    if(RET_OK == aWarning.Execute())
                        sOutPath = aWarning.GetFileName();
                    else
                    {
                        xTempDocShell->DoClose();
                        return 0;
                    }
                }
                else
                {
                    xTempDocShell->DoClose();
                    break;
                }
            }
        }
        ::osl::File::remove( sTargetTempURL );
    }
    m_pWizard->enableButtons(WZB_CANCEL, sal_True);
    m_pWizard->enableButtons(WZB_FINISH, sal_True);
    return 0;
}
/*-- 22.06.2004 11:51:30---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, PrinterChangeHdl_Impl, ListBox*, pBox)
{
    if( m_pDocumentPrinterCopy && pBox->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
    {
        const QueueInfo* pInfo = Printer::GetQueueInfo( pBox->GetSelectEntry(), false );

        if( pInfo )
        {
            if ( !m_pTempPrinter )
            {
                if( (m_pDocumentPrinterCopy->GetName() == pInfo->GetPrinterName()) &&
                     (m_pDocumentPrinterCopy->GetDriverName() == pInfo->GetDriver()) )
                    m_pTempPrinter = new Printer( m_pDocumentPrinterCopy->GetJobSetup() );
                else
                    m_pTempPrinter = new Printer( *pInfo );
            }
            else
            {
                if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
                     (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
                {
                    delete m_pTempPrinter;
                    m_pTempPrinter = new Printer( *pInfo );
                }
            }
        }
        else if( ! m_pTempPrinter )
            m_pTempPrinter = new Printer();

        m_aPrinterSettingsPB.Enable( m_pTempPrinter->HasSupport( SUPPORT_SETUPDIALOG ) );
    }
    else
        m_aPrinterSettingsPB.Disable();
    m_pWizard->GetConfigItem().SetSelectedPrinter( pBox->GetSelectEntry() );

//    return m_pTempPrinter;
    return 0;
}

/*-- 17.05.2004 13:51:02---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, PrintHdl_Impl, PushButton*, EMPTYARG)
{
    SwView* pTargetView = m_pWizard->GetConfigItem().GetTargetView();
    DBG_ASSERT(pTargetView, "no target view exists");
    if(!pTargetView)
        return 0;

    sal_uInt32 nBegin = 0;
    sal_uInt32 nEnd = 0;
    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
    if(m_aPrintAllRB.IsChecked())
    {
        nBegin = 0;
        nEnd = rConfigItem.GetMergedDocumentCount();
    }
    else
    {
        nBegin  = static_cast< sal_Int32 >(m_aFromNF.GetValue() - 1);
        nEnd    = static_cast< sal_Int32 >(m_aToNF.GetValue());
        if(nEnd > rConfigItem.GetMergedDocumentCount())
            nEnd = rConfigItem.GetMergedDocumentCount();
    }
    rConfigItem.SetPrintRange( (sal_uInt16)nBegin, (sal_uInt16)nEnd );
    SwDocMergeInfo& rStartInfo = rConfigItem.GetDocumentMergeInfo(nBegin);
    SwDocMergeInfo& rEndInfo = rConfigItem.GetDocumentMergeInfo(nEnd - 1);

    rtl::OUString sPages(rtl::OUString::valueOf( rStartInfo.nStartPageInTarget ));
    sPages += rtl::OUString::createFromAscii( " - ");
    sPages += rtl::OUString::valueOf(  rEndInfo.nEndPageInTarget );

    SwWrtShell& rSh = pTargetView->GetWrtShell();
    pTargetView->SetMailMergeConfigItem(&rConfigItem, 0, sal_False);
    if(m_pTempPrinter)
    {
        m_pDocumentPrinterCopy->SetPrinterProps(m_pTempPrinter);
        pTargetView->SetPrinter(m_pDocumentPrinterCopy->Clone());
    }

    SfxObjectShell* pObjSh = pTargetView->GetViewFrame()->GetObjectShell();
    SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), pObjSh));
    rSh.GetNewDBMgr()->SetMergeType( DBMGR_MERGE_DOCUMENTS );
    //SfxDispatcher *pDis = pTargetView->GetViewFrame()->GetDispatcher();
    SfxBoolItem aMergeSilent(SID_SILENT, sal_False);
    m_pWizard->enableButtons(WZB_CANCEL, sal_False);

    uno::Sequence < beans::PropertyValue > aProps( 2 );
    aProps[0]. Name = rtl::OUString::createFromAscii("MonitorVisible");
    aProps[0].Value <<= sal_True;
    aProps[1]. Name = rtl::OUString::createFromAscii("Pages");
    aProps[1]. Value <<= sPages;

    pTargetView->ExecPrint( aProps, false, true );
    SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), pObjSh));

    pTargetView->SetMailMergeConfigItem(0, 0, sal_False);
    m_pWizard->enableButtons(WZB_CANCEL, sal_True);
    m_pWizard->enableButtons(WZB_FINISH, sal_True);
    return 0;
}
/*-- 17.05.2004 13:51:02---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, PrinterSetupHdl_Impl, PushButton*, pButton)
{
    if( !m_pTempPrinter )
        PrinterChangeHdl_Impl(&m_aPrinterLB);
    if(m_pTempPrinter)
        m_pTempPrinter->Setup(pButton);
    return 0;
}
/*-- 14.06.2004 09:34:01---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SendTypeHdl_Impl, ListBox*, pBox)
{
    sal_uLong nDocType = (sal_uLong)pBox->GetEntryData(pBox->GetSelectEntryPos());
    sal_Bool bEnable = MM_DOCTYPE_HTML != nDocType && MM_DOCTYPE_TEXT != nDocType;
    m_aSendAsPB.Enable( bEnable );
    m_aAttachmentFT.Enable( bEnable );
    m_aAttachmentED.Enable( bEnable );
    if(bEnable)
    {
        //add the correct extension
        String sAttach(m_aAttachmentED.GetText());
        //do nothing if the user has removed the name - the warning will come early enough
        if(sAttach.Len())
        {
            xub_StrLen nTokenCount = sAttach.GetTokenCount( '.' );
            if( 2 > nTokenCount)
            {
                sAttach += '.';
                ++nTokenCount;
            }
            sAttach.SetToken( nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
            m_aAttachmentED.SetText(sAttach);
        }
    }
    return 0;
}
/*-- 17.05.2004 13:51:02---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SendAsHdl_Impl, PushButton*, pButton)
{
    SwMailBodyDialog* pDlg = new SwMailBodyDialog(pButton, m_pWizard);
    pDlg->SetBody(m_sBody);
    if(RET_OK == pDlg->Execute())
    {
        m_sBody = pDlg->GetBody();
    }
    return 0;
}
/*-- 21.05.2004 12:03:25---------------------------------------------------
    Send documents as e-mail
  -----------------------------------------------------------------------*/
IMPL_LINK(SwMailMergeOutputPage, SendDocumentsHdl_Impl, PushButton*, pButton)
{
    SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();

    //get the composed document
    SwView* pTargetView = rConfigItem.GetTargetView();
    DBG_ASSERT(pTargetView, "no target view exists");
    if(!pTargetView)
        return 0;

    if(!rConfigItem.GetMailServer().getLength() ||
            !SwMailMergeHelper::CheckMailAddress(rConfigItem.GetMailAddress()) )
    {
        QueryBox aQuery(pButton, WB_YES_NO_CANCEL, m_sConfigureMail);
        sal_uInt16 nRet = aQuery.Execute();
        if(RET_YES == nRet )
        {
            SfxAllItemSet aSet(pTargetView->GetPool());
            SwMailConfigDlg* pDlg = new SwMailConfigDlg(pButton, aSet);
            nRet = pDlg->Execute();
            delete pDlg;
        }

        if(nRet != RET_OK && nRet != RET_YES)
            return 0;
    }
    //add the documents
    sal_uInt32 nBegin = 0;
    sal_uInt32 nEnd = 0;
    if(m_aSendAllRB.IsChecked())
    {
        nBegin = 0;
        nEnd = rConfigItem.GetMergedDocumentCount();
    }
    else
    {
        nBegin  = static_cast< sal_Int32 >(m_aFromNF.GetValue() - 1);
        nEnd    = static_cast< sal_Int32 >(m_aToNF.GetValue());
        if(nEnd > rConfigItem.GetMergedDocumentCount())
            nEnd = rConfigItem.GetMergedDocumentCount();
    }
    bool bAsBody = false;
    bool bIsPDF = false;
    rtl_TextEncoding eEncoding = ::gsl_getSystemTextEncoding();
    SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
    const SfxFilter *pSfxFlt = 0;
    sal_uLong nDocType = (sal_uLong)m_aSendAsLB.GetEntryData(m_aSendAsLB.GetSelectEntryPos());
    String sExtension = lcl_GetExtensionForDocType(nDocType);
    switch( nDocType )
    {
        case MM_DOCTYPE_OOO : break;
        case MM_DOCTYPE_PDF : bIsPDF = true;
        {
            //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
            //because it uses the same user data :-(
            SfxFilterMatcher aMatcher( pFilterContainer->GetName() );
            SfxFilterMatcherIter aIter( &aMatcher );
            const SfxFilter* pFilter = aIter.First();
            String sFilterMime( String::CreateFromAscii( "application/pdf" ));
            while ( pFilter )
            {
                if( pFilter->GetMimeType() == sFilterMime  && pFilter->CanExport() )
                {
                    pSfxFlt = pFilter;
                    break;
                }
                pFilter = aIter.Next();
            }

        }
        break;
        case MM_DOCTYPE_WORD:
        {
            //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
            //because it uses the same user data :-(
            SfxFilterMatcher aMatcher( pFilterContainer->GetName() );
            SfxFilterMatcherIter aIter( &aMatcher );
            const SfxFilter* pFilter = aIter.First();
            String sFilterUserData( String::CreateFromAscii( FILTER_WW8 ));
            while ( pFilter )
            {
                if( pFilter->GetUserData() == sFilterUserData   && pFilter->CanExport() )
                {
                    pSfxFlt = pFilter;
                    break;
                }
                pFilter = aIter.Next();
            }

        }
        break;
        case MM_DOCTYPE_HTML:
        {
            bAsBody = true;
            SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
            eEncoding = pHtmlOptions->GetTextEncoding();
        }
        break;
        case MM_DOCTYPE_TEXT:
            bAsBody = true;
        break;
    }
    if(!pSfxFlt)
        pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT);

    if(!pSfxFlt)
        return 0;
    String sMimeType = pSfxFlt->GetMimeType();

    if(!m_aSubjectED.GetText().Len())
    {
        SwSendQueryBox_Impl aQuery(pButton, m_sNoSubjectQueryST);
        aQuery.SetIsEmptyTextAllowed(true);
        aQuery.SetValue(m_sNoSubjectST);
        if(RET_OK == aQuery.Execute())
        {
            if(aQuery.GetValue() != m_sNoSubjectST)
                m_aSubjectED.SetText(aQuery.GetValue());
        }
        else
            return 0;
    }
    if(!bAsBody && !m_aAttachmentED.GetText().Len())
    {
        SwSendQueryBox_Impl aQuery(pButton, m_sNoAttachmentNameST);
        aQuery.SetIsEmptyTextAllowed(false);
        if(RET_OK == aQuery.Execute())
        {
            String sAttach(aQuery.GetValue());
            xub_StrLen nTokenCount = sAttach.GetTokenCount( '.' );
            if( 2 > nTokenCount)
            {
                sAttach += '.';
                ++nTokenCount;
            }
            sAttach.SetToken( nTokenCount - 1, '.', lcl_GetExtensionForDocType(
                     (sal_uLong)m_aSendAsLB.GetEntryData(m_aSendAsLB.GetSelectEntryPos())));
            m_aAttachmentED.SetText(sAttach);
        }
        else
            return 0;
    }
    SfxStringItem aFilterName( SID_FILTER_NAME, pSfxFlt->GetFilterName() );
    String sEMailColumn = m_aMailToLB.GetSelectEntry();
    DBG_ASSERT( sEMailColumn.Len(), "No email column selected");
    Reference< sdbcx::XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), UNO_QUERY);
    Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
    if(!sEMailColumn.Len() || !xColAccess.is() || !xColAccess->hasByName(sEMailColumn))
        return 0;

    String sFilterOptions;
    if(MM_DOCTYPE_TEXT == nDocType)
    {
        SwAsciiOptions aOpt;
        sal_uInt16 nAppScriptType = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
        sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
        aOpt.SetLanguage( ((SvxLanguageItem&)pTargetView->GetWrtShell().
                            GetDefault( nWhich )).GetLanguage());
        aOpt.SetParaFlags( LINEEND_CR );
        aOpt.WriteUserData( sFilterOptions );
    }
    String sTargetTempURL = URIHelper::SmartRel2Abs(
        INetURLObject(), utl::TempFile::CreateTempName(),
        URIHelper::GetMaybeFileHdl());
    const SfxFilter *pTargetSfxFlt = SwIoSystem::GetFilterOfFormat(
            String::CreateFromAscii( FILTER_XML ),
            SwDocShell::Factory().GetFilterContainer() );

    uno::Sequence< beans::PropertyValue > aValues(1);
    beans::PropertyValue* pValues = aValues.getArray();
    pValues[0].Name = C2U("FilterName");
    pValues[0].Value <<= ::rtl::OUString(pTargetSfxFlt->GetFilterName());

    uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
    xStore->storeToURL( sTargetTempURL, aValues   );

    //create the send dialog
    SwSendMailDialog* pDlg = new SwSendMailDialog( pButton, rConfigItem );
    pDlg->SetDocumentCount( nEnd );
    pDlg->ShowDialog();
    //help to force painting the dialog
    //TODO/CLEANUP
    //Sollbruchstelle
    for ( sal_Int16 i = 0; i < 25; i++)
        Application::Reschedule();
    for(sal_uInt32 nDoc = nBegin; nDoc < nEnd; ++nDoc)
    {
        m_pWizard->EnterWait();
        SwDocMergeInfo& rInfo = rConfigItem.GetDocumentMergeInfo(nDoc);

        //now extract a document from the target document
        // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
        SfxObjectShellLock xTempDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
        xTempDocShell->DoInitNew( 0 );
        SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, 0 );
//        pTempFrame->GetFrame().Appear();
        SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
        pTargetView->GetWrtShell().StartAction();
        SwgReaderOption aOpt;
        aOpt.SetTxtFmts( sal_True );
        aOpt.SetFrmFmts( sal_True );
        aOpt.SetPageDescs( sal_True );
        aOpt.SetNumRules( sal_True );
        aOpt.SetMerge( sal_False );
        pTempView->GetDocShell()->LoadStylesFromFile(
                sTargetTempURL, aOpt, sal_True );
        pTargetView->GetWrtShell().PastePages(pTempView->GetWrtShell(),
                (sal_uInt16)rInfo.nStartPageInTarget, (sal_uInt16)rInfo.nEndPageInTarget );
        pTargetView->GetWrtShell().EndAction();

        //then save it
        SfxStringItem aName(SID_FILE_NAME,
                URIHelper::SmartRel2Abs(
                    INetURLObject(), utl::TempFile::CreateTempName(0),
                    URIHelper::GetMaybeFileHdl()) );

/*        if(bIsPDF)
        {
            SfxDispatcher* pSfxDispatcher = pTempView->GetViewFrame()->GetDispatcher();
            pSfxDispatcher->Execute(
                            SID_DIRECTEXPORTDOCASPDF,
                                  SFX_CALLMODE_SYNCHRON, &aName, &aFilterName, 0L );
        }
        else*/
        {
            uno::Sequence< beans::PropertyValue > aFilterValues(MM_DOCTYPE_TEXT == nDocType ? 2 : 1);
            beans::PropertyValue* pFilterValues = aFilterValues.getArray();
            pFilterValues[0].Name = C2U("FilterName");
            pFilterValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName());
            if(MM_DOCTYPE_TEXT == nDocType)
            {
                pFilterValues[1].Name = C2U("FilterOptions");
                pFilterValues[1].Value <<= ::rtl::OUString(sFilterOptions);
            }

            uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY);
            xTempStore->storeToURL( aName.GetValue(), aFilterValues );
        }
        xTempDocShell->DoClose();

#ifdef DBG_UTIL
        sal_Int32 nTarget =
#endif
                rConfigItem.MoveResultSet(rInfo.nDBRow);
        DBG_ASSERT( nTarget == rInfo.nDBRow, "row of current document could not be selected");
        DBG_ASSERT( sEMailColumn.Len(), "No email column selected");
        ::rtl::OUString sEMail = lcl_GetColumnValueOf(sEMailColumn, xColAccess);
        SwMailDescriptor aDesc;
        aDesc.sEMail = sEMail;
        rtl::OUString sBody;
        if(bAsBody)
        {
            {
                //read in the temporary file and use it as mail body
                SfxMedium aMedium( aName.GetValue(),    STREAM_READ, sal_True);
                SvStream* pInStream = aMedium.GetInStream();
                if(pInStream)
                    pInStream->SetStreamCharSet( eEncoding );
                else
                {
                    DBG_ERROR("no output file created?");
                    continue;
                }
                ByteString sLine;
                sal_Bool bDone = pInStream->ReadLine( sLine );
                while ( bDone )
                {
                    sBody += rtl::OUString(String(sLine, eEncoding));
                    sBody += rtl::OUString('\n');
                    bDone = pInStream->ReadLine( sLine );
                }
            }
            //remove the temporary file
            SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
        }
        else
        {
            sBody = m_sBody;
            aDesc.sAttachmentURL = aName.GetValue();
            String sAttachment(m_aAttachmentED.GetText());
            xub_StrLen nTokenCount = sAttachment.GetTokenCount( '.' );
            if( 2 > nTokenCount)
            {
                sAttachment += '.';
                sAttachment.SetToken( nTokenCount, '.', sExtension);
            }
            else if(sAttachment.GetToken( nTokenCount - 1, '.') != sExtension)
                sAttachment += sExtension;
            aDesc.sAttachmentName = sAttachment;
            aDesc.sMimeType = sMimeType;

            if(rConfigItem.IsGreetingLine(sal_True))
            {
                ::rtl::OUString sNameColumn = rConfigItem.GetAssignedColumn(MM_PART_LASTNAME);
                ::rtl::OUString sName = lcl_GetColumnValueOf(sNameColumn, xColAccess);
                String sGreeting;
                if(sName.getLength() && rConfigItem.IsIndividualGreeting(sal_True))
                {
                    ::rtl::OUString sGenderColumn = rConfigItem.GetAssignedColumn(MM_PART_GENDER);
                    const ::rtl::OUString& sFemaleValue = rConfigItem.GetFemaleGenderValue();
                    ::rtl::OUString sGenderValue = lcl_GetColumnValueOf(sGenderColumn, xColAccess);
                    SwMailMergeConfigItem::Gender eGenderType = sGenderValue == sFemaleValue ?
                        SwMailMergeConfigItem::FEMALE :
                        SwMailMergeConfigItem::MALE;

                    sGreeting = SwAddressPreview::FillData(
                        rConfigItem.GetGreetings(eGenderType)
                        [rConfigItem.GetCurrentGreeting(eGenderType)],
                            rConfigItem);
                }
                else
                {
                    sGreeting =
                        rConfigItem.GetGreetings(SwMailMergeConfigItem::NEUTRAL)
                        [rConfigItem.GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];

                }
                sGreeting += '\n';
                ::rtl::OUString sTemp( sGreeting );
                sTemp += sBody;
                sBody = sTemp;
            }
        }
        aDesc.sBodyContent = sBody;
        if(MM_DOCTYPE_HTML == nDocType)
        {
            aDesc.sBodyMimeType = ::rtl::OUString::createFromAscii("text/html; charset=");
            aDesc.sBodyMimeType += ::rtl::OUString::createFromAscii(
                                rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
        }
        else
            aDesc.sBodyMimeType =
                ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed");

        aDesc.sSubject = m_aSubjectED.GetText();
        aDesc.sCC = m_sCC;
        aDesc.sBCC = m_sBCC;
        pDlg->AddDocument( aDesc );
        //help to force painting the dialog
        for ( sal_Int16 i = 0; i < 25; i++)
            Application::Reschedule();
        //stop creating of data when dialog has been closed
        if(!pDlg->IsVisible())
        {
            m_pWizard->LeaveWait();
            break;
        }
        m_pWizard->LeaveWait();
    }
    pDlg->EnableDesctruction();
    ::osl::File::remove( sTargetTempURL );

    m_pWizard->enableButtons(WZB_FINISH, sal_True);
    //the dialog deletes itself
    //delete pDlg;
    return 0;
}
