1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <mmresultdialogs.hxx>
21 #include <mmconfigitem.hxx>
22 #include <mailconfigpage.hxx>
23 #include "mmgreetingspage.hxx"
24 #include <printdata.hxx>
25 #include <swmessdialog.hxx>
27 #include <swtypes.hxx>
31 #include <IDocumentDeviceAccess.hxx>
32 #include <hintids.hxx>
33 #include <swmodule.hxx>
35 #include <vcl/QueueInfo.hxx>
36 #include <editeng/langitem.hxx>
37 #include <o3tl/temporary.hxx>
38 #include <svl/itemset.hxx>
39 #include <svl/stritem.hxx>
40 #include <svtools/ehdl.hxx>
41 #include <svtools/sfxecode.hxx>
42 #include <vcl/stdtext.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/weld.hxx>
45 #include <vcl/scheduler.hxx>
46 #include <sfx2/printer.hxx>
47 #include <sfx2/fcontnr.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <sfx2/docfilt.hxx>
51 #include <tools/urlobj.hxx>
52 #include <svl/urihelper.hxx>
53 #include <vcl/print.hxx>
54 #include <rtl/tencinfo.h>
55 #include <sal/log.hxx>
57 #include <unotools/tempfile.hxx>
58 #include <osl/file.hxx>
59 #include <com/sun/star/frame/XStorable.hpp>
60 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
61 #include <com/sun/star/sdb/XColumn.hpp>
62 #include <com/sun/star/task/ErrorCodeIOException.hpp>
64 #include <swunohelper.hxx>
65 #include <shellio.hxx>
66 #include <svtools/htmlcfg.hxx>
67 #include <sfx2/event.hxx>
68 #include <swevent.hxx>
72 #include <sfx2/app.hxx>
73 #include <strings.hrc>
74 #include <comphelper/propertyvalue.hxx>
75 #include <comphelper/string.hxx>
76 #include <iodetect.hxx>
79 using namespace ::com::sun::star
;
80 using namespace ::com::sun::star::uno
;
82 #define MM_DOCTYPE_OOO 1
83 #define MM_DOCTYPE_PDF 2
84 #define MM_DOCTYPE_WORD 3
85 #define MM_DOCTYPE_HTML 4
86 #define MM_DOCTYPE_TEXT 5
88 static OUString
lcl_GetExtensionForDocType(sal_uLong nDocType
)
93 case MM_DOCTYPE_OOO
: sExtension
= "odt"; break;
94 case MM_DOCTYPE_PDF
: sExtension
= "pdf"; break;
95 case MM_DOCTYPE_WORD
: sExtension
= "doc"; break;
96 case MM_DOCTYPE_HTML
: sExtension
= "html"; break;
97 case MM_DOCTYPE_TEXT
: sExtension
= "txt"; break;
102 static OUString
lcl_GetColumnValueOf(const OUString
& rColumn
, Reference
< container::XNameAccess
> const & rxColAccess
)
107 if (rxColAccess
->hasByName(rColumn
))
109 Any aCol
= rxColAccess
->getByName(rColumn
);
110 Reference
< sdb::XColumn
> xColumn
;
113 sRet
= xColumn
->getString();
116 catch (const uno::Exception
&)
123 * Replace email server settings in rConfigItem with those set in Writer's global
124 * mail merge config settings.
126 static void lcl_UpdateEmailSettingsFromGlobalConfig(SwMailMergeConfigItem
& rConfigItem
)
128 // newly created SwMailMergeConfigItem is initialized with values from (global) config
129 SwMailMergeConfigItem aConfigItem
;
131 // take over email-related settings
132 rConfigItem
.SetMailDisplayName(aConfigItem
.GetMailDisplayName());
133 rConfigItem
.SetMailAddress(aConfigItem
.GetMailAddress());
134 rConfigItem
.SetMailReplyTo(aConfigItem
.GetMailReplyTo());
135 rConfigItem
.SetMailReplyTo(aConfigItem
.IsMailReplyTo());
136 rConfigItem
.SetMailServer(aConfigItem
.GetMailServer());
137 rConfigItem
.SetMailPort(aConfigItem
.GetMailPort());
138 rConfigItem
.SetSecureConnection(aConfigItem
.IsSecureConnection());
139 // authentication settings
140 rConfigItem
.SetAuthentication(aConfigItem
.IsAuthentication());
141 rConfigItem
.SetSMTPAfterPOP(aConfigItem
.IsSMTPAfterPOP());
142 rConfigItem
.SetMailUserName(aConfigItem
.GetMailUserName());
143 rConfigItem
.SetMailPassword(aConfigItem
.GetMailPassword());
144 rConfigItem
.SetInServerName(aConfigItem
.GetInServerName());
145 rConfigItem
.SetInServerPort(aConfigItem
.GetInServerPort());
146 rConfigItem
.SetInServerPOP(aConfigItem
.IsInServerPOP());
147 rConfigItem
.SetInServerUserName(aConfigItem
.GetInServerUserName());
148 rConfigItem
.SetInServerPassword(aConfigItem
.GetInServerPassword());
153 class SwSaveWarningBox_Impl
: public SwMessageAndEditDialog
155 DECL_LINK( ModifyHdl
, weld::Entry
&, void);
157 SwSaveWarningBox_Impl(weld::Window
* pParent
, const OUString
& rFileName
);
159 OUString
GetFileName() const
161 return m_xEdit
->get_text();
165 class SwSendQueryBox_Impl
: public SwMessageAndEditDialog
167 bool m_bIsEmptyAllowed
;
168 DECL_LINK( ModifyHdl
, weld::Entry
&, void);
170 SwSendQueryBox_Impl(weld::Window
* pParent
, const OUString
& rID
,
171 const OUString
& rUIXMLDescription
);
173 void SetValue(const OUString
& rSet
)
175 m_xEdit
->set_text(rSet
);
179 OUString
GetValue() const
181 return m_xEdit
->get_text();
184 void SetIsEmptyTextAllowed(bool bSet
)
186 m_bIsEmptyAllowed
= bSet
;
193 SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(weld::Window
* pParent
, const OUString
& rFileName
)
194 : SwMessageAndEditDialog(pParent
, "AlreadyExistsDialog",
195 "modules/swriter/ui/alreadyexistsdialog.ui")
197 m_xEdit
->set_text(rFileName
);
198 m_xEdit
->connect_changed(LINK(this, SwSaveWarningBox_Impl
, ModifyHdl
));
200 INetURLObject
aTmp(rFileName
);
201 m_xDialog
->set_primary_text(m_xDialog
->get_primary_text().replaceAll("%1", aTmp
.getName(
202 INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
)));
207 IMPL_LINK( SwSaveWarningBox_Impl
, ModifyHdl
, weld::Entry
&, rEdit
, void)
209 m_xOKPB
->set_sensitive(!rEdit
.get_text().isEmpty());
212 SwSendQueryBox_Impl::SwSendQueryBox_Impl(weld::Window
* pParent
, const OUString
& rID
,
213 const OUString
& rUIXMLDescription
)
214 : SwMessageAndEditDialog(pParent
, rID
, rUIXMLDescription
)
215 , m_bIsEmptyAllowed(true)
217 m_xEdit
->connect_changed(LINK(this, SwSendQueryBox_Impl
, ModifyHdl
));
221 IMPL_LINK( SwSendQueryBox_Impl
, ModifyHdl
, weld::Entry
&, rEdit
, void)
223 m_xOKPB
->set_sensitive(m_bIsEmptyAllowed
|| !rEdit
.get_text().isEmpty());
228 class SwCopyToDialog
: public SfxDialogController
230 std::unique_ptr
<weld::Entry
> m_xCCED
;
231 std::unique_ptr
<weld::Entry
> m_xBCCED
;
234 explicit SwCopyToDialog(weld::Window
* pParent
)
235 : SfxDialogController(pParent
, "modules/swriter/ui/ccdialog.ui", "CCDialog")
236 , m_xCCED(m_xBuilder
->weld_entry("cc"))
237 , m_xBCCED(m_xBuilder
->weld_entry("bcc"))
241 OUString
GetCC() const {return m_xCCED
->get_text();}
242 void SetCC(const OUString
& rSet
) {m_xCCED
->set_text(rSet
);}
244 OUString
GetBCC() const {return m_xBCCED
->get_text();}
245 void SetBCC(const OUString
& rSet
) {m_xBCCED
->set_text(rSet
);}
250 SwMMResultSaveDialog::SwMMResultSaveDialog(weld::Window
* pParent
)
251 : SfxDialogController(pParent
, "modules/swriter/ui/mmresultsavedialog.ui", "MMResultSaveDialog")
252 , m_bCancelSaving(false)
253 , m_xSaveAsOneRB(m_xBuilder
->weld_radio_button("singlerb"))
254 , m_xSaveIndividualRB(m_xBuilder
->weld_radio_button("individualrb"))
255 , m_xFromRB(m_xBuilder
->weld_check_button("fromrb"))
256 , m_xFromNF(m_xBuilder
->weld_spin_button("from"))
257 , m_xToFT(m_xBuilder
->weld_label("toft"))
258 , m_xToNF(m_xBuilder
->weld_spin_button("to"))
259 , m_xOKButton(m_xBuilder
->weld_button("ok"))
261 Link
<weld::Toggleable
&,void> aLink
= LINK(this, SwMMResultSaveDialog
, DocumentSelectionHdl_Impl
);
262 m_xSaveAsOneRB
->connect_toggled(aLink
);
263 m_xSaveIndividualRB
->connect_toggled(aLink
);
264 m_xFromRB
->connect_toggled(aLink
);
265 // m_pSaveAsOneRB is the default, so disable m_xFromNF and m_xToNF initially.
266 aLink
.Call(*m_xSaveAsOneRB
);
267 if (SwView
* pView
= GetActiveView())
269 const std::shared_ptr
<SwMailMergeConfigItem
>& xConfigItem
= pView
->GetMailMergeConfigItem();
271 sal_Int32 nCount
= xConfigItem
->GetMergedDocumentCount();
272 m_xFromNF
->set_max(nCount
);
273 m_xToNF
->set_max(nCount
);
274 m_xToNF
->set_value(nCount
);
277 m_xOKButton
->connect_clicked(LINK(this, SwMMResultSaveDialog
, SaveOutputHdl_Impl
));
280 SwMMResultSaveDialog::~SwMMResultSaveDialog()
284 SwMMResultPrintDialog::SwMMResultPrintDialog(weld::Window
* pParent
)
285 : SfxDialogController(pParent
, "modules/swriter/ui/mmresultprintdialog.ui", "MMResultPrintDialog")
286 , m_xPrinterLB(m_xBuilder
->weld_combo_box("printers"))
287 , m_xPrinterSettingsPB(m_xBuilder
->weld_button("printersettings"))
288 , m_xPrintAllRB(m_xBuilder
->weld_radio_button("printallrb"))
289 , m_xFromRB(m_xBuilder
->weld_radio_button("fromrb"))
290 , m_xFromNF(m_xBuilder
->weld_spin_button("from"))
291 , m_xToFT(m_xBuilder
->weld_label("toft"))
292 , m_xToNF(m_xBuilder
->weld_spin_button("to"))
293 , m_xOKButton(m_xBuilder
->weld_button("ok"))
295 m_xPrinterLB
->make_sorted();
297 m_xPrinterLB
->connect_changed(LINK(this, SwMMResultPrintDialog
, PrinterChangeHdl_Impl
));
298 m_xPrinterSettingsPB
->connect_clicked(LINK(this, SwMMResultPrintDialog
, PrinterSetupHdl_Impl
));
300 Link
<weld::Toggleable
&,void> aLink
= LINK(this, SwMMResultPrintDialog
, DocumentSelectionHdl_Impl
);
301 m_xPrintAllRB
->connect_toggled(aLink
);
302 m_xFromRB
->connect_toggled(aLink
);
303 // m_pPrintAllRB is the default, so disable m_xFromNF and m_xToNF initially.
304 aLink
.Call(*m_xPrintAllRB
);
306 m_xOKButton
->connect_clicked(LINK(this, SwMMResultPrintDialog
, PrintHdl_Impl
));
308 FillInPrinterSettings();
311 SwMMResultPrintDialog::~SwMMResultPrintDialog()
315 SwMMResultEmailDialog::SwMMResultEmailDialog(weld::Window
* pParent
)
316 : SfxDialogController(pParent
, "modules/swriter/ui/mmresultemaildialog.ui", "MMResultEmailDialog")
317 , m_sConfigureMail(SwResId(ST_CONFIGUREMAIL
))
318 , m_xMailToLB(m_xBuilder
->weld_combo_box("mailto"))
319 , m_xCopyToPB(m_xBuilder
->weld_button("copyto"))
320 , m_xSubjectED(m_xBuilder
->weld_entry("subject"))
321 , m_xSendAsLB(m_xBuilder
->weld_combo_box("sendas"))
322 , m_xSendAsPB(m_xBuilder
->weld_button("sendassettings"))
323 , m_xAttachmentGroup(m_xBuilder
->weld_widget("attachgroup"))
324 , m_xAttachmentED(m_xBuilder
->weld_entry("attach"))
325 , m_xPasswordFT(m_xBuilder
->weld_label("passwordft"))
326 , m_xPasswordLB(m_xBuilder
->weld_combo_box("password"))
327 , m_xPasswordCB(m_xBuilder
->weld_check_button("passwordcb"))
328 , m_xSendAllRB(m_xBuilder
->weld_radio_button("sendallrb"))
329 , m_xFromRB(m_xBuilder
->weld_radio_button("fromrb"))
330 , m_xFromNF(m_xBuilder
->weld_spin_button("from"))
331 , m_xToFT(m_xBuilder
->weld_label("toft"))
332 , m_xToNF(m_xBuilder
->weld_spin_button("to"))
333 , m_xOKButton(m_xBuilder
->weld_button("ok"))
335 m_xCopyToPB
->connect_clicked(LINK(this, SwMMResultEmailDialog
, CopyToHdl_Impl
));
336 m_xSendAsPB
->connect_clicked(LINK(this, SwMMResultEmailDialog
, SendAsHdl_Impl
));
337 m_xSendAsLB
->connect_changed(LINK(this, SwMMResultEmailDialog
, SendTypeHdl_Impl
));
338 m_xPasswordCB
->connect_toggled( LINK( this, SwMMResultEmailDialog
, CheckHdl
));
340 Link
<weld::Toggleable
&,void> aLink
= LINK(this, SwMMResultEmailDialog
, DocumentSelectionHdl_Impl
);
341 m_xSendAllRB
->connect_toggled(aLink
);
342 m_xFromRB
->connect_toggled(aLink
);
343 // m_xSendAllRB is the default, so disable m_xFromNF and m_xToNF initially.
344 aLink
.Call(*m_xSendAllRB
);
346 m_xOKButton
->connect_clicked(LINK(this, SwMMResultEmailDialog
, SendDocumentsHdl_Impl
));
348 m_xPasswordCB
->set_sensitive(false);
349 m_xPasswordFT
->set_sensitive(false);
350 m_xPasswordLB
->set_sensitive(false);
352 FillInEmailSettings();
355 SwMMResultEmailDialog::~SwMMResultEmailDialog()
359 void SwMMResultPrintDialog::FillInPrinterSettings()
361 //fill printer ListBox
362 SwView
* pView
= GetActiveView();
365 const std::shared_ptr
<SwMailMergeConfigItem
>& xConfigItem
= pView
->GetMailMergeConfigItem();
366 const std::vector
<OUString
>& rPrinters
= Printer::GetPrinterQueues();
367 unsigned int nCount
= rPrinters
.size();
368 bool bMergePrinterExists
= false;
370 for (unsigned int i
= 0; i
< nCount
; ++i
)
372 m_xPrinterLB
->append_text( rPrinters
[i
] );
373 if( !bMergePrinterExists
&& rPrinters
[i
] == xConfigItem
->GetSelectedPrinter() )
374 bMergePrinterExists
= true;
378 if(!bMergePrinterExists
)
380 SfxPrinter
* pPrinter
= pView
->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
381 m_xPrinterLB
->set_active_text(pPrinter
->GetName());
385 m_xPrinterLB
->set_active_text(xConfigItem
->GetSelectedPrinter());
387 PrinterChangeHdl_Impl(*m_xPrinterLB
);
389 sal_Int32 count
= xConfigItem
->GetMergedDocumentCount();
390 m_xFromNF
->set_max(count
);
391 m_xToNF
->set_value(count
);
392 m_xToNF
->set_max(count
);
395 void SwMMResultEmailDialog::FillInEmailSettings()
397 SwView
* pView
= GetActiveView();
400 const std::shared_ptr
<SwMailMergeConfigItem
>& xConfigItem
= pView
->GetMailMergeConfigItem();
403 SwView
* pSourceView
= xConfigItem
->GetSourceView();
404 OSL_ENSURE(pSourceView
, "no source view exists");
407 SwDocShell
* pDocShell
= pSourceView
->GetDocShell();
408 if (pDocShell
->HasName())
410 INetURLObject
aTmp(pDocShell
->GetMedium()->GetName());
411 m_xAttachmentED
->set_text(aTmp
.getName(
412 INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
));
416 if (m_xAttachmentED
->get_text().isEmpty())
418 OUString sAttach
= "." + lcl_GetExtensionForDocType(m_xSendAsLB
->get_active_id().toUInt32());
419 m_xAttachmentED
->set_text(sAttach
);
423 //select first column
424 uno::Reference
< sdbcx::XColumnsSupplier
> xColsSupp(xConfigItem
->GetResultSet(), uno::UNO_QUERY
);
425 //get the name of the actual columns
426 uno::Reference
< container::XNameAccess
> xColAccess
= xColsSupp
.is() ? xColsSupp
->getColumns() : nullptr;
427 uno::Sequence
< OUString
> aFields
;
429 aFields
= xColAccess
->getElementNames();
431 // fill mail address and password ListBox
432 assert(m_xMailToLB
->get_count() == 0);
433 assert(m_xPasswordLB
->get_count() == 0);
434 for (const OUString
& rField
: std::as_const(aFields
))
436 m_xMailToLB
->append_text(rField
);
437 m_xPasswordLB
->append_text(rField
);
440 m_xMailToLB
->set_active(0);
441 m_xPasswordLB
->set_active(0);
443 // then select the right one - may not be available
444 const std::vector
<std::pair
<OUString
, int>>& rHeaders
= xConfigItem
->GetDefaultAddressHeaders();
445 OUString sEMailColumn
= rHeaders
[MM_PART_E_MAIL
].first
;
446 Sequence
< OUString
> aAssignment
= xConfigItem
->GetColumnAssignment(xConfigItem
->GetCurrentDBData());
447 if (aAssignment
.getLength() > MM_PART_E_MAIL
&& !aAssignment
[MM_PART_E_MAIL
].isEmpty())
448 sEMailColumn
= aAssignment
[MM_PART_E_MAIL
];
449 if (int pos
= m_xMailToLB
->find_text(sEMailColumn
); pos
>= 0)
450 m_xMailToLB
->set_active(pos
);
452 // HTML format pre-selected
453 m_xSendAsLB
->set_active(3);
454 SendTypeHdl_Impl(*m_xSendAsLB
);
456 const sal_Int32 nCount
= xConfigItem
->GetMergedDocumentCount();
457 m_xFromNF
->set_max(nCount
);
458 m_xToNF
->set_max(nCount
);
459 m_xToNF
->set_value(nCount
);
462 IMPL_LINK_NOARG(SwMMResultSaveDialog
, DocumentSelectionHdl_Impl
, weld::Toggleable
&, void)
464 bool bEnableFromTo
= m_xFromRB
->get_active();
465 m_xFromNF
->set_sensitive(bEnableFromTo
);
466 m_xToFT
->set_sensitive(bEnableFromTo
);
467 m_xToNF
->set_sensitive(bEnableFromTo
);
470 IMPL_LINK_NOARG(SwMMResultEmailDialog
, CheckHdl
, weld::Toggleable
&, void)
472 bool bEnable
= m_xPasswordCB
->get_active();
474 m_xPasswordFT
->set_sensitive(bEnable
);
475 m_xPasswordLB
->set_sensitive(bEnable
);
478 IMPL_LINK_NOARG(SwMMResultPrintDialog
, DocumentSelectionHdl_Impl
, weld::Toggleable
&, void)
480 bool bEnableFromTo
= m_xFromRB
->get_active();
481 m_xFromNF
->set_sensitive(bEnableFromTo
);
482 m_xToFT
->set_sensitive(bEnableFromTo
);
483 m_xToNF
->set_sensitive(bEnableFromTo
);
486 IMPL_LINK_NOARG(SwMMResultEmailDialog
, DocumentSelectionHdl_Impl
, weld::Toggleable
&, void)
488 bool bEnableFromTo
= m_xFromRB
->get_active();
489 m_xFromNF
->set_sensitive(bEnableFromTo
);
490 m_xToFT
->set_sensitive(bEnableFromTo
);
491 m_xToNF
->set_sensitive(bEnableFromTo
);
494 IMPL_LINK_NOARG(SwMMResultEmailDialog
, CopyToHdl_Impl
, weld::Button
&, void)
496 SwCopyToDialog
aDlg(m_xDialog
.get());
499 if (aDlg
.run() == RET_OK
)
501 m_sCC
= aDlg
.GetCC() ;
502 m_sBCC
= aDlg
.GetBCC();
508 int documentStartPageNumber(SwMailMergeConfigItem
* pConfigItem
, int document
, bool bIgnoreEmpty
)
510 SwView
* pTargetView
= pConfigItem
->GetTargetView();
511 assert( pTargetView
);
512 SwCursorShell
& shell
= pTargetView
->GetWrtShell();
513 const SwDocMergeInfo
& info
= pConfigItem
->GetDocumentMergeInfo(document
);
516 shell
.GotoMark( info
.startPageInTarget
);
518 shell
.GetPageNum(page
, o3tl::temporary(sal_uInt16()));
520 page
= shell
.GetPageNumSeqNonEmpty();
521 shell
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
525 int documentEndPageNumber(SwMailMergeConfigItem
* pConfigItem
, int document
, bool bIgnoreEmpty
)
527 SwView
* pTargetView
= pConfigItem
->GetTargetView();
528 assert( pTargetView
);
529 SwWrtShell
& shell
= pTargetView
->GetWrtShell();
531 if (document
< int(pConfigItem
->GetMergedDocumentCount()) - 1)
533 // Go to the page before the starting page of the next merged document.
534 const SwDocMergeInfo
& info
= pConfigItem
->GetDocumentMergeInfo( document
+ 1 );
535 shell
.GotoMark( info
.startPageInTarget
);
539 { // This is the last merged document, so it ends on the page at which the document ends.
540 shell
.SttEndDoc( false ); // go to doc end
544 shell
.GetPageNum(page
, o3tl::temporary(sal_uInt16()));
546 page
= shell
.GetPageNumSeqNonEmpty();
547 shell
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
551 } // anonymous namespace
553 IMPL_LINK_NOARG(SwMMResultSaveDialog
, SaveOutputHdl_Impl
, weld::Button
&, void)
555 SwView
* pView
= GetActiveView();
558 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
= pView
->GetMailMergeConfigItem();
561 const sal_uInt32 nDocumentCount
= xConfigItem
->GetMergedDocumentCount();
562 sal_uInt32 nBegin
= 0;
563 sal_uInt32 nEnd
= nDocumentCount
;
565 if (m_xFromRB
->get_active())
567 nBegin
= static_cast<sal_Int32
>(m_xFromNF
->get_value() - 1);
568 nEnd
= static_cast<sal_Int32
>(m_xToNF
->get_value());
569 if (nEnd
> nDocumentCount
)
570 nEnd
= nDocumentCount
;
573 xConfigItem
->SetBeginEnd(nBegin
, nEnd
);
575 if (!xConfigItem
->GetTargetView())
576 SwDBManager::PerformMailMerge(pView
);
578 SwView
* pTargetView
= xConfigItem
->GetTargetView();
582 OUString sPath
= SwMailMergeHelper::CallSaveAsDialog(m_xDialog
.get(), sFilter
);
585 // just return back to the dialog
589 if (m_xSaveAsOneRB
->get_active())
591 uno::Sequence
< beans::PropertyValue
> aValues
{ comphelper::makePropertyValue("FilterName", sFilter
) };
593 uno::Reference
< frame::XStorable
> xStore( pTargetView
->GetDocShell()->GetModel(), uno::UNO_QUERY
);
594 ErrCode nErrorCode
= ERRCODE_NONE
;
597 xStore
->storeToURL( sPath
, aValues
);
599 catch (const task::ErrorCodeIOException
& rErrorEx
)
601 nErrorCode
= ErrCode(rErrorEx
.ErrCode
);
603 catch (const Exception
&)
605 nErrorCode
= ERRCODE_IO_GENERAL
;
607 if( nErrorCode
!= ERRCODE_NONE
)
609 SfxErrorContext
aEc(ERRCTX_SFX_SAVEASDOC
, pTargetView
->GetDocShell()->GetTitle());
610 ErrorHandler::HandleError( nErrorCode
);
615 OUString sTargetTempURL
= URIHelper::SmartRel2Abs(
616 INetURLObject(), utl::CreateTempName(),
617 URIHelper::GetMaybeFileHdl());
618 std::shared_ptr
<const SfxFilter
> pSfxFlt
= SwIoSystem::GetFilterOfFormat(
620 SwDocShell::Factory().GetFilterContainer() );
622 uno::Sequence
< beans::PropertyValue
> aValues(1);
623 beans::PropertyValue
* pValues
= aValues
.getArray();
624 pValues
[0].Name
= "FilterName";
625 pValues
[0].Value
<<= pSfxFlt
->GetFilterName();
627 uno::Reference
< frame::XStorable
> xStore( pTargetView
->GetDocShell()->GetModel(), uno::UNO_QUERY
);
628 ErrCode nErrorCode
= ERRCODE_NONE
;
631 xStore
->storeToURL( sTargetTempURL
, aValues
);
633 catch (const task::ErrorCodeIOException
& rErrorEx
)
635 nErrorCode
= ErrCode(rErrorEx
.ErrCode
);
637 catch (const Exception
&)
639 nErrorCode
= ERRCODE_IO_GENERAL
;
641 if( nErrorCode
!= ERRCODE_NONE
)
643 SfxErrorContext
aEc(ERRCTX_SFX_SAVEASDOC
, pTargetView
->GetDocShell()->GetTitle());
644 ErrorHandler::HandleError( nErrorCode
);
647 SwView
* pSourceView
= xConfigItem
->GetSourceView();
648 auto xSaveMonitor
= std::make_shared
<SaveMonitor
>(m_xDialog
.get());
649 xSaveMonitor
->m_xDocName
->set_label(pSourceView
->GetDocShell()->GetTitle(22));
650 xSaveMonitor
->m_xPrinter
->set_label( INetURLObject( sPath
).getFSysPath( FSysStyle::Detect
) );
651 m_bCancelSaving
= false;
652 weld::DialogController::runAsync(xSaveMonitor
, [this, &xSaveMonitor
](sal_Int32 nResult
){
653 if (nResult
== RET_CANCEL
)
654 m_bCancelSaving
= true;
655 xSaveMonitor
.reset();
658 for(sal_uInt32 nDoc
= 0; nDoc
< nEnd
- nBegin
&& !m_bCancelSaving
; ++nDoc
)
660 INetURLObject
aURL(sPath
);
661 OUString sExtension
= aURL
.getExtension();
662 if (sExtension
.isEmpty())
664 sExtension
= pSfxFlt
->GetWildcard().getGlob().getToken(1, '.');
665 sPath
+= "." + sExtension
;
667 OUString sStat
= SwResId(STR_STATSTR_LETTER
) + " " + OUString::number(nDoc
+ 1);
668 xSaveMonitor
->m_xPrintInfo
->set_label(sStat
);
670 //now extract a document from the target document
671 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
672 SfxObjectShellLock
xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD
) );
673 xTempDocShell
->DoInitNew();
674 SfxViewFrame
* pTempFrame
= SfxViewFrame::LoadHiddenDocument( *xTempDocShell
, SFX_INTERFACE_NONE
);
675 SwView
* pTempView
= static_cast<SwView
*>( pTempFrame
->GetViewShell() );
676 pTargetView
->GetWrtShell().StartAction();
677 SwgReaderOption aOpt
;
678 aOpt
.SetTextFormats( true );
679 aOpt
.SetFrameFormats( true );
680 aOpt
.SetPageDescs( true );
681 aOpt
.SetNumRules( true );
682 aOpt
.SetMerge( false );
683 pTempView
->GetDocShell()->LoadStylesFromFile(
684 sTargetTempURL
, aOpt
, true );
685 pTempView
->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView
->GetDocShell()->GetDoc());
686 pTempView
->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView
->GetDocShell()->GetDoc());
687 pTempView
->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView
->GetDocShell()->GetDoc(), true );
689 uno::Reference
<beans::XPropertySet
> const xThisSet(
690 pTargetView
->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW
);
691 uno::Reference
<beans::XPropertySet
> const xRetSet(
692 pTempView
->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW
);
693 uno::Sequence
<beans::PropertyValue
> aInteropGrabBag
;
694 xThisSet
->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag
;
695 xRetSet
->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag
));
697 pTargetView
->GetWrtShell().PastePages(
698 pTempView
->GetWrtShell(), documentStartPageNumber(xConfigItem
.get(), nDoc
, false),
699 documentEndPageNumber(xConfigItem
.get(), nDoc
, false));
700 pTargetView
->GetWrtShell().EndAction();
702 OUString sOutPath
= aURL
.GetMainURL(INetURLObject::DecodeMechanism::ToIUri
);
703 OUString sCounter
= "_" + OUString::number(nDoc
+ 1);
704 sOutPath
= sOutPath
.replaceAt( sOutPath
.getLength() - sExtension
.getLength() - 1, 0, sCounter
);
708 //time for other slots is needed
709 Scheduler::ProcessEventsToIdle();
711 bool bFailed
= false;
714 pValues
[0].Value
<<= sFilter
;
715 uno::Reference
< frame::XStorable
> xTempStore( xTempDocShell
->GetModel(), uno::UNO_QUERY
);
716 xTempStore
->storeToURL( sOutPath
, aValues
);
718 catch (const uno::Exception
&)
725 std::unique_ptr
<SwSaveWarningBox_Impl
> xWarning(new SwSaveWarningBox_Impl(m_xDialog
.get(), sOutPath
));
726 if (RET_OK
== xWarning
->run())
727 sOutPath
= xWarning
->GetFileName();
730 xTempDocShell
->DoClose();
731 m_xDialog
->response(RET_OK
);
737 xTempDocShell
->DoClose();
738 m_xDialog
->response(RET_OK
);
744 xSaveMonitor
->response(RET_OK
);
745 ::osl::File::remove( sTargetTempURL
);
748 m_xDialog
->response(RET_OK
);
751 IMPL_LINK(SwMMResultPrintDialog
, PrinterChangeHdl_Impl
, weld::ComboBox
&, rBox
, void)
753 SwView
* pView
= GetActiveView();
756 const std::shared_ptr
<SwMailMergeConfigItem
>& xConfigItem
= pView
->GetMailMergeConfigItem();
758 if (rBox
.get_active() != -1)
760 const QueueInfo
* pInfo
= Printer::GetQueueInfo( rBox
.get_active_text(), false );
764 if ( !m_pTempPrinter
)
766 m_pTempPrinter
= VclPtr
<Printer
>::Create( *pInfo
);
770 if( (m_pTempPrinter
->GetName() != pInfo
->GetPrinterName()) ||
771 (m_pTempPrinter
->GetDriverName() != pInfo
->GetDriver()) )
773 m_pTempPrinter
.disposeAndClear();
774 m_pTempPrinter
= VclPtr
<Printer
>::Create( *pInfo
);
778 else if( ! m_pTempPrinter
)
779 m_pTempPrinter
= VclPtr
<Printer
>::Create();
781 m_xPrinterSettingsPB
->set_sensitive(m_pTempPrinter
->HasSupport(PrinterSupport::SetupDialog
));
784 m_xPrinterSettingsPB
->set_sensitive(false);
786 xConfigItem
->SetSelectedPrinter(rBox
.get_active_text());
789 IMPL_LINK_NOARG(SwMMResultPrintDialog
, PrintHdl_Impl
, weld::Button
&, void)
791 SwView
* pView
= GetActiveView();
794 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
= pView
->GetMailMergeConfigItem();
797 const sal_uInt32 nDocumentCount
= xConfigItem
->GetMergedDocumentCount();
798 sal_uInt32 nBegin
= 0;
799 sal_uInt32 nEnd
= nDocumentCount
;
801 if (m_xFromRB
->get_active())
803 nBegin
= static_cast<sal_Int32
>(m_xFromNF
->get_value() - 1);
804 nEnd
= static_cast<sal_Int32
>(m_xToNF
->get_value());
805 if (nEnd
> nDocumentCount
)
806 nEnd
= nDocumentCount
;
809 xConfigItem
->SetBeginEnd(nBegin
, nEnd
);
811 if(!xConfigItem
->GetTargetView())
812 SwDBManager::PerformMailMerge(pView
);
814 SwView
* pTargetView
= xConfigItem
->GetTargetView();
817 // If we skip autoinserted blanks, then the page numbers used in the print range string
818 // refer to the non-blank pages as they appear in the document (see tdf#89708).
819 const bool bIgnoreEmptyPages
=
820 !pTargetView
->GetDocShell()->GetDoc()->getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages();
821 const int nStartPage
= documentStartPageNumber(xConfigItem
.get(), 0, bIgnoreEmptyPages
);
822 const int nEndPage
= documentEndPageNumber(xConfigItem
.get(), nEnd
- nBegin
- 1, bIgnoreEmptyPages
);
824 const OUString
sPages(OUString::number(nStartPage
) + "-" + OUString::number(nEndPage
));
826 pTargetView
->SetMailMergeConfigItem(xConfigItem
);
829 SfxPrinter
*const pDocumentPrinter
= pTargetView
->GetWrtShell()
830 .getIDocumentDeviceAccess().getPrinter(true);
831 pDocumentPrinter
->SetPrinterProps(m_pTempPrinter
);
832 // this should be able to handle setting its own printer
833 pTargetView
->SetPrinter(pDocumentPrinter
);
836 SfxObjectShell
* pObjSh
= pTargetView
->GetViewFrame().GetObjectShell();
837 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMerge
, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE
), pObjSh
));
839 uno::Sequence aProps
{ comphelper::makePropertyValue("MonitorVisible", true),
840 comphelper::makePropertyValue("Pages", sPages
) };
842 pTargetView
->ExecPrint( aProps
, false, true );
843 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd
, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END
), pObjSh
));
845 m_xDialog
->response(RET_OK
);
848 IMPL_LINK_NOARG(SwMMResultPrintDialog
, PrinterSetupHdl_Impl
, weld::Button
&, void)
851 m_pTempPrinter
->Setup(m_xDialog
.get());
854 IMPL_LINK(SwMMResultEmailDialog
, SendTypeHdl_Impl
, weld::ComboBox
&, rBox
, void)
856 auto nDocType
= rBox
.get_active_id().toUInt32();
857 bool bEnable
= MM_DOCTYPE_HTML
!= nDocType
&& MM_DOCTYPE_TEXT
!= nDocType
;
858 bool bIsPDF
= nDocType
== MM_DOCTYPE_PDF
;
859 m_xSendAsPB
->set_sensitive(bEnable
);
860 m_xAttachmentGroup
->set_sensitive(bEnable
);
863 //add the correct extension
864 OUString
sAttach(m_xAttachmentED
->get_text());
865 //do nothing if the user has removed the name - the warning will come early enough
866 if (!sAttach
.isEmpty())
868 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(sAttach
, '.');
874 sAttach
= comphelper::string::setToken(sAttach
, nTokenCount
- 1, '.', lcl_GetExtensionForDocType( nDocType
));
875 m_xAttachmentED
->set_text(sAttach
);
881 m_xPasswordCB
->set_sensitive(true);
882 m_xPasswordFT
->set_sensitive(true);
883 m_xPasswordLB
->set_sensitive(true);
884 CheckHdl(*m_xPasswordCB
);
888 m_xPasswordCB
->set_sensitive(false);
889 m_xPasswordFT
->set_sensitive(false);
890 m_xPasswordLB
->set_sensitive(false);
894 IMPL_LINK_NOARG(SwMMResultEmailDialog
, SendAsHdl_Impl
, weld::Button
&, void)
896 // work around crash when calling constructor with no active view
897 if (!GetActiveView())
899 SAL_WARN("sw", "ignoring SendAs button click, because no active view");
902 SwMailBodyDialog
aDlg(m_xDialog
.get());
903 aDlg
.SetBody(m_sBody
);
904 if (RET_OK
== aDlg
.run())
906 m_sBody
= aDlg
.GetBody();
910 // Send documents as e-mail
911 IMPL_LINK_NOARG(SwMMResultEmailDialog
, SendDocumentsHdl_Impl
, weld::Button
&, void)
913 SwView
* pView
= GetActiveView();
916 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
= pView
->GetMailMergeConfigItem();
919 const sal_uInt32 nDocumentCount
= xConfigItem
->GetMergedDocumentCount();
920 sal_uInt32 nBegin
= 0;
921 sal_uInt32 nEnd
= nDocumentCount
;
923 if (m_xFromRB
->get_active())
925 nBegin
= static_cast<sal_Int32
>(m_xFromNF
->get_value() - 1);
926 nEnd
= static_cast<sal_Int32
>(m_xToNF
->get_value());
927 if (nEnd
> nDocumentCount
)
928 nEnd
= nDocumentCount
;
931 xConfigItem
->SetBeginEnd(nBegin
, nEnd
);
933 if (!xConfigItem
->GetTargetView())
934 SwDBManager::PerformMailMerge(pView
);
936 //get the composed document
937 SwView
* pTargetView
= xConfigItem
->GetTargetView();
938 SAL_WARN_IF(!pTargetView
, "sw.ui", "No TargetView in SwMailMergeConfigItem");
940 if (xConfigItem
->GetMailServer().isEmpty() ||
941 !SwMailMergeHelper::CheckMailAddress(xConfigItem
->GetMailAddress()) )
943 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(m_xDialog
.get(),
944 VclMessageType::Question
, VclButtonsType::YesNo
,
946 xQueryBox
->add_button(GetStandardText(StandardButtonType::Cancel
), RET_CANCEL
);
947 sal_uInt16 nRet
= xQueryBox
->run();
948 if (RET_YES
== nRet
)
950 SwView
* pConfigView
= pTargetView
? pTargetView
: pView
;
951 SfxAllItemSet
aSet(pConfigView
->GetPool());
952 SwMailConfigDlg
aDlg(m_xDialog
.get(), aSet
);
956 if(nRet
!= RET_OK
&& nRet
!= RET_YES
)
957 return; // back to the dialog
959 // SwMailConfigDlg writes mail merge email settings only to (global) config,
960 // so copy them to the existing config item
961 lcl_UpdateEmailSettingsFromGlobalConfig(*xConfigItem
);
964 bool bAsBody
= false;
965 rtl_TextEncoding eEncoding
= ::osl_getThreadTextEncoding();
966 SfxFilterContainer
* pFilterContainer
= SwDocShell::Factory().GetFilterContainer();
967 std::shared_ptr
<const SfxFilter
> pSfxFlt
;
968 auto nDocType
= m_xSendAsLB
->get_active_id().toUInt32();
969 OUString sExtension
= lcl_GetExtensionForDocType(nDocType
);
974 //Make sure we don't pick e.g. the flat xml filter
976 pSfxFlt
= pFilterContainer
->GetFilter4FilterName(
978 SfxFilterFlags::EXPORT
);
983 pSfxFlt
= pFilterContainer
->GetFilter4FilterName(
985 SfxFilterFlags::EXPORT
);
988 case MM_DOCTYPE_WORD
:
990 //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
991 //because it uses the same user data :-(
992 SfxFilterMatcher
aMatcher( pFilterContainer
->GetName() );
993 SfxFilterMatcherIter
aIter( aMatcher
);
994 std::shared_ptr
<const SfxFilter
> pFilter
= aIter
.First();
997 if( pFilter
->GetUserData() == FILTER_WW8
&& pFilter
->CanExport() )
1002 pFilter
= aIter
.Next();
1007 case MM_DOCTYPE_HTML
:
1010 eEncoding
= RTL_TEXTENCODING_UTF8
;
1013 case MM_DOCTYPE_TEXT
:
1016 pSfxFlt
= pFilterContainer
->GetFilter4FilterName(
1017 "Text (encoded)", SfxFilterFlags::EXPORT
);
1022 pSfxFlt
= pFilterContainer
->GetFilter4Extension(sExtension
, SfxFilterFlags::EXPORT
);
1026 m_xDialog
->response(RET_OK
);
1029 OUString sMimeType
= pSfxFlt
->GetMimeType();
1031 if (m_xSubjectED
->get_text().isEmpty())
1033 std::unique_ptr
<SwSendQueryBox_Impl
> xQuery(new SwSendQueryBox_Impl(m_xDialog
.get(), "SubjectDialog",
1034 "modules/swriter/ui/subjectdialog.ui"));
1035 xQuery
->SetIsEmptyTextAllowed(true);
1036 xQuery
->SetValue("");
1037 if(RET_OK
== xQuery
->run())
1039 if (!xQuery
->GetValue().isEmpty())
1040 m_xSubjectED
->set_text(xQuery
->GetValue());
1043 return; // back to the dialog
1045 if(!bAsBody
&& m_xAttachmentED
->get_text().isEmpty())
1047 std::unique_ptr
<SwSendQueryBox_Impl
> xQuery(new SwSendQueryBox_Impl(m_xDialog
.get(), "AttachNameDialog",
1048 "modules/swriter/ui/attachnamedialog.ui"));
1049 xQuery
->SetIsEmptyTextAllowed(false);
1050 if (RET_OK
== xQuery
->run())
1052 OUString
sAttach(xQuery
->GetValue());
1053 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(sAttach
, '.');
1054 if (2 > nTokenCount
)
1059 sAttach
= comphelper::string::setToken(sAttach
, nTokenCount
- 1, '.', lcl_GetExtensionForDocType(
1060 m_xSendAsLB
->get_active_id().toUInt32()));
1061 m_xAttachmentED
->set_text(sAttach
);
1064 return; // back to the dialog
1067 OUString sEMailColumn
= m_xMailToLB
->get_active_text();
1068 OSL_ENSURE( !sEMailColumn
.isEmpty(), "No email column selected");
1069 Reference
< sdbcx::XColumnsSupplier
> xColsSupp( xConfigItem
->GetResultSet(), UNO_QUERY
);
1070 Reference
< container::XNameAccess
> xColAccess
= xColsSupp
.is() ? xColsSupp
->getColumns() : nullptr;
1071 if(sEMailColumn
.isEmpty() || !xColAccess
.is() || !xColAccess
->hasByName(sEMailColumn
))
1073 m_xDialog
->response(RET_OK
);
1077 OUString sPasswordColumn
= m_xPasswordLB
->get_active_text();
1078 OSL_ENSURE( !sPasswordColumn
.isEmpty(), "No password column selected");
1079 if(sPasswordColumn
.isEmpty() || !xColAccess
.is() || !xColAccess
->hasByName(sPasswordColumn
))
1081 m_xDialog
->response(RET_OK
);
1085 OUString sFilterOptions
;
1086 if(MM_DOCTYPE_TEXT
== nDocType
)
1088 SwAsciiOptions aOpt
;
1089 sal_uInt16 nAppScriptType
= SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
1090 sal_uInt16 nWhich
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, nAppScriptType
);
1091 aOpt
.SetLanguage( static_cast<const SvxLanguageItem
&>(pTargetView
->GetWrtShell().
1092 GetDefault( nWhich
)).GetLanguage());
1093 aOpt
.SetParaFlags( LINEEND_CR
);
1094 aOpt
.WriteUserData( sFilterOptions
);
1096 else if(MM_DOCTYPE_HTML
== nDocType
)
1098 sFilterOptions
= "EmbedImages";
1100 OUString sTargetTempURL
= URIHelper::SmartRel2Abs(
1101 INetURLObject(), utl::CreateTempName(),
1102 URIHelper::GetMaybeFileHdl());
1103 std::shared_ptr
<const SfxFilter
> pTargetSfxFlt
= SwIoSystem::GetFilterOfFormat(
1105 SwDocShell::Factory().GetFilterContainer() );
1107 uno::Sequence
< beans::PropertyValue
> aValues
{ comphelper::makePropertyValue("FilterName", pTargetSfxFlt
->GetFilterName()) };
1109 uno::Reference
< frame::XStorable
> xStore( pTargetView
->GetDocShell()->GetModel(), uno::UNO_QUERY
);
1110 xStore
->storeToURL( sTargetTempURL
, aValues
);
1112 //create the send dialog
1113 std::shared_ptr
<SwSendMailDialog
> xDlg
= std::make_shared
<SwSendMailDialog
>(Application::GetDefDialogParent(), *xConfigItem
);
1115 xDlg
->StartSend(nEnd
- nBegin
);
1116 weld::DialogController::runAsync(xDlg
, [](sal_Int32
/*nResult*/){});
1118 //help to force painting the dialog
1120 //predetermined breaking point
1121 Application::Reschedule( true );
1122 m_xDialog
->response(RET_OK
);
1123 for(sal_uInt32 nDoc
= 0; nDoc
< nEnd
- nBegin
; ++nDoc
)
1125 SwDocMergeInfo
& rInfo
= xConfigItem
->GetDocumentMergeInfo(nDoc
);
1127 //now extract a document from the target document
1128 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
1129 SfxObjectShellLock
xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD
) );
1130 xTempDocShell
->DoInitNew();
1131 SfxViewFrame
* pTempFrame
= SfxViewFrame::LoadHiddenDocument( *xTempDocShell
, SFX_INTERFACE_NONE
);
1132 SwView
* pTempView
= static_cast<SwView
*>( pTempFrame
->GetViewShell() );
1133 pTargetView
->GetWrtShell().StartAction();
1134 SwgReaderOption aOpt
;
1135 aOpt
.SetTextFormats( true );
1136 aOpt
.SetFrameFormats( true );
1137 aOpt
.SetPageDescs( true );
1138 aOpt
.SetNumRules( true );
1139 aOpt
.SetMerge( false );
1140 pTempView
->GetDocShell()->LoadStylesFromFile(
1141 sTargetTempURL
, aOpt
, true );
1142 pTempView
->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView
->GetDocShell()->GetDoc());
1143 pTempView
->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView
->GetDocShell()->GetDoc());
1144 pTempView
->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView
->GetDocShell()->GetDoc(), true );
1145 pTargetView
->GetWrtShell().PastePages(
1146 pTempView
->GetWrtShell(), documentStartPageNumber(xConfigItem
.get(), nDoc
, false),
1147 documentEndPageNumber(xConfigItem
.get(), nDoc
, false));
1148 pTargetView
->GetWrtShell().EndAction();
1151 SfxStringItem
aName(SID_FILE_NAME
,
1152 URIHelper::SmartRel2Abs(
1153 INetURLObject(), utl::CreateTempName(),
1154 URIHelper::GetMaybeFileHdl()) );
1157 bool withFilterOptions
= MM_DOCTYPE_TEXT
== nDocType
|| MM_DOCTYPE_HTML
== nDocType
;
1158 bool withPasswordOptions
= m_xPasswordCB
->get_active();
1160 sal_Int32 nTarget
= xConfigItem
->MoveResultSet(rInfo
.nDBRow
);
1161 OSL_ENSURE( nTarget
== rInfo
.nDBRow
, "row of current document could not be selected");
1162 OUString sPassword
= lcl_GetColumnValueOf(sPasswordColumn
, xColAccess
);
1164 sal_Int32 nOptionCount
= (withFilterOptions
&& withPasswordOptions
) ? 4 : withPasswordOptions
? 3 : withFilterOptions
? 2 : 1;
1166 uno::Sequence
< beans::PropertyValue
> aFilterValues(nOptionCount
);
1167 beans::PropertyValue
* pFilterValues
= aFilterValues
.getArray();
1169 pFilterValues
[nOpt
].Name
= "FilterName";
1170 pFilterValues
[nOpt
].Value
<<= pSfxFlt
->GetFilterName();
1172 if(withFilterOptions
)
1175 pFilterValues
[nOpt
].Name
= "FilterOptions";
1176 pFilterValues
[nOpt
].Value
<<= sFilterOptions
;
1179 if(withPasswordOptions
)
1182 pFilterValues
[nOpt
].Name
= "EncryptFile";
1183 pFilterValues
[nOpt
].Value
<<= true;
1185 pFilterValues
[nOpt
].Name
= "DocumentOpenPassword";
1186 pFilterValues
[nOpt
].Value
<<= sPassword
;
1189 uno::Reference
< frame::XStorable
> xTempStore( pTempView
->GetDocShell()->GetModel(), uno::UNO_QUERY
);
1190 xTempStore
->storeToURL( aName
.GetValue(), aFilterValues
);
1192 xTempDocShell
->DoClose();
1194 sal_Int32 nTarget
= xConfigItem
->MoveResultSet(rInfo
.nDBRow
);
1195 OSL_ENSURE( nTarget
== rInfo
.nDBRow
, "row of current document could not be selected");
1196 OSL_ENSURE( !sEMailColumn
.isEmpty(), "No email column selected");
1197 OUString sEMail
= lcl_GetColumnValueOf(sEMailColumn
, xColAccess
);
1198 SwMailDescriptor aDesc
;
1199 aDesc
.sEMail
= sEMail
;
1200 OUStringBuffer sBody
;
1204 //read in the temporary file and use it as mail body
1205 SfxMedium
aMedium( aName
.GetValue(), StreamMode::READ
);
1206 SvStream
* pInStream
= aMedium
.GetInStream();
1208 pInStream
->SetStreamCharSet( eEncoding
);
1211 OSL_FAIL("no output file created?");
1214 OStringBuffer sLine
;
1215 bool bDone
= pInStream
->ReadLine( sLine
);
1218 sBody
.append( OStringToOUString(sLine
, eEncoding
) + "\n");
1219 bDone
= pInStream
->ReadLine( sLine
);
1222 //remove the temporary file
1223 SWUnoHelper::UCB_DeleteFile( aName
.GetValue() );
1228 aDesc
.sAttachmentURL
= aName
.GetValue();
1229 OUString
sAttachment(m_xAttachmentED
->get_text());
1230 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(sAttachment
, '.');
1231 if (2 > nTokenCount
)
1234 sAttachment
= comphelper::string::setToken(sAttachment
, nTokenCount
, '.', sExtension
);
1236 else if (o3tl::getToken(sAttachment
, nTokenCount
- 1, '.') != sExtension
)
1237 sAttachment
+= sExtension
;
1238 aDesc
.sAttachmentName
= sAttachment
;
1239 aDesc
.sMimeType
= sMimeType
;
1241 if (xConfigItem
->IsGreetingLine(true))
1243 OUString sNameColumn
= xConfigItem
->GetAssignedColumn(MM_PART_LASTNAME
);
1244 OUString sName
= lcl_GetColumnValueOf(sNameColumn
, xColAccess
);
1246 if(!sName
.isEmpty() && xConfigItem
->IsIndividualGreeting(true))
1248 OUString sGenderColumn
= xConfigItem
->GetAssignedColumn(MM_PART_GENDER
);
1249 const OUString
& sFemaleValue
= xConfigItem
->GetFemaleGenderValue();
1250 OUString sGenderValue
= lcl_GetColumnValueOf(sGenderColumn
, xColAccess
);
1251 SwMailMergeConfigItem::Gender eGenderType
= sGenderValue
== sFemaleValue
?
1252 SwMailMergeConfigItem::FEMALE
:
1253 SwMailMergeConfigItem::MALE
;
1255 sGreeting
= SwAddressPreview::FillData(
1256 xConfigItem
->GetGreetings(eGenderType
)
1257 [xConfigItem
->GetCurrentGreeting(eGenderType
)],
1263 xConfigItem
->GetGreetings(SwMailMergeConfigItem::NEUTRAL
)
1264 [xConfigItem
->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL
)];
1268 sBody
.insert(0, sGreeting
);
1271 aDesc
.sBodyContent
= sBody
.makeStringAndClear();
1272 if(MM_DOCTYPE_HTML
== nDocType
)
1274 aDesc
.sBodyMimeType
= "text/html; charset=" +
1275 OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding
));
1278 aDesc
.sBodyMimeType
= "text/plain; charset=UTF-8; format=flowed";
1280 aDesc
.sSubject
= m_xSubjectED
->get_text();
1282 aDesc
.sBCC
= m_sBCC
;
1283 xDlg
->AddDocument( aDesc
);
1284 //help to force painting the dialog
1285 Application::Reschedule( true );
1286 //stop creating of data when dialog has been closed
1287 if (!xDlg
->getDialog()->get_visible())
1292 xDlg
->EnableDestruction();
1293 ::osl::File::remove( sTargetTempURL
);
1296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */