diff options
Diffstat (limited to 'sw/source/ui/dbui/mmresultdialogs.cxx')
-rw-r--r-- | sw/source/ui/dbui/mmresultdialogs.cxx | 1295 |
1 files changed, 1295 insertions, 0 deletions
diff --git a/sw/source/ui/dbui/mmresultdialogs.cxx b/sw/source/ui/dbui/mmresultdialogs.cxx new file mode 100644 index 000000000..102920ba5 --- /dev/null +++ b/sw/source/ui/dbui/mmresultdialogs.cxx @@ -0,0 +1,1295 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <mmresultdialogs.hxx> +#include <mmconfigitem.hxx> +#include <mailconfigpage.hxx> +#include "mmgreetingspage.hxx" +#include <printdata.hxx> +#include <swmessdialog.hxx> +#include <cmdid.h> +#include <swtypes.hxx> +#include <view.hxx> +#include <wrtsh.hxx> +#include <docsh.hxx> +#include <IDocumentDeviceAccess.hxx> +#include <hintids.hxx> +#include <swmodule.hxx> + +#include <vcl/QueueInfo.hxx> +#include <editeng/langitem.hxx> +#include <o3tl/temporary.hxx> +#include <svl/itemset.hxx> +#include <svl/stritem.hxx> +#include <svtools/ehdl.hxx> +#include <svtools/sfxecode.hxx> +#include <vcl/stdtext.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <vcl/scheduler.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/fcontnr.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <tools/urlobj.hxx> +#include <svl/urihelper.hxx> +#include <vcl/print.hxx> +#include <rtl/tencinfo.h> +#include <sal/log.hxx> + +#include <unotools/tempfile.hxx> +#include <osl/file.hxx> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdb/XColumn.hpp> +#include <com/sun/star/task/ErrorCodeIOException.hpp> +#include <dbmgr.hxx> +#include <swunohelper.hxx> +#include <shellio.hxx> +#include <svtools/htmlcfg.hxx> +#include <sfx2/event.hxx> +#include <swevent.hxx> +#include <dbui.hxx> +#include <dbui.hrc> +#include <doc.hxx> +#include <sfx2/app.hxx> +#include <strings.hrc> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/string.hxx> +#include <iodetect.hxx> + +using namespace svt; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +#define MM_DOCTYPE_OOO 1 +#define MM_DOCTYPE_PDF 2 +#define MM_DOCTYPE_WORD 3 +#define MM_DOCTYPE_HTML 4 +#define MM_DOCTYPE_TEXT 5 + +static OUString lcl_GetExtensionForDocType(sal_uLong nDocType) +{ + OUString sExtension; + switch( nDocType ) + { + case MM_DOCTYPE_OOO : sExtension = "odt"; break; + case MM_DOCTYPE_PDF : sExtension = "pdf"; break; + case MM_DOCTYPE_WORD: sExtension = "doc"; break; + case MM_DOCTYPE_HTML: sExtension = "html"; break; + case MM_DOCTYPE_TEXT: sExtension = "txt"; break; + } + return sExtension; +} + +static OUString lcl_GetColumnValueOf(const OUString& rColumn, Reference < container::XNameAccess> const & rxColAccess ) +{ + OUString sRet; + try + { + if (rxColAccess->hasByName(rColumn)) + { + Any aCol = rxColAccess->getByName(rColumn); + Reference< sdb::XColumn > xColumn; + aCol >>= xColumn; + if(xColumn.is()) + sRet = xColumn->getString(); + } + } + catch (const uno::Exception&) + { + } + return sRet; +} + +/** + * Replace email server settings in rConfigItem with those set in Writer's global + * mail merge config settings. + */ +static void lcl_UpdateEmailSettingsFromGlobalConfig(SwMailMergeConfigItem& rConfigItem) +{ + // newly created SwMailMergeConfigItem is initialized with values from (global) config + SwMailMergeConfigItem aConfigItem; + + // take over email-related settings + rConfigItem.SetMailDisplayName(aConfigItem.GetMailDisplayName()); + rConfigItem.SetMailAddress(aConfigItem.GetMailAddress()); + rConfigItem.SetMailReplyTo(aConfigItem.GetMailReplyTo()); + rConfigItem.SetMailReplyTo(aConfigItem.IsMailReplyTo()); + rConfigItem.SetMailServer(aConfigItem.GetMailServer()); + rConfigItem.SetMailPort(aConfigItem.GetMailPort()); + rConfigItem.SetSecureConnection(aConfigItem.IsSecureConnection()); + // authentication settings + rConfigItem.SetAuthentication(aConfigItem.IsAuthentication()); + rConfigItem.SetSMTPAfterPOP(aConfigItem.IsSMTPAfterPOP()); + rConfigItem.SetMailUserName(aConfigItem.GetMailUserName()); + rConfigItem.SetMailPassword(aConfigItem.GetMailPassword()); + rConfigItem.SetInServerName(aConfigItem.GetInServerName()); + rConfigItem.SetInServerPort(aConfigItem.GetInServerPort()); + rConfigItem.SetInServerPOP(aConfigItem.IsInServerPOP()); + rConfigItem.SetInServerUserName(aConfigItem.GetInServerUserName()); + rConfigItem.SetInServerPassword(aConfigItem.GetInServerPassword()); +} + +namespace { + +class SwSaveWarningBox_Impl : public SwMessageAndEditDialog +{ + DECL_LINK( ModifyHdl, weld::Entry&, void); +public: + SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName); + + OUString GetFileName() const + { + return m_xEdit->get_text(); + } +}; + +class SwSendQueryBox_Impl : public SwMessageAndEditDialog +{ + bool bIsEmptyAllowed; + DECL_LINK( ModifyHdl, weld::Entry&, void); +public: + SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID, + const OUString& rUIXMLDescription); + + void SetValue(const OUString& rSet) + { + m_xEdit->set_text(rSet); + ModifyHdl(*m_xEdit); + } + + OUString GetValue() const + { + return m_xEdit->get_text(); + } + + void SetIsEmptyTextAllowed(bool bSet) + { + bIsEmptyAllowed = bSet; + ModifyHdl(*m_xEdit); + } +}; + +} + +SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName) + : SwMessageAndEditDialog(pParent, "AlreadyExistsDialog", + "modules/swriter/ui/alreadyexistsdialog.ui") +{ + m_xEdit->set_text(rFileName); + m_xEdit->connect_changed(LINK(this, SwSaveWarningBox_Impl, ModifyHdl)); + + INetURLObject aTmp(rFileName); + m_xDialog->set_primary_text(m_xDialog->get_primary_text().replaceAll("%1", aTmp.getName( + INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset))); + + ModifyHdl(*m_xEdit); +} + +IMPL_LINK( SwSaveWarningBox_Impl, ModifyHdl, weld::Entry&, rEdit, void) +{ + m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty()); +} + +SwSendQueryBox_Impl::SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID, + const OUString& rUIXMLDescription) + : SwMessageAndEditDialog(pParent, rID, rUIXMLDescription) + , bIsEmptyAllowed(true) +{ + m_xEdit->connect_changed(LINK(this, SwSendQueryBox_Impl, ModifyHdl)); + ModifyHdl(*m_xEdit); +} + +IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, weld::Entry&, rEdit, void) +{ + m_xOKPB->set_sensitive(bIsEmptyAllowed || !rEdit.get_text().isEmpty()); +} + +namespace { + +class SwCopyToDialog : public SfxDialogController +{ + std::unique_ptr<weld::Entry> m_xCCED; + std::unique_ptr<weld::Entry> m_xBCCED; + +public: + explicit SwCopyToDialog(weld::Window* pParent) + : SfxDialogController(pParent, "modules/swriter/ui/ccdialog.ui", "CCDialog") + , m_xCCED(m_xBuilder->weld_entry("cc")) + , m_xBCCED(m_xBuilder->weld_entry("bcc")) + { + } + + OUString GetCC() const {return m_xCCED->get_text();} + void SetCC(const OUString& rSet) {m_xCCED->set_text(rSet);} + + OUString GetBCC() const {return m_xBCCED->get_text();} + void SetBCC(const OUString& rSet) {m_xBCCED->set_text(rSet);} +}; + +} + +SwMMResultSaveDialog::SwMMResultSaveDialog(weld::Window* pParent) + : SfxDialogController(pParent, "modules/swriter/ui/mmresultsavedialog.ui", "MMResultSaveDialog") + , m_bCancelSaving(false) + , m_xSaveAsOneRB(m_xBuilder->weld_radio_button("singlerb")) + , m_xSaveIndividualRB(m_xBuilder->weld_radio_button("individualrb")) + , m_xFromRB(m_xBuilder->weld_check_button("fromrb")) + , m_xFromNF(m_xBuilder->weld_spin_button("from")) + , m_xToFT(m_xBuilder->weld_label("toft")) + , m_xToNF(m_xBuilder->weld_spin_button("to")) + , m_xOKButton(m_xBuilder->weld_button("ok")) +{ + Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultSaveDialog, DocumentSelectionHdl_Impl); + m_xSaveAsOneRB->connect_toggled(aLink); + m_xSaveIndividualRB->connect_toggled(aLink); + m_xFromRB->connect_toggled(aLink); + // m_pSaveAsOneRB is the default, so disable m_xFromNF and m_xToNF initially. + aLink.Call(*m_xSaveAsOneRB); + if (SwView* pView = GetActiveView()) + { + const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + sal_Int32 nCount = xConfigItem->GetMergedDocumentCount(); + m_xFromNF->set_max(nCount); + m_xToNF->set_max(nCount); + m_xToNF->set_value(nCount); + } + + m_xOKButton->connect_clicked(LINK(this, SwMMResultSaveDialog, SaveOutputHdl_Impl)); +} + +SwMMResultSaveDialog::~SwMMResultSaveDialog() +{ +} + +SwMMResultPrintDialog::SwMMResultPrintDialog(weld::Window* pParent) + : SfxDialogController(pParent, "modules/swriter/ui/mmresultprintdialog.ui", "MMResultPrintDialog") + , m_xPrinterFT(m_xBuilder->weld_label("printerft")) + , m_xPrinterLB(m_xBuilder->weld_combo_box("printers")) + , m_xPrinterSettingsPB(m_xBuilder->weld_button("printersettings")) + , m_xPrintAllRB(m_xBuilder->weld_radio_button("printallrb")) + , m_xFromRB(m_xBuilder->weld_radio_button("fromrb")) + , m_xFromNF(m_xBuilder->weld_spin_button("from")) + , m_xToFT(m_xBuilder->weld_label("toft")) + , m_xToNF(m_xBuilder->weld_spin_button("to")) + , m_xOKButton(m_xBuilder->weld_button("ok")) +{ + m_xPrinterLB->make_sorted(); + + m_xPrinterLB->connect_changed(LINK(this, SwMMResultPrintDialog, PrinterChangeHdl_Impl)); + m_xPrinterSettingsPB->connect_clicked(LINK(this, SwMMResultPrintDialog, PrinterSetupHdl_Impl)); + + Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultPrintDialog, DocumentSelectionHdl_Impl); + m_xPrintAllRB->connect_toggled(aLink); + m_xFromRB->connect_toggled(aLink); + // m_pPrintAllRB is the default, so disable m_xFromNF and m_xToNF initially. + aLink.Call(*m_xPrintAllRB); + + m_xOKButton->connect_clicked(LINK(this, SwMMResultPrintDialog, PrintHdl_Impl)); + + FillInPrinterSettings(); +} + +SwMMResultPrintDialog::~SwMMResultPrintDialog() +{ +} + +SwMMResultEmailDialog::SwMMResultEmailDialog(weld::Window* pParent) + : SfxDialogController(pParent, "modules/swriter/ui/mmresultemaildialog.ui", "MMResultEmailDialog") + , m_sConfigureMail(SwResId(ST_CONFIGUREMAIL)) + , m_xMailToFT(m_xBuilder->weld_label("mailtoft")) + , m_xMailToLB(m_xBuilder->weld_combo_box("mailto")) + , m_xCopyToPB(m_xBuilder->weld_button("copyto")) + , m_xSubjectFT(m_xBuilder->weld_label("subjectft")) + , m_xSubjectED(m_xBuilder->weld_entry("subject")) + , m_xSendAsFT(m_xBuilder->weld_label("sendasft")) + , m_xSendAsLB(m_xBuilder->weld_combo_box("sendas")) + , m_xSendAsPB(m_xBuilder->weld_button("sendassettings")) + , m_xAttachmentGroup(m_xBuilder->weld_widget("attachgroup")) + , m_xAttachmentED(m_xBuilder->weld_entry("attach")) + , m_xPasswordFT(m_xBuilder->weld_label("passwordft")) + , m_xPasswordLB(m_xBuilder->weld_combo_box("password")) + , m_xPasswordCB(m_xBuilder->weld_check_button("passwordcb")) + , m_xSendAllRB(m_xBuilder->weld_radio_button("sendallrb")) + , m_xFromRB(m_xBuilder->weld_radio_button("fromrb")) + , m_xFromNF(m_xBuilder->weld_spin_button("from")) + , m_xToFT(m_xBuilder->weld_label("toft")) + , m_xToNF(m_xBuilder->weld_spin_button("to")) + , m_xOKButton(m_xBuilder->weld_button("ok")) +{ + m_xCopyToPB->connect_clicked(LINK(this, SwMMResultEmailDialog, CopyToHdl_Impl)); + m_xSendAsPB->connect_clicked(LINK(this, SwMMResultEmailDialog, SendAsHdl_Impl)); + m_xSendAsLB->connect_changed(LINK(this, SwMMResultEmailDialog, SendTypeHdl_Impl)); + m_xPasswordCB->connect_toggled( LINK( this, SwMMResultEmailDialog, CheckHdl )); + + Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultEmailDialog, DocumentSelectionHdl_Impl); + m_xSendAllRB->connect_toggled(aLink); + m_xFromRB->connect_toggled(aLink); + // m_xSendAllRB is the default, so disable m_xFromNF and m_xToNF initially. + aLink.Call(*m_xSendAllRB); + + m_xOKButton->connect_clicked(LINK(this, SwMMResultEmailDialog, SendDocumentsHdl_Impl)); + + m_xPasswordCB->set_sensitive(false); + m_xPasswordFT->set_sensitive(false); + m_xPasswordLB->set_sensitive(false); + + FillInEmailSettings(); +} + +SwMMResultEmailDialog::~SwMMResultEmailDialog() +{ +} + +void SwMMResultPrintDialog::FillInPrinterSettings() +{ + //fill printer ListBox + SwView* pView = GetActiveView(); + if (!pView) + return; + const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem(); + const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues(); + unsigned int nCount = rPrinters.size(); + bool bMergePrinterExists = false; + + for (unsigned int i = 0; i < nCount; ++i) + { + m_xPrinterLB->append_text( rPrinters[i] ); + if( !bMergePrinterExists && rPrinters[i] == xConfigItem->GetSelectedPrinter() ) + bMergePrinterExists = true; + } + + assert(xConfigItem); + if(!bMergePrinterExists) + { + SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true ); + m_xPrinterLB->set_active_text(pPrinter->GetName()); + } + else + { + m_xPrinterLB->set_active_text(xConfigItem->GetSelectedPrinter()); + } + PrinterChangeHdl_Impl(*m_xPrinterLB); + + sal_Int32 count = xConfigItem->GetMergedDocumentCount(); + m_xFromNF->set_max(count); + m_xToNF->set_value(count); + m_xToNF->set_max(count); +} + +void SwMMResultEmailDialog::FillInEmailSettings() +{ + SwView* pView = GetActiveView(); + if (!pView) + return; + const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + + SwView* pSourceView = xConfigItem->GetSourceView(); + OSL_ENSURE(pSourceView, "no source view exists"); + if (pSourceView) + { + SwDocShell* pDocShell = pSourceView->GetDocShell(); + if (pDocShell->HasName()) + { + INetURLObject aTmp(pDocShell->GetMedium()->GetName()); + m_xAttachmentED->set_text(aTmp.getName( + INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset )); + } + } + + if (m_xAttachmentED->get_text().isEmpty()) + { + OUString sAttach = "." + lcl_GetExtensionForDocType(m_xSendAsLB->get_active_id().toUInt32()); + m_xAttachmentED->set_text(sAttach); + + } + + //select first column + uno::Reference< sdbcx::XColumnsSupplier > xColsSupp(xConfigItem->GetResultSet(), uno::UNO_QUERY); + //get the name of the actual columns + uno::Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr; + uno::Sequence< OUString > aFields; + if (xColAccess.is()) + aFields = xColAccess->getElementNames(); + + // fill mail address and password ListBox + assert(m_xMailToLB->get_count() == 0); + assert(m_xPasswordLB->get_count() == 0); + for (const OUString& rField : std::as_const(aFields)) + { + m_xMailToLB->append_text(rField); + m_xPasswordLB->append_text(rField); + } + + m_xMailToLB->set_active(0); + m_xPasswordLB->set_active(0); + + // then select the right one - may not be available + const std::vector<std::pair<OUString, int>>& rHeaders = xConfigItem->GetDefaultAddressHeaders(); + OUString sEMailColumn = rHeaders[MM_PART_E_MAIL].first; + Sequence< OUString> aAssignment = xConfigItem->GetColumnAssignment(xConfigItem->GetCurrentDBData()); + if (aAssignment.getLength() > MM_PART_E_MAIL && !aAssignment[MM_PART_E_MAIL].isEmpty()) + sEMailColumn = aAssignment[MM_PART_E_MAIL]; + if (int pos = m_xMailToLB->find_text(sEMailColumn); pos >= 0) + m_xMailToLB->set_active(pos); + + // HTML format pre-selected + m_xSendAsLB->set_active(3); + SendTypeHdl_Impl(*m_xSendAsLB); + + const sal_Int32 nCount = xConfigItem->GetMergedDocumentCount(); + m_xFromNF->set_max(nCount); + m_xToNF->set_max(nCount); + m_xToNF->set_value(nCount); +} + +IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void) +{ + bool bEnableFromTo = m_xFromRB->get_active(); + m_xFromNF->set_sensitive(bEnableFromTo); + m_xToFT->set_sensitive(bEnableFromTo); + m_xToNF->set_sensitive(bEnableFromTo); +} + +IMPL_LINK_NOARG(SwMMResultEmailDialog, CheckHdl, weld::Toggleable&, void) +{ + bool bEnable = m_xPasswordCB->get_active(); + + m_xPasswordFT->set_sensitive(bEnable); + m_xPasswordLB->set_sensitive(bEnable); +} + +IMPL_LINK_NOARG(SwMMResultPrintDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void) +{ + bool bEnableFromTo = m_xFromRB->get_active(); + m_xFromNF->set_sensitive(bEnableFromTo); + m_xToFT->set_sensitive(bEnableFromTo); + m_xToNF->set_sensitive(bEnableFromTo); +} + +IMPL_LINK_NOARG(SwMMResultEmailDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void) +{ + bool bEnableFromTo = m_xFromRB->get_active(); + m_xFromNF->set_sensitive(bEnableFromTo); + m_xToFT->set_sensitive(bEnableFromTo); + m_xToNF->set_sensitive(bEnableFromTo); +} + +IMPL_LINK_NOARG(SwMMResultEmailDialog, CopyToHdl_Impl, weld::Button&, void) +{ + SwCopyToDialog aDlg(m_xDialog.get()); + aDlg.SetCC(m_sCC ); + aDlg.SetBCC(m_sBCC); + if (aDlg.run() == RET_OK) + { + m_sCC = aDlg.GetCC() ; + m_sBCC = aDlg.GetBCC(); + } +} + +namespace { + +int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty) +{ + SwView* pTargetView = pConfigItem->GetTargetView(); + assert( pTargetView ); + SwCursorShell& shell = pTargetView->GetWrtShell(); + const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo(document); + sal_uInt16 page; + shell.Push(); + shell.GotoMark( info.startPageInTarget ); + if (!bIgnoreEmpty) + shell.GetPageNum(page, o3tl::temporary(sal_uInt16())); + else + page = shell.GetPageNumSeqNonEmpty(); + shell.Pop(SwCursorShell::PopMode::DeleteCurrent); + return page; +} + +int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty) +{ + SwView* pTargetView = pConfigItem->GetTargetView(); + assert( pTargetView ); + SwWrtShell& shell = pTargetView->GetWrtShell(); + shell.Push(); + if (document < int(pConfigItem->GetMergedDocumentCount()) - 1) + { + // Go to the page before the starting page of the next merged document. + const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo( document + 1 ); + shell.GotoMark( info.startPageInTarget ); + shell.EndPrvPg(); + } + else + { // This is the last merged document, so it ends on the page at which the document ends. + shell.SttEndDoc( false ); // go to doc end + } + sal_uInt16 page; + if (!bIgnoreEmpty) + shell.GetPageNum(page, o3tl::temporary(sal_uInt16())); + else + page = shell.GetPageNumSeqNonEmpty(); + shell.Pop(SwCursorShell::PopMode::DeleteCurrent); + return page; +} + +} // anonymous namespace + +IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void) +{ + SwView* pView = GetActiveView(); + if (!pView) + return; + std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + + const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount(); + sal_uInt32 nBegin = 0; + sal_uInt32 nEnd = nDocumentCount; + + if (m_xFromRB->get_active()) + { + nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1); + nEnd = static_cast<sal_Int32>(m_xToNF->get_value()); + if (nEnd > nDocumentCount) + nEnd = nDocumentCount; + } + + xConfigItem->SetBeginEnd(nBegin, nEnd); + + if (!xConfigItem->GetTargetView()) + SwDBManager::PerformMailMerge(pView); + + SwView* pTargetView = xConfigItem->GetTargetView(); + assert(pTargetView); + + OUString sFilter; + OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter); + if (sPath.isEmpty()) + { + // just return back to the dialog + return; + } + + if (m_xSaveAsOneRB->get_active()) + { + uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", sFilter) }; + + uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY); + ErrCode nErrorCode = ERRCODE_NONE; + try + { + xStore->storeToURL( sPath, aValues ); + } + catch (const task::ErrorCodeIOException& rErrorEx) + { + nErrorCode = ErrCode(rErrorEx.ErrCode); + } + catch (const Exception&) + { + nErrorCode = ERRCODE_IO_GENERAL; + } + if( nErrorCode != ERRCODE_NONE ) + { + SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle()); + ErrorHandler::HandleError( nErrorCode ); + } + } + else + { + OUString sTargetTempURL = URIHelper::SmartRel2Abs( + INetURLObject(), utl::TempFile::CreateTempName(), + URIHelper::GetMaybeFileHdl()); + std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat( + FILTER_XML, + SwDocShell::Factory().GetFilterContainer() ); + + uno::Sequence< beans::PropertyValue > aValues(1); + beans::PropertyValue* pValues = aValues.getArray(); + pValues[0].Name = "FilterName"; + pValues[0].Value <<= pSfxFlt->GetFilterName(); + + uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY); + ErrCode nErrorCode = ERRCODE_NONE; + try + { + xStore->storeToURL( sTargetTempURL, aValues ); + } + catch (const task::ErrorCodeIOException& rErrorEx) + { + nErrorCode = ErrCode(rErrorEx.ErrCode); + } + catch (const Exception&) + { + nErrorCode = ERRCODE_IO_GENERAL; + } + if( nErrorCode != ERRCODE_NONE ) + { + SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle()); + ErrorHandler::HandleError( nErrorCode ); + } + + SwView* pSourceView = xConfigItem->GetSourceView(); + auto xSaveMonitor = std::make_shared<SaveMonitor>(m_xDialog.get()); + xSaveMonitor->m_xDocName->set_label(pSourceView->GetDocShell()->GetTitle(22)); + xSaveMonitor->m_xPrinter->set_label( INetURLObject( sPath ).getFSysPath( FSysStyle::Detect ) ); + m_bCancelSaving = false; + weld::DialogController::runAsync(xSaveMonitor, [this, &xSaveMonitor](sal_Int32 nResult){ + if (nResult == RET_CANCEL) + m_bCancelSaving = true; + xSaveMonitor.reset(); + }); + + for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin && !m_bCancelSaving; ++nDoc) + { + INetURLObject aURL(sPath); + OUString sExtension = aURL.getExtension(); + if (sExtension.isEmpty()) + { + sExtension = pSfxFlt->GetWildcard().getGlob().getToken(1, '.'); + sPath += "." + sExtension; + } + OUString sStat = SwResId(STR_STATSTR_LETTER) + " " + OUString::number(nDoc + 1); + xSaveMonitor->m_xPrintInfo->set_label(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( SfxObjectCreateMode::STANDARD ) ); + xTempDocShell->DoInitNew(); + SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE ); + SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() ); + pTargetView->GetWrtShell().StartAction(); + SwgReaderOption aOpt; + aOpt.SetTextFormats( true ); + aOpt.SetFrameFormats( true ); + aOpt.SetPageDescs( true ); + aOpt.SetNumRules( true ); + aOpt.SetMerge( false ); + pTempView->GetDocShell()->LoadStylesFromFile( + sTargetTempURL, aOpt, true ); + pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc()); + pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc()); + pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true ); + + uno::Reference<beans::XPropertySet> const xThisSet( + pTargetView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> const xRetSet( + pTempView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW); + uno::Sequence<beans::PropertyValue> aInteropGrabBag; + xThisSet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag; + xRetSet->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag)); + + pTargetView->GetWrtShell().PastePages( + pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false), + documentEndPageNumber(xConfigItem.get(), nDoc, false)); + pTargetView->GetWrtShell().EndAction(); + //then save it + OUString sOutPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); + OUString sCounter = "_" + OUString::number(nDoc + 1); + sOutPath = sOutPath.replaceAt( sOutPath.getLength() - sExtension.getLength() - 1, 0, sCounter); + + while(true) + { + //time for other slots is needed + Scheduler::ProcessEventsToIdle(); + + bool bFailed = false; + try + { + pValues[0].Value <<= sFilter; + uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY); + xTempStore->storeToURL( sOutPath, aValues ); + } + catch (const uno::Exception&) + { + bFailed = true; + } + + if(bFailed) + { + std::unique_ptr<SwSaveWarningBox_Impl> xWarning(new SwSaveWarningBox_Impl(m_xDialog.get(), sOutPath)); + if (RET_OK == xWarning->run()) + sOutPath = xWarning->GetFileName(); + else + { + xTempDocShell->DoClose(); + m_xDialog->response(RET_OK); + return; + } + } + else + { + xTempDocShell->DoClose(); + m_xDialog->response(RET_OK); + break; + } + } + } + if (xSaveMonitor) + xSaveMonitor->response(RET_OK); + ::osl::File::remove( sTargetTempURL ); + } + + m_xDialog->response(RET_OK); +} + +IMPL_LINK(SwMMResultPrintDialog, PrinterChangeHdl_Impl, weld::ComboBox&, rBox, void) +{ + SwView* pView = GetActiveView(); + if (!pView) + return; + const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + if (rBox.get_active() != -1) + { + const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false ); + + if( pInfo ) + { + if ( !m_pTempPrinter ) + { + m_pTempPrinter = VclPtr<Printer>::Create( *pInfo ); + } + else + { + if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) || + (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) ) + { + m_pTempPrinter.disposeAndClear(); + m_pTempPrinter = VclPtr<Printer>::Create( *pInfo ); + } + } + } + else if( ! m_pTempPrinter ) + m_pTempPrinter = VclPtr<Printer>::Create(); + + m_xPrinterSettingsPB->set_sensitive(m_pTempPrinter->HasSupport(PrinterSupport::SetupDialog)); + } + else + m_xPrinterSettingsPB->set_sensitive(false); + + xConfigItem->SetSelectedPrinter(rBox.get_active_text()); +} + +IMPL_LINK_NOARG(SwMMResultPrintDialog, PrintHdl_Impl, weld::Button&, void) +{ + SwView* pView = GetActiveView(); + if (!pView) + return; + std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + + const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount(); + sal_uInt32 nBegin = 0; + sal_uInt32 nEnd = nDocumentCount; + + if (m_xFromRB->get_active()) + { + nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1); + nEnd = static_cast<sal_Int32>(m_xToNF->get_value()); + if (nEnd > nDocumentCount) + nEnd = nDocumentCount; + } + + xConfigItem->SetBeginEnd(nBegin, nEnd); + + if(!xConfigItem->GetTargetView()) + SwDBManager::PerformMailMerge(pView); + + SwView* pTargetView = xConfigItem->GetTargetView(); + assert(pTargetView); + + // If we skip autoinserted blanks, then the page numbers used in the print range string + // refer to the non-blank pages as they appear in the document (see tdf#89708). + const bool bIgnoreEmptyPages = + !pTargetView->GetDocShell()->GetDoc()->getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages(); + const int nStartPage = documentStartPageNumber(xConfigItem.get(), 0, bIgnoreEmptyPages); + const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - nBegin - 1, bIgnoreEmptyPages); + + const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage)); + + pTargetView->SetMailMergeConfigItem(xConfigItem); + if(m_pTempPrinter) + { + SfxPrinter *const pDocumentPrinter = pTargetView->GetWrtShell() + .getIDocumentDeviceAccess().getPrinter(true); + pDocumentPrinter->SetPrinterProps(m_pTempPrinter); + // this should be able to handle setting its own printer + pTargetView->SetPrinter(pDocumentPrinter); + } + + SfxObjectShell* pObjSh = pTargetView->GetViewFrame()->GetObjectShell(); + SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMerge, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), pObjSh)); + + uno::Sequence aProps{ comphelper::makePropertyValue("MonitorVisible", true), + comphelper::makePropertyValue("Pages", sPages) }; + + pTargetView->ExecPrint( aProps, false, true ); + SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), pObjSh)); + + m_xDialog->response(RET_OK); +} + +IMPL_LINK_NOARG(SwMMResultPrintDialog, PrinterSetupHdl_Impl, weld::Button&, void) +{ + if (m_pTempPrinter) + m_pTempPrinter->Setup(m_xDialog.get()); +} + +IMPL_LINK(SwMMResultEmailDialog, SendTypeHdl_Impl, weld::ComboBox&, rBox, void) +{ + auto nDocType = rBox.get_active_id().toUInt32(); + bool bEnable = MM_DOCTYPE_HTML != nDocType && MM_DOCTYPE_TEXT != nDocType; + bool bIsPDF = nDocType == MM_DOCTYPE_PDF; + m_xSendAsPB->set_sensitive(bEnable); + m_xAttachmentGroup->set_sensitive(bEnable); + if(bEnable) + { + //add the correct extension + OUString sAttach(m_xAttachmentED->get_text()); + //do nothing if the user has removed the name - the warning will come early enough + if (!sAttach.isEmpty()) + { + sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.'); + if( 2 > nTokenCount) + { + sAttach += "."; + ++nTokenCount; + } + sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType )); + m_xAttachmentED->set_text(sAttach); + } + } + + if(bIsPDF) + { + m_xPasswordCB->set_sensitive(true); + m_xPasswordFT->set_sensitive(true); + m_xPasswordLB->set_sensitive(true); + CheckHdl(*m_xPasswordCB); + } + else + { + m_xPasswordCB->set_sensitive(false); + m_xPasswordFT->set_sensitive(false); + m_xPasswordLB->set_sensitive(false); + } +} + +IMPL_LINK_NOARG(SwMMResultEmailDialog, SendAsHdl_Impl, weld::Button&, void) +{ + SwMailBodyDialog aDlg(m_xDialog.get()); + aDlg.SetBody(m_sBody); + if (RET_OK == aDlg.run()) + { + m_sBody = aDlg.GetBody(); + } +} + +// Send documents as e-mail +IMPL_LINK_NOARG(SwMMResultEmailDialog, SendDocumentsHdl_Impl, weld::Button&, void) +{ + SwView* pView = GetActiveView(); + if (!pView) + return; + std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem(); + assert(xConfigItem); + + const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount(); + sal_uInt32 nBegin = 0; + sal_uInt32 nEnd = nDocumentCount; + + if (m_xFromRB->get_active()) + { + nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1); + nEnd = static_cast<sal_Int32>(m_xToNF->get_value()); + if (nEnd > nDocumentCount) + nEnd = nDocumentCount; + } + + xConfigItem->SetBeginEnd(nBegin, nEnd); + + if (!xConfigItem->GetTargetView()) + SwDBManager::PerformMailMerge(pView); + + //get the composed document + SwView* pTargetView = xConfigItem->GetTargetView(); + SAL_WARN_IF(!pTargetView, "sw.ui", "No TargetView in SwMailMergeConfigItem"); + + if (xConfigItem->GetMailServer().isEmpty() || + !SwMailMergeHelper::CheckMailAddress(xConfigItem->GetMailAddress()) ) + { + std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Question, VclButtonsType::YesNo, + m_sConfigureMail)); + xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL); + sal_uInt16 nRet = xQueryBox->run(); + if (RET_YES == nRet ) + { + SwView* pConfigView = pTargetView ? pTargetView : pView; + SfxAllItemSet aSet(pConfigView->GetPool()); + SwMailConfigDlg aDlg(m_xDialog.get(), aSet); + nRet = aDlg.run(); + } + + if(nRet != RET_OK && nRet != RET_YES) + return; // back to the dialog + + // SwMailConfigDlg writes mail merge email settings only to (global) config, + // so copy them to the existing config item + lcl_UpdateEmailSettingsFromGlobalConfig(*xConfigItem); + } + //add the documents + bool bAsBody = false; + rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding(); + SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer(); + std::shared_ptr<const SfxFilter> pSfxFlt; + auto nDocType = m_xSendAsLB->get_active_id().toUInt32(); + OUString sExtension = lcl_GetExtensionForDocType(nDocType); + switch( nDocType ) + { + case MM_DOCTYPE_OOO: + { + //Make sure we don't pick e.g. the flat xml filter + //for this format + pSfxFlt = pFilterContainer->GetFilter4FilterName( + "writer8", + SfxFilterFlags::EXPORT); + } + break; + case MM_DOCTYPE_PDF: + { + pSfxFlt = pFilterContainer->GetFilter4FilterName( + "writer_pdf_Export", + SfxFilterFlags::EXPORT); + } + 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 ); + std::shared_ptr<const SfxFilter> pFilter = aIter.First(); + while ( pFilter ) + { + if( pFilter->GetUserData() == FILTER_WW8 && pFilter->CanExport() ) + { + pSfxFlt = pFilter; + break; + } + pFilter = aIter.Next(); + } + + } + break; + case MM_DOCTYPE_HTML: + { + bAsBody = true; + eEncoding = RTL_TEXTENCODING_UTF8; + } + break; + case MM_DOCTYPE_TEXT: + { + bAsBody = true; + pSfxFlt = pFilterContainer->GetFilter4FilterName( + "Text (encoded)", SfxFilterFlags::EXPORT); + } + break; + } + if(!pSfxFlt) + pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT); + + if(!pSfxFlt) + { + m_xDialog->response(RET_OK); + return; + } + OUString sMimeType = pSfxFlt->GetMimeType(); + + if (m_xSubjectED->get_text().isEmpty()) + { + std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "SubjectDialog", + "modules/swriter/ui/subjectdialog.ui")); + xQuery->SetIsEmptyTextAllowed(true); + xQuery->SetValue(""); + if(RET_OK == xQuery->run()) + { + if (!xQuery->GetValue().isEmpty()) + m_xSubjectED->set_text(xQuery->GetValue()); + } + else + return; // back to the dialog + } + if(!bAsBody && m_xAttachmentED->get_text().isEmpty()) + { + std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "AttachNameDialog", + "modules/swriter/ui/attachnamedialog.ui")); + xQuery->SetIsEmptyTextAllowed(false); + if (RET_OK == xQuery->run()) + { + OUString sAttach(xQuery->GetValue()); + sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.'); + if (2 > nTokenCount) + { + sAttach += "."; + ++nTokenCount; + } + sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( + m_xSendAsLB->get_active_id().toUInt32())); + m_xAttachmentED->set_text(sAttach); + } + else + return; // back to the dialog + } + + OUString sEMailColumn = m_xMailToLB->get_active_text(); + OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected"); + Reference< sdbcx::XColumnsSupplier > xColsSupp( xConfigItem->GetResultSet(), UNO_QUERY); + Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr; + if(sEMailColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sEMailColumn)) + { + m_xDialog->response(RET_OK); + return; + } + + OUString sPasswordColumn = m_xPasswordLB->get_active_text(); + OSL_ENSURE( !sPasswordColumn.isEmpty(), "No password column selected"); + if(sPasswordColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sPasswordColumn)) + { + m_xDialog->response(RET_OK); + return; + } + + OUString sFilterOptions; + if(MM_DOCTYPE_TEXT == nDocType) + { + SwAsciiOptions aOpt; + sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ); + sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType); + aOpt.SetLanguage( static_cast<const SvxLanguageItem&>(pTargetView->GetWrtShell(). + GetDefault( nWhich )).GetLanguage()); + aOpt.SetParaFlags( LINEEND_CR ); + aOpt.WriteUserData( sFilterOptions ); + } + else if(MM_DOCTYPE_HTML == nDocType) + { + sFilterOptions = "EmbedImages"; + } + OUString sTargetTempURL = URIHelper::SmartRel2Abs( + INetURLObject(), utl::TempFile::CreateTempName(), + URIHelper::GetMaybeFileHdl()); + std::shared_ptr<const SfxFilter> pTargetSfxFlt = SwIoSystem::GetFilterOfFormat( + FILTER_XML, + SwDocShell::Factory().GetFilterContainer() ); + + uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", pTargetSfxFlt->GetFilterName()) }; + + uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY); + xStore->storeToURL( sTargetTempURL, aValues ); + + //create the send dialog + std::shared_ptr<SwSendMailDialog> xDlg = std::make_shared<SwSendMailDialog>(Application::GetDefDialogParent(), *xConfigItem); + + xDlg->StartSend(nEnd - nBegin); + weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){}); + + //help to force painting the dialog + //TODO/CLEANUP + //predetermined breaking point + Application::Reschedule( true ); + m_xDialog->response(RET_OK); + for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin; ++nDoc) + { + SwDocMergeInfo& rInfo = xConfigItem->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( SfxObjectCreateMode::STANDARD ) ); + xTempDocShell->DoInitNew(); + SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE ); + SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() ); + pTargetView->GetWrtShell().StartAction(); + SwgReaderOption aOpt; + aOpt.SetTextFormats( true ); + aOpt.SetFrameFormats( true ); + aOpt.SetPageDescs( true ); + aOpt.SetNumRules( true ); + aOpt.SetMerge( false ); + pTempView->GetDocShell()->LoadStylesFromFile( + sTargetTempURL, aOpt, true ); + pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc()); + pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc()); + pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true ); + pTargetView->GetWrtShell().PastePages( + pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false), + documentEndPageNumber(xConfigItem.get(), nDoc, false)); + pTargetView->GetWrtShell().EndAction(); + + //then save it + SfxStringItem aName(SID_FILE_NAME, + URIHelper::SmartRel2Abs( + INetURLObject(), utl::TempFile::CreateTempName(), + URIHelper::GetMaybeFileHdl()) ); + + { + bool withFilterOptions = MM_DOCTYPE_TEXT == nDocType || MM_DOCTYPE_HTML == nDocType; + bool withPasswordOptions = m_xPasswordCB->get_active(); + + sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow); + OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected"); + OUString sPassword = lcl_GetColumnValueOf(sPasswordColumn, xColAccess); + + sal_Int32 nOptionCount = (withFilterOptions && withPasswordOptions) ? 4 : withPasswordOptions ? 3 : withFilterOptions ? 2 : 1; + sal_Int32 nOpt = 0; + uno::Sequence< beans::PropertyValue > aFilterValues(nOptionCount); + beans::PropertyValue* pFilterValues = aFilterValues.getArray(); + + pFilterValues[nOpt].Name = "FilterName"; + pFilterValues[nOpt].Value <<= pSfxFlt->GetFilterName(); + + if(withFilterOptions) + { + nOpt++; + pFilterValues[nOpt].Name = "FilterOptions"; + pFilterValues[nOpt].Value <<= sFilterOptions; + } + + if(withPasswordOptions) + { + nOpt++; + pFilterValues[nOpt].Name = "EncryptFile"; + pFilterValues[nOpt].Value <<= true; + nOpt++; + pFilterValues[nOpt].Name = "DocumentOpenPassword"; + pFilterValues[nOpt].Value <<= sPassword; + } + + uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY); + xTempStore->storeToURL( aName.GetValue(), aFilterValues ); + } + xTempDocShell->DoClose(); + + sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow); + OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected"); + OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected"); + OUString sEMail = lcl_GetColumnValueOf(sEMailColumn, xColAccess); + SwMailDescriptor aDesc; + aDesc.sEMail = sEMail; + OUStringBuffer sBody; + if(bAsBody) + { + { + //read in the temporary file and use it as mail body + SfxMedium aMedium( aName.GetValue(), StreamMode::READ); + SvStream* pInStream = aMedium.GetInStream(); + if(pInStream) + pInStream->SetStreamCharSet( eEncoding ); + else + { + OSL_FAIL("no output file created?"); + continue; + } + OStringBuffer sLine; + bool bDone = pInStream->ReadLine( sLine ); + while ( bDone ) + { + sBody.append( OStringToOUString(sLine, eEncoding) ); + sBody.append("\n"); + bDone = pInStream->ReadLine( sLine ); + } + } + //remove the temporary file + SWUnoHelper::UCB_DeleteFile( aName.GetValue() ); + } + else + { + sBody = m_sBody; + aDesc.sAttachmentURL = aName.GetValue(); + OUString sAttachment(m_xAttachmentED->get_text()); + sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttachment, '.'); + if (2 > nTokenCount) + { + sAttachment += "."; + sAttachment = comphelper::string::setToken(sAttachment, nTokenCount, '.', sExtension); + } + else if (o3tl::getToken(sAttachment, nTokenCount - 1, '.') != sExtension) + sAttachment += sExtension; + aDesc.sAttachmentName = sAttachment; + aDesc.sMimeType = sMimeType; + + if (xConfigItem->IsGreetingLine(true)) + { + OUString sNameColumn = xConfigItem->GetAssignedColumn(MM_PART_LASTNAME); + OUString sName = lcl_GetColumnValueOf(sNameColumn, xColAccess); + OUString sGreeting; + if(!sName.isEmpty() && xConfigItem->IsIndividualGreeting(true)) + { + OUString sGenderColumn = xConfigItem->GetAssignedColumn(MM_PART_GENDER); + const OUString& sFemaleValue = xConfigItem->GetFemaleGenderValue(); + OUString sGenderValue = lcl_GetColumnValueOf(sGenderColumn, xColAccess); + SwMailMergeConfigItem::Gender eGenderType = sGenderValue == sFemaleValue ? + SwMailMergeConfigItem::FEMALE : + SwMailMergeConfigItem::MALE; + + sGreeting = SwAddressPreview::FillData( + xConfigItem->GetGreetings(eGenderType) + [xConfigItem->GetCurrentGreeting(eGenderType)], + *xConfigItem); + } + else + { + sGreeting = + xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL) + [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)]; + + } + sGreeting += "\n"; + sBody.insert(0, sGreeting); + } + } + aDesc.sBodyContent = sBody.makeStringAndClear(); + if(MM_DOCTYPE_HTML == nDocType) + { + aDesc.sBodyMimeType = "text/html; charset=" + + OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding )); + } + else + aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed"; + + aDesc.sSubject = m_xSubjectED->get_text(); + aDesc.sCC = m_sCC; + aDesc.sBCC = m_sBCC; + xDlg->AddDocument( aDesc ); + //help to force painting the dialog + Application::Reschedule( true ); + //stop creating of data when dialog has been closed + if (!xDlg->getDialog()->get_visible()) + { + break; + } + } + xDlg->EnableDestruction(); + ::osl::File::remove( sTargetTempURL ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |