android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / dbui / mmresultdialogs.cxx
blob55e6d3ed899c6bc206b32a6561ce47b7217b2452
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
26 #include <cmdid.h>
27 #include <swtypes.hxx>
28 #include <view.hxx>
29 #include <wrtsh.hxx>
30 #include <docsh.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>
63 #include <dbmgr.hxx>
64 #include <swunohelper.hxx>
65 #include <shellio.hxx>
66 #include <svtools/htmlcfg.hxx>
67 #include <sfx2/event.hxx>
68 #include <swevent.hxx>
69 #include <dbui.hxx>
70 #include <dbui.hrc>
71 #include <doc.hxx>
72 #include <sfx2/app.hxx>
73 #include <strings.hrc>
74 #include <comphelper/propertyvalue.hxx>
75 #include <comphelper/string.hxx>
76 #include <iodetect.hxx>
78 using namespace svt;
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)
90 OUString sExtension;
91 switch( 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;
99 return sExtension;
102 static OUString lcl_GetColumnValueOf(const OUString& rColumn, Reference < container::XNameAccess> const & rxColAccess )
104 OUString sRet;
107 if (rxColAccess->hasByName(rColumn))
109 Any aCol = rxColAccess->getByName(rColumn);
110 Reference< sdb::XColumn > xColumn;
111 aCol >>= xColumn;
112 if(xColumn.is())
113 sRet = xColumn->getString();
116 catch (const uno::Exception&)
119 return sRet;
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());
151 namespace {
153 class SwSaveWarningBox_Impl : public SwMessageAndEditDialog
155 DECL_LINK( ModifyHdl, weld::Entry&, void);
156 public:
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);
169 public:
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);
176 ModifyHdl(*m_xEdit);
179 OUString GetValue() const
181 return m_xEdit->get_text();
184 void SetIsEmptyTextAllowed(bool bSet)
186 m_bIsEmptyAllowed = bSet;
187 ModifyHdl(*m_xEdit);
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)));
204 ModifyHdl(*m_xEdit);
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));
218 ModifyHdl(*m_xEdit);
221 IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)
223 m_xOKPB->set_sensitive(m_bIsEmptyAllowed || !rEdit.get_text().isEmpty());
226 namespace {
228 class SwCopyToDialog : public SfxDialogController
230 std::unique_ptr<weld::Entry> m_xCCED;
231 std::unique_ptr<weld::Entry> m_xBCCED;
233 public:
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();
270 assert(xConfigItem);
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();
363 if (!pView)
364 return;
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;
377 assert(xConfigItem);
378 if(!bMergePrinterExists)
380 SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
381 m_xPrinterLB->set_active_text(pPrinter->GetName());
383 else
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();
398 if (!pView)
399 return;
400 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
401 assert(xConfigItem);
403 SwView* pSourceView = xConfigItem->GetSourceView();
404 OSL_ENSURE(pSourceView, "no source view exists");
405 if (pSourceView)
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;
428 if (xColAccess.is())
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());
497 aDlg.SetCC(m_sCC );
498 aDlg.SetBCC(m_sBCC);
499 if (aDlg.run() == RET_OK)
501 m_sCC = aDlg.GetCC() ;
502 m_sBCC = aDlg.GetBCC();
506 namespace {
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);
514 sal_uInt16 page;
515 shell.Push();
516 shell.GotoMark( info.startPageInTarget );
517 if (!bIgnoreEmpty)
518 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
519 else
520 page = shell.GetPageNumSeqNonEmpty();
521 shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
522 return page;
525 int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
527 SwView* pTargetView = pConfigItem->GetTargetView();
528 assert( pTargetView );
529 SwWrtShell& shell = pTargetView->GetWrtShell();
530 shell.Push();
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 );
536 shell.EndPrvPg();
538 else
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
542 sal_uInt16 page;
543 if (!bIgnoreEmpty)
544 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
545 else
546 page = shell.GetPageNumSeqNonEmpty();
547 shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
548 return page;
551 } // anonymous namespace
553 IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void)
555 SwView* pView = GetActiveView();
556 if (!pView)
557 return;
558 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
559 assert(xConfigItem);
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();
579 assert(pTargetView);
581 OUString sFilter;
582 OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
583 if (sPath.isEmpty())
585 // just return back to the dialog
586 return;
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 );
613 else
615 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
616 INetURLObject(), utl::CreateTempName(),
617 URIHelper::GetMaybeFileHdl());
618 std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
619 FILTER_XML,
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();
701 //then save it
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);
706 while(true)
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&)
720 bFailed = true;
723 if(bFailed)
725 std::unique_ptr<SwSaveWarningBox_Impl> xWarning(new SwSaveWarningBox_Impl(m_xDialog.get(), sOutPath));
726 if (RET_OK == xWarning->run())
727 sOutPath = xWarning->GetFileName();
728 else
730 xTempDocShell->DoClose();
731 m_xDialog->response(RET_OK);
732 return;
735 else
737 xTempDocShell->DoClose();
738 m_xDialog->response(RET_OK);
739 break;
743 if (xSaveMonitor)
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();
754 if (!pView)
755 return;
756 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
757 assert(xConfigItem);
758 if (rBox.get_active() != -1)
760 const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false );
762 if( pInfo )
764 if ( !m_pTempPrinter )
766 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
768 else
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));
783 else
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();
792 if (!pView)
793 return;
794 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
795 assert(xConfigItem);
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();
815 assert(pTargetView);
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);
827 if(m_pTempPrinter)
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)
850 if (m_pTempPrinter)
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);
861 if(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, '.');
869 if( 2 > nTokenCount)
871 sAttach += ".";
872 ++nTokenCount;
874 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
875 m_xAttachmentED->set_text(sAttach);
879 if(bIsPDF)
881 m_xPasswordCB->set_sensitive(true);
882 m_xPasswordFT->set_sensitive(true);
883 m_xPasswordLB->set_sensitive(true);
884 CheckHdl(*m_xPasswordCB);
886 else
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");
900 return;
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();
914 if (!pView)
915 return;
916 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
917 assert(xConfigItem);
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,
945 m_sConfigureMail));
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);
953 nRet = aDlg.run();
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);
963 //add the documents
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);
970 switch( nDocType )
972 case MM_DOCTYPE_OOO:
974 //Make sure we don't pick e.g. the flat xml filter
975 //for this format
976 pSfxFlt = pFilterContainer->GetFilter4FilterName(
977 "writer8",
978 SfxFilterFlags::EXPORT);
980 break;
981 case MM_DOCTYPE_PDF:
983 pSfxFlt = pFilterContainer->GetFilter4FilterName(
984 "writer_pdf_Export",
985 SfxFilterFlags::EXPORT);
987 break;
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();
995 while ( pFilter )
997 if( pFilter->GetUserData() == FILTER_WW8 && pFilter->CanExport() )
999 pSfxFlt = pFilter;
1000 break;
1002 pFilter = aIter.Next();
1006 break;
1007 case MM_DOCTYPE_HTML:
1009 bAsBody = true;
1010 eEncoding = RTL_TEXTENCODING_UTF8;
1012 break;
1013 case MM_DOCTYPE_TEXT:
1015 bAsBody = true;
1016 pSfxFlt = pFilterContainer->GetFilter4FilterName(
1017 "Text (encoded)", SfxFilterFlags::EXPORT);
1019 break;
1021 if(!pSfxFlt)
1022 pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
1024 if(!pSfxFlt)
1026 m_xDialog->response(RET_OK);
1027 return;
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());
1042 else
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)
1056 sAttach += ".";
1057 ++nTokenCount;
1059 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType(
1060 m_xSendAsLB->get_active_id().toUInt32()));
1061 m_xAttachmentED->set_text(sAttach);
1063 else
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);
1074 return;
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);
1082 return;
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(
1104 FILTER_XML,
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
1119 //TODO/CLEANUP
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();
1150 //then save it
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;
1165 sal_Int32 nOpt = 0;
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)
1174 nOpt++;
1175 pFilterValues[nOpt].Name = "FilterOptions";
1176 pFilterValues[nOpt].Value <<= sFilterOptions;
1179 if(withPasswordOptions)
1181 nOpt++;
1182 pFilterValues[nOpt].Name = "EncryptFile";
1183 pFilterValues[nOpt].Value <<= true;
1184 nOpt++;
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;
1201 if(bAsBody)
1204 //read in the temporary file and use it as mail body
1205 SfxMedium aMedium( aName.GetValue(), StreamMode::READ);
1206 SvStream* pInStream = aMedium.GetInStream();
1207 if(pInStream)
1208 pInStream->SetStreamCharSet( eEncoding );
1209 else
1211 OSL_FAIL("no output file created?");
1212 continue;
1214 OStringBuffer sLine;
1215 bool bDone = pInStream->ReadLine( sLine );
1216 while ( bDone )
1218 sBody.append( OStringToOUString(sLine, eEncoding) + "\n");
1219 bDone = pInStream->ReadLine( sLine );
1222 //remove the temporary file
1223 SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
1225 else
1227 sBody = m_sBody;
1228 aDesc.sAttachmentURL = aName.GetValue();
1229 OUString sAttachment(m_xAttachmentED->get_text());
1230 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttachment, '.');
1231 if (2 > nTokenCount)
1233 sAttachment += ".";
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);
1245 OUString sGreeting;
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)],
1258 *xConfigItem);
1260 else
1262 sGreeting =
1263 xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL)
1264 [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];
1267 sGreeting += "\n";
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 ));
1277 else
1278 aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
1280 aDesc.sSubject = m_xSubjectED->get_text();
1281 aDesc.sCC = m_sCC;
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())
1289 break;
1292 xDlg->EnableDestruction();
1293 ::osl::File::remove( sTargetTempURL );
1296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */