LibreOffice Module sw (master) 1
mmresultdialogs.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <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>
32#include <hintids.hxx>
33#include <swmodule.hxx>
34
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>
56
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>
75#include <comphelper/string.hxx>
76#include <iodetect.hxx>
77
78using namespace svt;
79using namespace ::com::sun::star;
80using namespace ::com::sun::star::uno;
81
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
87
88static OUString lcl_GetExtensionForDocType(sal_uLong nDocType)
89{
90 OUString sExtension;
91 switch( nDocType )
92 {
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;
98 }
99 return sExtension;
100}
101
102static OUString lcl_GetColumnValueOf(const OUString& rColumn, Reference < container::XNameAccess> const & rxColAccess )
103{
104 OUString sRet;
105 try
106 {
107 if (rxColAccess->hasByName(rColumn))
108 {
109 Any aCol = rxColAccess->getByName(rColumn);
110 Reference< sdb::XColumn > xColumn;
111 aCol >>= xColumn;
112 if(xColumn.is())
113 sRet = xColumn->getString();
114 }
115 }
116 catch (const uno::Exception&)
117 {
118 }
119 return sRet;
120}
121
127{
128 // newly created SwMailMergeConfigItem is initialized with values from (global) config
129 SwMailMergeConfigItem aConfigItem;
130
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());
149}
150
151namespace {
152
153class SwSaveWarningBox_Impl : public SwMessageAndEditDialog
154{
155 DECL_LINK( ModifyHdl, weld::Entry&, void);
156public:
157 SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName);
158
159 OUString GetFileName() const
160 {
161 return m_xEdit->get_text();
162 }
163};
164
165class SwSendQueryBox_Impl : public SwMessageAndEditDialog
166{
167 bool bIsEmptyAllowed;
168 DECL_LINK( ModifyHdl, weld::Entry&, void);
169public:
170 SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID,
171 const OUString& rUIXMLDescription);
172
173 void SetValue(const OUString& rSet)
174 {
175 m_xEdit->set_text(rSet);
176 ModifyHdl(*m_xEdit);
177 }
178
179 OUString GetValue() const
180 {
181 return m_xEdit->get_text();
182 }
183
184 void SetIsEmptyTextAllowed(bool bSet)
185 {
186 bIsEmptyAllowed = bSet;
187 ModifyHdl(*m_xEdit);
188 }
189};
190
191}
192
193SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName)
194 : SwMessageAndEditDialog(pParent, "AlreadyExistsDialog",
195 "modules/swriter/ui/alreadyexistsdialog.ui")
196{
197 m_xEdit->set_text(rFileName);
198 m_xEdit->connect_changed(LINK(this, SwSaveWarningBox_Impl, ModifyHdl));
199
200 INetURLObject aTmp(rFileName);
201 m_xDialog->set_primary_text(m_xDialog->get_primary_text().replaceAll("%1", aTmp.getName(
203
204 ModifyHdl(*m_xEdit);
205}
206
207IMPL_LINK( SwSaveWarningBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)
208{
209 m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty());
210}
211
212SwSendQueryBox_Impl::SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID,
213 const OUString& rUIXMLDescription)
214 : SwMessageAndEditDialog(pParent, rID, rUIXMLDescription)
215 , bIsEmptyAllowed(true)
216{
217 m_xEdit->connect_changed(LINK(this, SwSendQueryBox_Impl, ModifyHdl));
218 ModifyHdl(*m_xEdit);
219}
220
221IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)
222{
223 m_xOKPB->set_sensitive(bIsEmptyAllowed || !rEdit.get_text().isEmpty());
224}
225
226namespace {
227
228class SwCopyToDialog : public SfxDialogController
229{
230 std::unique_ptr<weld::Entry> m_xCCED;
231 std::unique_ptr<weld::Entry> m_xBCCED;
232
233public:
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"))
238 {
239 }
240
241 OUString GetCC() const {return m_xCCED->get_text();}
242 void SetCC(const OUString& rSet) {m_xCCED->set_text(rSet);}
243
244 OUString GetBCC() const {return m_xBCCED->get_text();}
245 void SetBCC(const OUString& rSet) {m_xBCCED->set_text(rSet);}
246};
247
248}
249
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"))
260{
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 SwView* pView = ::GetActiveView();
268 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
269 assert(xConfigItem);
270 sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
271 m_xFromNF->set_max(nCount);
272 m_xToNF->set_max(nCount);
273 m_xToNF->set_value(nCount);
274
275 m_xOKButton->connect_clicked(LINK(this, SwMMResultSaveDialog, SaveOutputHdl_Impl));
276}
277
279{
280}
281
283 : SfxDialogController(pParent, "modules/swriter/ui/mmresultprintdialog.ui", "MMResultPrintDialog")
284 , m_xPrinterLB(m_xBuilder->weld_combo_box("printers"))
285 , m_xPrinterSettingsPB(m_xBuilder->weld_button("printersettings"))
286 , m_xPrintAllRB(m_xBuilder->weld_radio_button("printallrb"))
287 , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
288 , m_xFromNF(m_xBuilder->weld_spin_button("from"))
289 , m_xToFT(m_xBuilder->weld_label("toft"))
290 , m_xToNF(m_xBuilder->weld_spin_button("to"))
291 , m_xOKButton(m_xBuilder->weld_button("ok"))
292{
293 m_xPrinterLB->make_sorted();
294
295 m_xPrinterLB->connect_changed(LINK(this, SwMMResultPrintDialog, PrinterChangeHdl_Impl));
296 m_xPrinterSettingsPB->connect_clicked(LINK(this, SwMMResultPrintDialog, PrinterSetupHdl_Impl));
297
298 Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultPrintDialog, DocumentSelectionHdl_Impl);
299 m_xPrintAllRB->connect_toggled(aLink);
300 m_xFromRB->connect_toggled(aLink);
301 // m_pPrintAllRB is the default, so disable m_xFromNF and m_xToNF initially.
302 aLink.Call(*m_xPrintAllRB);
303
304 m_xOKButton->connect_clicked(LINK(this, SwMMResultPrintDialog, PrintHdl_Impl));
305
307}
308
310{
311}
312
314 : SfxDialogController(pParent, "modules/swriter/ui/mmresultemaildialog.ui", "MMResultEmailDialog")
315 , m_sConfigureMail(SwResId(ST_CONFIGUREMAIL))
316 , m_xMailToLB(m_xBuilder->weld_combo_box("mailto"))
317 , m_xCopyToPB(m_xBuilder->weld_button("copyto"))
318 , m_xSubjectED(m_xBuilder->weld_entry("subject"))
319 , m_xSendAsLB(m_xBuilder->weld_combo_box("sendas"))
320 , m_xSendAsPB(m_xBuilder->weld_button("sendassettings"))
321 , m_xAttachmentGroup(m_xBuilder->weld_widget("attachgroup"))
322 , m_xAttachmentED(m_xBuilder->weld_entry("attach"))
323 , m_xPasswordFT(m_xBuilder->weld_label("passwordft"))
324 , m_xPasswordLB(m_xBuilder->weld_combo_box("password"))
325 , m_xPasswordCB(m_xBuilder->weld_check_button("passwordcb"))
326 , m_xSendAllRB(m_xBuilder->weld_radio_button("sendallrb"))
327 , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
328 , m_xFromNF(m_xBuilder->weld_spin_button("from"))
329 , m_xToFT(m_xBuilder->weld_label("toft"))
330 , m_xToNF(m_xBuilder->weld_spin_button("to"))
331 , m_xOKButton(m_xBuilder->weld_button("ok"))
332{
333 m_xCopyToPB->connect_clicked(LINK(this, SwMMResultEmailDialog, CopyToHdl_Impl));
334 m_xSendAsPB->connect_clicked(LINK(this, SwMMResultEmailDialog, SendAsHdl_Impl));
335 m_xSendAsLB->connect_changed(LINK(this, SwMMResultEmailDialog, SendTypeHdl_Impl));
336 m_xPasswordCB->connect_toggled( LINK( this, SwMMResultEmailDialog, CheckHdl ));
337
338 Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultEmailDialog, DocumentSelectionHdl_Impl);
339 m_xSendAllRB->connect_toggled(aLink);
340 m_xFromRB->connect_toggled(aLink);
341 // m_xSendAllRB is the default, so disable m_xFromNF and m_xToNF initially.
342 aLink.Call(*m_xSendAllRB);
343
344 m_xOKButton->connect_clicked(LINK(this, SwMMResultEmailDialog, SendDocumentsHdl_Impl));
345
346 m_xPasswordCB->set_sensitive(false);
347 m_xPasswordFT->set_sensitive(false);
348 m_xPasswordLB->set_sensitive(false);
349
351}
352
354{
355}
356
358{
359 //fill printer ListBox
360 SwView* pView = ::GetActiveView();
361 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
362 const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues();
363 unsigned int nCount = rPrinters.size();
364 bool bMergePrinterExists = false;
365
366 for (unsigned int i = 0; i < nCount; ++i)
367 {
368 m_xPrinterLB->append_text( rPrinters[i] );
369 if( !bMergePrinterExists && rPrinters[i] == xConfigItem->GetSelectedPrinter() )
370 bMergePrinterExists = true;
371 }
372
373 assert(xConfigItem);
374 if(!bMergePrinterExists)
375 {
376 SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
377 m_xPrinterLB->set_active_text(pPrinter->GetName());
378 }
379 else
380 {
381 m_xPrinterLB->set_active_text(xConfigItem->GetSelectedPrinter());
382 }
383 PrinterChangeHdl_Impl(*m_xPrinterLB);
384
385 sal_Int32 count = xConfigItem->GetMergedDocumentCount();
386 m_xFromNF->set_max(count);
387 m_xToNF->set_value(count);
388 m_xToNF->set_max(count);
389}
390
392{
393 SwView* pView = ::GetActiveView();
394 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
395 assert(xConfigItem);
396
397 SwView* pSourceView = xConfigItem->GetSourceView();
398 OSL_ENSURE(pSourceView, "no source view exists");
399 if (pSourceView)
400 {
401 SwDocShell* pDocShell = pSourceView->GetDocShell();
402 if (pDocShell->HasName())
403 {
404 INetURLObject aTmp(pDocShell->GetMedium()->GetName());
405 m_xAttachmentED->set_text(aTmp.getName(
407 }
408 }
409
410 if (m_xAttachmentED->get_text().isEmpty())
411 {
412 OUString sAttach = "." + lcl_GetExtensionForDocType(m_xSendAsLB->get_active_id().toUInt32());
413 m_xAttachmentED->set_text(sAttach);
414
415 }
416
417 //select first column
418 uno::Reference< sdbcx::XColumnsSupplier > xColsSupp(xConfigItem->GetResultSet(), uno::UNO_QUERY);
419 //get the name of the actual columns
420 uno::Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
421 uno::Sequence< OUString > aFields;
422 if (xColAccess.is())
423 aFields = xColAccess->getElementNames();
424
425 // fill mail address and password ListBox
426 assert(m_xMailToLB->get_count() == 0);
427 assert(m_xPasswordLB->get_count() == 0);
428 for (const OUString& rField : std::as_const(aFields))
429 {
430 m_xMailToLB->append_text(rField);
431 m_xPasswordLB->append_text(rField);
432 }
433
434 m_xMailToLB->set_active(0);
435 m_xPasswordLB->set_active(0);
436
437 // then select the right one - may not be available
438 const std::vector<std::pair<OUString, int>>& rHeaders = xConfigItem->GetDefaultAddressHeaders();
439 OUString sEMailColumn = rHeaders[MM_PART_E_MAIL].first;
440 Sequence< OUString> aAssignment = xConfigItem->GetColumnAssignment(xConfigItem->GetCurrentDBData());
441 if (aAssignment.getLength() > MM_PART_E_MAIL && !aAssignment[MM_PART_E_MAIL].isEmpty())
442 sEMailColumn = aAssignment[MM_PART_E_MAIL];
443 if (int pos = m_xMailToLB->find_text(sEMailColumn); pos >= 0)
444 m_xMailToLB->set_active(pos);
445
446 // HTML format pre-selected
447 m_xSendAsLB->set_active(3);
448 SendTypeHdl_Impl(*m_xSendAsLB);
449
450 const sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
451 m_xFromNF->set_max(nCount);
452 m_xToNF->set_max(nCount);
453 m_xToNF->set_value(nCount);
454}
455
456IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
457{
458 bool bEnableFromTo = m_xFromRB->get_active();
459 m_xFromNF->set_sensitive(bEnableFromTo);
460 m_xToFT->set_sensitive(bEnableFromTo);
461 m_xToNF->set_sensitive(bEnableFromTo);
462}
463
465{
466 bool bEnable = m_xPasswordCB->get_active();
467
468 m_xPasswordFT->set_sensitive(bEnable);
469 m_xPasswordLB->set_sensitive(bEnable);
470}
471
472IMPL_LINK_NOARG(SwMMResultPrintDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
473{
474 bool bEnableFromTo = m_xFromRB->get_active();
475 m_xFromNF->set_sensitive(bEnableFromTo);
476 m_xToFT->set_sensitive(bEnableFromTo);
477 m_xToNF->set_sensitive(bEnableFromTo);
478}
479
480IMPL_LINK_NOARG(SwMMResultEmailDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
481{
482 bool bEnableFromTo = m_xFromRB->get_active();
483 m_xFromNF->set_sensitive(bEnableFromTo);
484 m_xToFT->set_sensitive(bEnableFromTo);
485 m_xToNF->set_sensitive(bEnableFromTo);
486}
487
489{
490 SwCopyToDialog aDlg(m_xDialog.get());
491 aDlg.SetCC(m_sCC );
492 aDlg.SetBCC(m_sBCC);
493 if (aDlg.run() == RET_OK)
494 {
495 m_sCC = aDlg.GetCC() ;
496 m_sBCC = aDlg.GetBCC();
497 }
498}
499
500namespace {
501
502int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
503{
504 SwView* pTargetView = pConfigItem->GetTargetView();
505 assert( pTargetView );
506 SwCursorShell& shell = pTargetView->GetWrtShell();
507 const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo(document);
508 sal_uInt16 page;
509 shell.Push();
510 shell.GotoMark( info.startPageInTarget );
511 if (!bIgnoreEmpty)
512 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
513 else
514 page = shell.GetPageNumSeqNonEmpty();
516 return page;
517}
518
519int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
520{
521 SwView* pTargetView = pConfigItem->GetTargetView();
522 assert( pTargetView );
523 SwWrtShell& shell = pTargetView->GetWrtShell();
524 shell.Push();
525 if (document < int(pConfigItem->GetMergedDocumentCount()) - 1)
526 {
527 // Go to the page before the starting page of the next merged document.
528 const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo( document + 1 );
529 shell.GotoMark( info.startPageInTarget );
530 shell.EndPrvPg();
531 }
532 else
533 { // This is the last merged document, so it ends on the page at which the document ends.
534 shell.SttEndDoc( false ); // go to doc end
535 }
536 sal_uInt16 page;
537 if (!bIgnoreEmpty)
538 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
539 else
540 page = shell.GetPageNumSeqNonEmpty();
542 return page;
543}
544
545} // anonymous namespace
546
548{
549 SwView* pView = ::GetActiveView();
550 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
551 assert(xConfigItem);
552
553 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
554 sal_uInt32 nBegin = 0;
555 sal_uInt32 nEnd = nDocumentCount;
556
557 if (m_xFromRB->get_active())
558 {
559 nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
560 nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
561 if (nEnd > nDocumentCount)
562 nEnd = nDocumentCount;
563 }
564
565 xConfigItem->SetBeginEnd(nBegin, nEnd);
566
567 if (!xConfigItem->GetTargetView())
569
570 SwView* pTargetView = xConfigItem->GetTargetView();
571 assert(pTargetView);
572
573 OUString sFilter;
574 OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
575 if (sPath.isEmpty())
576 {
577 // just return back to the dialog
578 return;
579 }
580
581 if (m_xSaveAsOneRB->get_active())
582 {
583 uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", sFilter) };
584
585 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
586 ErrCode nErrorCode = ERRCODE_NONE;
587 try
588 {
589 xStore->storeToURL( sPath, aValues );
590 }
591 catch (const task::ErrorCodeIOException& rErrorEx)
592 {
593 nErrorCode = ErrCode(rErrorEx.ErrCode);
594 }
595 catch (const Exception&)
596 {
597 nErrorCode = ERRCODE_IO_GENERAL;
598 }
599 if( nErrorCode != ERRCODE_NONE )
600 {
602 ErrorHandler::HandleError( nErrorCode );
603 }
604 }
605 else
606 {
607 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
610 std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
612 SwDocShell::Factory().GetFilterContainer() );
613
614 uno::Sequence< beans::PropertyValue > aValues(1);
615 beans::PropertyValue* pValues = aValues.getArray();
616 pValues[0].Name = "FilterName";
617 pValues[0].Value <<= pSfxFlt->GetFilterName();
618
619 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
620 ErrCode nErrorCode = ERRCODE_NONE;
621 try
622 {
623 xStore->storeToURL( sTargetTempURL, aValues );
624 }
625 catch (const task::ErrorCodeIOException& rErrorEx)
626 {
627 nErrorCode = ErrCode(rErrorEx.ErrCode);
628 }
629 catch (const Exception&)
630 {
631 nErrorCode = ERRCODE_IO_GENERAL;
632 }
633 if( nErrorCode != ERRCODE_NONE )
634 {
636 ErrorHandler::HandleError( nErrorCode );
637 }
638
639 SwView* pSourceView = xConfigItem->GetSourceView();
640 auto xSaveMonitor = std::make_shared<SaveMonitor>(m_xDialog.get());
641 xSaveMonitor->m_xDocName->set_label(pSourceView->GetDocShell()->GetTitle(22));
642 xSaveMonitor->m_xPrinter->set_label( INetURLObject( sPath ).getFSysPath( FSysStyle::Detect ) );
643 m_bCancelSaving = false;
644 weld::DialogController::runAsync(xSaveMonitor, [this, &xSaveMonitor](sal_Int32 nResult){
645 if (nResult == RET_CANCEL)
646 m_bCancelSaving = true;
647 xSaveMonitor.reset();
648 });
649
650 for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin && !m_bCancelSaving; ++nDoc)
651 {
652 INetURLObject aURL(sPath);
653 OUString sExtension = aURL.getExtension();
654 if (sExtension.isEmpty())
655 {
656 sExtension = pSfxFlt->GetWildcard().getGlob().getToken(1, '.');
657 sPath += "." + sExtension;
658 }
659 OUString sStat = SwResId(STR_STATSTR_LETTER) + " " + OUString::number(nDoc + 1);
660 xSaveMonitor->m_xPrintInfo->set_label(sStat);
661
662 //now extract a document from the target document
663 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
664 SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
665 xTempDocShell->DoInitNew();
667 SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
668 pTargetView->GetWrtShell().StartAction();
669 SwgReaderOption aOpt;
670 aOpt.SetTextFormats( true );
671 aOpt.SetFrameFormats( true );
672 aOpt.SetPageDescs( true );
673 aOpt.SetNumRules( true );
674 aOpt.SetMerge( false );
675 pTempView->GetDocShell()->LoadStylesFromFile(
676 sTargetTempURL, aOpt, true );
677 pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
678 pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
679 pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
680
681 uno::Reference<beans::XPropertySet> const xThisSet(
682 pTargetView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
683 uno::Reference<beans::XPropertySet> const xRetSet(
684 pTempView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
685 uno::Sequence<beans::PropertyValue> aInteropGrabBag;
686 xThisSet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
687 xRetSet->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag));
688
689 pTargetView->GetWrtShell().PastePages(
690 pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
691 documentEndPageNumber(xConfigItem.get(), nDoc, false));
692 pTargetView->GetWrtShell().EndAction();
693 //then save it
694 OUString sOutPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
695 OUString sCounter = "_" + OUString::number(nDoc + 1);
696 sOutPath = sOutPath.replaceAt( sOutPath.getLength() - sExtension.getLength() - 1, 0, sCounter);
697
698 while(true)
699 {
700 //time for other slots is needed
702
703 bool bFailed = false;
704 try
705 {
706 pValues[0].Value <<= sFilter;
707 uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY);
708 xTempStore->storeToURL( sOutPath, aValues );
709 }
710 catch (const uno::Exception&)
711 {
712 bFailed = true;
713 }
714
715 if(bFailed)
716 {
717 std::unique_ptr<SwSaveWarningBox_Impl> xWarning(new SwSaveWarningBox_Impl(m_xDialog.get(), sOutPath));
718 if (RET_OK == xWarning->run())
719 sOutPath = xWarning->GetFileName();
720 else
721 {
722 xTempDocShell->DoClose();
723 m_xDialog->response(RET_OK);
724 return;
725 }
726 }
727 else
728 {
729 xTempDocShell->DoClose();
730 m_xDialog->response(RET_OK);
731 break;
732 }
733 }
734 }
735 if (xSaveMonitor)
736 xSaveMonitor->response(RET_OK);
737 ::osl::File::remove( sTargetTempURL );
738 }
739
740 m_xDialog->response(RET_OK);
741}
742
743IMPL_LINK(SwMMResultPrintDialog, PrinterChangeHdl_Impl, weld::ComboBox&, rBox, void)
744{
745 SwView* pView = ::GetActiveView();
746 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
747 assert(xConfigItem);
748 if (rBox.get_active() != -1)
749 {
750 const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false );
751
752 if( pInfo )
753 {
754 if ( !m_pTempPrinter )
755 {
756 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
757 }
758 else
759 {
760 if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
761 (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
762 {
763 m_pTempPrinter.disposeAndClear();
764 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
765 }
766 }
767 }
768 else if( ! m_pTempPrinter )
769 m_pTempPrinter = VclPtr<Printer>::Create();
770
771 m_xPrinterSettingsPB->set_sensitive(m_pTempPrinter->HasSupport(PrinterSupport::SetupDialog));
772 }
773 else
774 m_xPrinterSettingsPB->set_sensitive(false);
775
776 xConfigItem->SetSelectedPrinter(rBox.get_active_text());
777}
778
780{
781 SwView* pView = ::GetActiveView();
782 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
783 assert(xConfigItem);
784
785 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
786 sal_uInt32 nBegin = 0;
787 sal_uInt32 nEnd = nDocumentCount;
788
789 if (m_xFromRB->get_active())
790 {
791 nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
792 nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
793 if (nEnd > nDocumentCount)
794 nEnd = nDocumentCount;
795 }
796
797 xConfigItem->SetBeginEnd(nBegin, nEnd);
798
799 if(!xConfigItem->GetTargetView())
801
802 SwView* pTargetView = xConfigItem->GetTargetView();
803 assert(pTargetView);
804
805 // If we skip autoinserted blanks, then the page numbers used in the print range string
806 // refer to the non-blank pages as they appear in the document (see tdf#89708).
807 const bool bIgnoreEmptyPages =
809 const int nStartPage = documentStartPageNumber(xConfigItem.get(), 0, bIgnoreEmptyPages);
810 const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - nBegin - 1, bIgnoreEmptyPages);
811
812 const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage));
813
814 pTargetView->SetMailMergeConfigItem(xConfigItem);
815 if(m_pTempPrinter)
816 {
817 SfxPrinter *const pDocumentPrinter = pTargetView->GetWrtShell()
819 pDocumentPrinter->SetPrinterProps(m_pTempPrinter);
820 // this should be able to handle setting its own printer
821 pTargetView->SetPrinter(pDocumentPrinter);
822 }
823
824 SfxObjectShell* pObjSh = pTargetView->GetViewFrame()->GetObjectShell();
826
827 uno::Sequence aProps{ comphelper::makePropertyValue("MonitorVisible", true),
828 comphelper::makePropertyValue("Pages", sPages) };
829
830 pTargetView->ExecPrint( aProps, false, true );
831 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), pObjSh));
832
833 m_xDialog->response(RET_OK);
834}
835
837{
838 if (m_pTempPrinter)
839 m_pTempPrinter->Setup(m_xDialog.get());
840}
841
842IMPL_LINK(SwMMResultEmailDialog, SendTypeHdl_Impl, weld::ComboBox&, rBox, void)
843{
844 auto nDocType = rBox.get_active_id().toUInt32();
845 bool bEnable = MM_DOCTYPE_HTML != nDocType && MM_DOCTYPE_TEXT != nDocType;
846 bool bIsPDF = nDocType == MM_DOCTYPE_PDF;
847 m_xSendAsPB->set_sensitive(bEnable);
848 m_xAttachmentGroup->set_sensitive(bEnable);
849 if(bEnable)
850 {
851 //add the correct extension
852 OUString sAttach(m_xAttachmentED->get_text());
853 //do nothing if the user has removed the name - the warning will come early enough
854 if (!sAttach.isEmpty())
855 {
856 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
857 if( 2 > nTokenCount)
858 {
859 sAttach += ".";
860 ++nTokenCount;
861 }
862 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
863 m_xAttachmentED->set_text(sAttach);
864 }
865 }
866
867 if(bIsPDF)
868 {
869 m_xPasswordCB->set_sensitive(true);
870 m_xPasswordFT->set_sensitive(true);
871 m_xPasswordLB->set_sensitive(true);
872 CheckHdl(*m_xPasswordCB);
873 }
874 else
875 {
876 m_xPasswordCB->set_sensitive(false);
877 m_xPasswordFT->set_sensitive(false);
878 m_xPasswordLB->set_sensitive(false);
879 }
880}
881
883{
884 SwMailBodyDialog aDlg(m_xDialog.get());
885 aDlg.SetBody(m_sBody);
886 if (RET_OK == aDlg.run())
887 {
888 m_sBody = aDlg.GetBody();
889 }
890}
891
892// Send documents as e-mail
894{
895 SwView* pView = ::GetActiveView();
896 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
897 assert(xConfigItem);
898
899 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
900 sal_uInt32 nBegin = 0;
901 sal_uInt32 nEnd = nDocumentCount;
902
903 if (m_xFromRB->get_active())
904 {
905 nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
906 nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
907 if (nEnd > nDocumentCount)
908 nEnd = nDocumentCount;
909 }
910
911 xConfigItem->SetBeginEnd(nBegin, nEnd);
912
913 if (!xConfigItem->GetTargetView())
915
916 //get the composed document
917 SwView* pTargetView = xConfigItem->GetTargetView();
918 SAL_WARN_IF(!pTargetView, "sw.ui", "No TargetView in SwMailMergeConfigItem");
919
920 if (xConfigItem->GetMailServer().isEmpty() ||
921 !SwMailMergeHelper::CheckMailAddress(xConfigItem->GetMailAddress()) )
922 {
923 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
924 VclMessageType::Question, VclButtonsType::YesNo,
925 m_sConfigureMail));
926 xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
927 sal_uInt16 nRet = xQueryBox->run();
928 if (RET_YES == nRet )
929 {
930 SwView* pConfigView = pTargetView ? pTargetView : pView;
931 SfxAllItemSet aSet(pConfigView->GetPool());
932 SwMailConfigDlg aDlg(m_xDialog.get(), aSet);
933 nRet = aDlg.run();
934 }
935
936 if(nRet != RET_OK && nRet != RET_YES)
937 return; // back to the dialog
938
939 // SwMailConfigDlg writes mail merge email settings only to (global) config,
940 // so copy them to the existing config item
942 }
943 //add the documents
944 bool bAsBody = false;
945 rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding();
946 SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
947 std::shared_ptr<const SfxFilter> pSfxFlt;
948 auto nDocType = m_xSendAsLB->get_active_id().toUInt32();
949 OUString sExtension = lcl_GetExtensionForDocType(nDocType);
950 switch( nDocType )
951 {
952 case MM_DOCTYPE_OOO:
953 {
954 //Make sure we don't pick e.g. the flat xml filter
955 //for this format
956 pSfxFlt = pFilterContainer->GetFilter4FilterName(
957 "writer8",
958 SfxFilterFlags::EXPORT);
959 }
960 break;
961 case MM_DOCTYPE_PDF:
962 {
963 pSfxFlt = pFilterContainer->GetFilter4FilterName(
964 "writer_pdf_Export",
965 SfxFilterFlags::EXPORT);
966 }
967 break;
968 case MM_DOCTYPE_WORD:
969 {
970 //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
971 //because it uses the same user data :-(
972 SfxFilterMatcher aMatcher( pFilterContainer->GetName() );
973 SfxFilterMatcherIter aIter( aMatcher );
974 std::shared_ptr<const SfxFilter> pFilter = aIter.First();
975 while ( pFilter )
976 {
977 if( pFilter->GetUserData() == FILTER_WW8 && pFilter->CanExport() )
978 {
979 pSfxFlt = pFilter;
980 break;
981 }
982 pFilter = aIter.Next();
983 }
984
985 }
986 break;
987 case MM_DOCTYPE_HTML:
988 {
989 bAsBody = true;
990 eEncoding = RTL_TEXTENCODING_UTF8;
991 }
992 break;
993 case MM_DOCTYPE_TEXT:
994 {
995 bAsBody = true;
996 pSfxFlt = pFilterContainer->GetFilter4FilterName(
997 "Text (encoded)", SfxFilterFlags::EXPORT);
998 }
999 break;
1000 }
1001 if(!pSfxFlt)
1002 pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
1003
1004 if(!pSfxFlt)
1005 {
1006 m_xDialog->response(RET_OK);
1007 return;
1008 }
1009 OUString sMimeType = pSfxFlt->GetMimeType();
1010
1011 if (m_xSubjectED->get_text().isEmpty())
1012 {
1013 std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "SubjectDialog",
1014 "modules/swriter/ui/subjectdialog.ui"));
1015 xQuery->SetIsEmptyTextAllowed(true);
1016 xQuery->SetValue("");
1017 if(RET_OK == xQuery->run())
1018 {
1019 if (!xQuery->GetValue().isEmpty())
1020 m_xSubjectED->set_text(xQuery->GetValue());
1021 }
1022 else
1023 return; // back to the dialog
1024 }
1025 if(!bAsBody && m_xAttachmentED->get_text().isEmpty())
1026 {
1027 std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "AttachNameDialog",
1028 "modules/swriter/ui/attachnamedialog.ui"));
1029 xQuery->SetIsEmptyTextAllowed(false);
1030 if (RET_OK == xQuery->run())
1031 {
1032 OUString sAttach(xQuery->GetValue());
1033 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
1034 if (2 > nTokenCount)
1035 {
1036 sAttach += ".";
1037 ++nTokenCount;
1038 }
1039 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType(
1040 m_xSendAsLB->get_active_id().toUInt32()));
1041 m_xAttachmentED->set_text(sAttach);
1042 }
1043 else
1044 return; // back to the dialog
1045 }
1046
1047 OUString sEMailColumn = m_xMailToLB->get_active_text();
1048 OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected");
1049 Reference< sdbcx::XColumnsSupplier > xColsSupp( xConfigItem->GetResultSet(), UNO_QUERY);
1050 Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
1051 if(sEMailColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sEMailColumn))
1052 {
1053 m_xDialog->response(RET_OK);
1054 return;
1055 }
1056
1057 OUString sPasswordColumn = m_xPasswordLB->get_active_text();
1058 OSL_ENSURE( !sPasswordColumn.isEmpty(), "No password column selected");
1059 if(sPasswordColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sPasswordColumn))
1060 {
1061 m_xDialog->response(RET_OK);
1062 return;
1063 }
1064
1065 OUString sFilterOptions;
1066 if(MM_DOCTYPE_TEXT == nDocType)
1067 {
1068 SwAsciiOptions aOpt;
1069 sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
1070 sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
1071 aOpt.SetLanguage( static_cast<const SvxLanguageItem&>(pTargetView->GetWrtShell().
1072 GetDefault( nWhich )).GetLanguage());
1073 aOpt.SetParaFlags( LINEEND_CR );
1074 aOpt.WriteUserData( sFilterOptions );
1075 }
1076 else if(MM_DOCTYPE_HTML == nDocType)
1077 {
1078 sFilterOptions = "EmbedImages";
1079 }
1080 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
1083 std::shared_ptr<const SfxFilter> pTargetSfxFlt = SwIoSystem::GetFilterOfFormat(
1084 FILTER_XML,
1085 SwDocShell::Factory().GetFilterContainer() );
1086
1087 uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", pTargetSfxFlt->GetFilterName()) };
1088
1089 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1090 xStore->storeToURL( sTargetTempURL, aValues );
1091
1092 //create the send dialog
1093 std::shared_ptr<SwSendMailDialog> xDlg = std::make_shared<SwSendMailDialog>(Application::GetDefDialogParent(), *xConfigItem);
1094
1095 xDlg->StartSend(nEnd - nBegin);
1096 weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){});
1097
1098 //help to force painting the dialog
1099 //TODO/CLEANUP
1100 //predetermined breaking point
1102 m_xDialog->response(RET_OK);
1103 for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin; ++nDoc)
1104 {
1105 SwDocMergeInfo& rInfo = xConfigItem->GetDocumentMergeInfo(nDoc);
1106
1107 //now extract a document from the target document
1108 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
1109 SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
1110 xTempDocShell->DoInitNew();
1111 SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE );
1112 SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
1113 pTargetView->GetWrtShell().StartAction();
1114 SwgReaderOption aOpt;
1115 aOpt.SetTextFormats( true );
1116 aOpt.SetFrameFormats( true );
1117 aOpt.SetPageDescs( true );
1118 aOpt.SetNumRules( true );
1119 aOpt.SetMerge( false );
1120 pTempView->GetDocShell()->LoadStylesFromFile(
1121 sTargetTempURL, aOpt, true );
1122 pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
1123 pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
1124 pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
1125 pTargetView->GetWrtShell().PastePages(
1126 pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
1127 documentEndPageNumber(xConfigItem.get(), nDoc, false));
1128 pTargetView->GetWrtShell().EndAction();
1129
1130 //then save it
1131 SfxStringItem aName(SID_FILE_NAME,
1135
1136 {
1137 bool withFilterOptions = MM_DOCTYPE_TEXT == nDocType || MM_DOCTYPE_HTML == nDocType;
1138 bool withPasswordOptions = m_xPasswordCB->get_active();
1139
1140 sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
1141 OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected");
1142 OUString sPassword = lcl_GetColumnValueOf(sPasswordColumn, xColAccess);
1143
1144 sal_Int32 nOptionCount = (withFilterOptions && withPasswordOptions) ? 4 : withPasswordOptions ? 3 : withFilterOptions ? 2 : 1;
1145 sal_Int32 nOpt = 0;
1146 uno::Sequence< beans::PropertyValue > aFilterValues(nOptionCount);
1147 beans::PropertyValue* pFilterValues = aFilterValues.getArray();
1148
1149 pFilterValues[nOpt].Name = "FilterName";
1150 pFilterValues[nOpt].Value <<= pSfxFlt->GetFilterName();
1151
1152 if(withFilterOptions)
1153 {
1154 nOpt++;
1155 pFilterValues[nOpt].Name = "FilterOptions";
1156 pFilterValues[nOpt].Value <<= sFilterOptions;
1157 }
1158
1159 if(withPasswordOptions)
1160 {
1161 nOpt++;
1162 pFilterValues[nOpt].Name = "EncryptFile";
1163 pFilterValues[nOpt].Value <<= true;
1164 nOpt++;
1165 pFilterValues[nOpt].Name = "DocumentOpenPassword";
1166 pFilterValues[nOpt].Value <<= sPassword;
1167 }
1168
1169 uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1170 xTempStore->storeToURL( aName.GetValue(), aFilterValues );
1171 }
1172 xTempDocShell->DoClose();
1173
1174 sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
1175 OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected");
1176 OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected");
1177 OUString sEMail = lcl_GetColumnValueOf(sEMailColumn, xColAccess);
1178 SwMailDescriptor aDesc;
1179 aDesc.sEMail = sEMail;
1180 OUStringBuffer sBody;
1181 if(bAsBody)
1182 {
1183 {
1184 //read in the temporary file and use it as mail body
1185 SfxMedium aMedium( aName.GetValue(), StreamMode::READ);
1186 SvStream* pInStream = aMedium.GetInStream();
1187 if(pInStream)
1188 pInStream->SetStreamCharSet( eEncoding );
1189 else
1190 {
1191 OSL_FAIL("no output file created?");
1192 continue;
1193 }
1194 OStringBuffer sLine;
1195 bool bDone = pInStream->ReadLine( sLine );
1196 while ( bDone )
1197 {
1198 sBody.append( OStringToOUString(sLine, eEncoding) );
1199 sBody.append("\n");
1200 bDone = pInStream->ReadLine( sLine );
1201 }
1202 }
1203 //remove the temporary file
1204 SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
1205 }
1206 else
1207 {
1208 sBody = m_sBody;
1209 aDesc.sAttachmentURL = aName.GetValue();
1210 OUString sAttachment(m_xAttachmentED->get_text());
1211 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttachment, '.');
1212 if (2 > nTokenCount)
1213 {
1214 sAttachment += ".";
1215 sAttachment = comphelper::string::setToken(sAttachment, nTokenCount, '.', sExtension);
1216 }
1217 else if (o3tl::getToken(sAttachment, nTokenCount - 1, '.') != sExtension)
1218 sAttachment += sExtension;
1219 aDesc.sAttachmentName = sAttachment;
1220 aDesc.sMimeType = sMimeType;
1221
1222 if (xConfigItem->IsGreetingLine(true))
1223 {
1224 OUString sNameColumn = xConfigItem->GetAssignedColumn(MM_PART_LASTNAME);
1225 OUString sName = lcl_GetColumnValueOf(sNameColumn, xColAccess);
1226 OUString sGreeting;
1227 if(!sName.isEmpty() && xConfigItem->IsIndividualGreeting(true))
1228 {
1229 OUString sGenderColumn = xConfigItem->GetAssignedColumn(MM_PART_GENDER);
1230 const OUString& sFemaleValue = xConfigItem->GetFemaleGenderValue();
1231 OUString sGenderValue = lcl_GetColumnValueOf(sGenderColumn, xColAccess);
1232 SwMailMergeConfigItem::Gender eGenderType = sGenderValue == sFemaleValue ?
1235
1236 sGreeting = SwAddressPreview::FillData(
1237 xConfigItem->GetGreetings(eGenderType)
1238 [xConfigItem->GetCurrentGreeting(eGenderType)],
1239 *xConfigItem);
1240 }
1241 else
1242 {
1243 sGreeting =
1244 xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL)
1245 [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];
1246
1247 }
1248 sGreeting += "\n";
1249 sBody.insert(0, sGreeting);
1250 }
1251 }
1252 aDesc.sBodyContent = sBody.makeStringAndClear();
1253 if(MM_DOCTYPE_HTML == nDocType)
1254 {
1255 aDesc.sBodyMimeType = "text/html; charset=" +
1256 OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
1257 }
1258 else
1259 aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
1260
1261 aDesc.sSubject = m_xSubjectED->get_text();
1262 aDesc.sCC = m_sCC;
1263 aDesc.sBCC = m_sBCC;
1264 xDlg->AddDocument( aDesc );
1265 //help to force painting the dialog
1267 //stop creating of data when dialog has been closed
1268 if (!xDlg->getDialog()->get_visible())
1269 {
1270 break;
1271 }
1272 }
1273 xDlg->EnableDestruction();
1274 ::osl::File::remove( sTargetTempURL );
1275}
1276
1277/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
SfxApplication * SfxGetpApp()
Reference< XExecutableDialog > m_xDialog
static bool Reschedule(bool bHandleAllCurrentEvents=false)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
static weld::Window * GetDefDialogParent()
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
virtual SfxPrinter * getPrinter(bool bCreate) const =0
Return the printer set at the document.
virtual const SwPrintData & getPrintData() const =0
Returns the PrintData.
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static const std::vector< OUString > & GetPrinterQueues()
static const QueueInfo * GetQueueInfo(const OUString &rPrinterName, bool bStatusUpdate)
const OUString & GetDriver() const
const OUString & GetPrinterName() const
static void ProcessEventsToIdle()
void NotifyEvent(const SfxEventHint &rEvent, bool bSynchron=true)
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
OUString const & GetName() const
std::shared_ptr< const SfxFilter > GetFilter4Extension(const OUString &rExt, SfxFilterFlags nMust=SfxFilterFlags::IMPORT, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
std::shared_ptr< const SfxFilter > First()
std::shared_ptr< const SfxFilter > Next()
const OUString & GetName() const
SvStream * GetInStream()
bool HasName() const
SfxMedium * GetMedium() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
SfxItemPool & GetPool() const
SfxViewShell * GetViewShell() const
virtual SfxObjectShell * GetObjectShell() override
static SfxViewFrame * LoadHiddenDocument(SfxObjectShell const &i_rDoc, SfxInterfaceId i_nViewId)
SfxViewFrame * GetViewFrame() const
void ExecPrint(const css::uno::Sequence< css::beans::PropertyValue > &, bool, bool)
bool ReadLine(OStringBuffer &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
void SetStreamCharSet(rtl_TextEncoding eCharSet)
static OUString FillData(const OUString &rAddress, SwMailMergeConfigItem const &rConfigItem, const css::uno::Sequence< OUString > *pAssignments=nullptr)
void WriteUserData(OUString &) const
Definition: fltini.cxx:573
void SetLanguage(LanguageType nVal)
Definition: shellio.hxx:76
void SetParaFlags(LineEnd eVal)
Definition: shellio.hxx:79
void StartAction()
Definition: crsrsh.cxx:226
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:243
static std::shared_ptr< SwMailMergeConfigItem > PerformMailMerge(SwView const *pView)
Definition: dbmgr.cxx:3212
ErrCode LoadStylesFromFile(const OUString &rURL, SwgReaderOption &rOpt, bool bUnoCall)
Definition: docsh2.cxx:1599
static OUString GetEventName(sal_Int32 nId)
Definition: docsh.cxx:1329
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
void ReplaceDefaults(const SwDoc &rSource)
Definition: docnew.cxx:847
void ReplaceCompatibilityOptions(const SwDoc &rSource)
Definition: docnew.cxx:877
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:244
void ReplaceDocumentProperties(const SwDoc &rSource, bool mailMerge=false)
Replace document properties with those from rSource.
Definition: docglos.cxx:83
void PastePages(SwFEShell &rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage)
Paste some pages into another doc - used in mailmerge.
Definition: fecopy.cxx:1141
static SW_DLLPUBLIC std::shared_ptr< const SfxFilter > GetFilterOfFormat(std::u16string_view rFormat, const SfxFilterContainer *pCnt=nullptr)
find for an internal format name the corresponding filter entry
Definition: iodetect.cxx:68
Dialog implementing the sending as email of the result document.
std::unique_ptr< weld::Entry > m_xAttachmentED
std::unique_ptr< weld::SpinButton > m_xFromNF
std::unique_ptr< weld::RadioButton > m_xFromRB
std::unique_ptr< weld::Label > m_xPasswordFT
std::unique_ptr< weld::Button > m_xSendAsPB
std::unique_ptr< weld::CheckButton > m_xPasswordCB
std::unique_ptr< weld::Button > m_xCopyToPB
std::unique_ptr< weld::RadioButton > m_xSendAllRB
SwMMResultEmailDialog(weld::Window *pParent)
std::unique_ptr< weld::ComboBox > m_xSendAsLB
virtual ~SwMMResultEmailDialog() override
std::unique_ptr< weld::SpinButton > m_xToNF
std::unique_ptr< weld::Button > m_xOKButton
std::unique_ptr< weld::ComboBox > m_xPasswordLB
std::unique_ptr< weld::ComboBox > m_xMailToLB
Dialog implementing the printing of the result document.
std::unique_ptr< weld::Button > m_xPrinterSettingsPB
virtual ~SwMMResultPrintDialog() override
std::unique_ptr< weld::SpinButton > m_xFromNF
std::unique_ptr< weld::ComboBox > m_xPrinterLB
SwMMResultPrintDialog(weld::Window *pParent)
std::unique_ptr< weld::RadioButton > m_xFromRB
std::unique_ptr< weld::RadioButton > m_xPrintAllRB
std::unique_ptr< weld::SpinButton > m_xToNF
std::unique_ptr< weld::Button > m_xOKButton
Dialog implementing the saving as of the result document.
std::unique_ptr< weld::SpinButton > m_xToNF
std::unique_ptr< weld::CheckButton > m_xFromRB
std::unique_ptr< weld::SpinButton > m_xFromNF
std::unique_ptr< weld::RadioButton > m_xSaveIndividualRB
SwMMResultSaveDialog(weld::Window *pParent)
std::unique_ptr< weld::RadioButton > m_xSaveAsOneRB
virtual ~SwMMResultSaveDialog() override
std::unique_ptr< weld::Button > m_xOKButton
void SetBody(const OUString &rBody)
OUString GetBody() const
void SetMailReplyTo(bool bSet)
void SetAuthentication(bool bSet)
SwDocMergeInfo & GetDocumentMergeInfo(sal_uInt32 nDocument)
OUString const & GetInServerUserName() const
bool IsAuthentication() const
OUString const & GetInServerName() const
OUString const & GetMailServer() const
OUString const & GetMailUserName() const
OUString const & GetMailAddress() const
void SetMailUserName(const OUString &rName)
OUString const & GetMailDisplayName() const
sal_uInt32 GetMergedDocumentCount()
bool IsSecureConnection() const
sal_Int16 GetInServerPort() const
void SetInServerName(const OUString &rServer)
bool IsMailReplyTo() const
void SetMailServer(const OUString &rAddress)
sal_Int16 GetMailPort() const
void SetInServerUserName(const OUString &rName)
void SetInServerPOP(bool bSet)
bool IsSMTPAfterPOP() const
void SetMailPort(sal_Int16 nSet)
void SetInServerPort(sal_Int16 nSet)
void SetSecureConnection(bool bSet)
OUString const & GetInServerPassword() const
void SetMailDisplayName(const OUString &rName)
void SetMailPassword(const OUString &rPassword)
void SetSMTPAfterPOP(bool bSet)
bool IsInServerPOP() const
OUString const & GetMailPassword() const
OUString const & GetMailReplyTo() const
void SetInServerPassword(const OUString &rPassword)
void SetMailAddress(const OUString &rAddress)
bool IsPrintEmptyPages() const
Definition: printdata.hxx:139
const IDocumentDeviceAccess & getIDocumentDeviceAccess() const
Provides access to the document device interface.
Definition: viewsh.cxx:2805
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:416
virtual sal_uInt16 SetPrinter(SfxPrinter *pNew, SfxPrinterChangeFlags nDiff=SFX_PRINTER_ALL) override
Definition: viewprt.cxx:97
std::shared_ptr< SwMailMergeConfigItem > const & GetMailMergeConfigItem() const
Definition: view0.cxx:136
SwDocShell * GetDocShell()
Definition: view.cxx:1160
void SetMailMergeConfigItem(std::shared_ptr< SwMailMergeConfigItem > const &rConfigItem)
Definition: view0.cxx:130
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
void SetNumRules(const bool bNew)
Definition: shellio.hxx:122
void SetTextFormats(const bool bNew)
Definition: shellio.hxx:119
void SetMerge(const bool bNew)
Definition: shellio.hxx:125
void SetPageDescs(const bool bNew)
Definition: shellio.hxx:116
void SetFrameFormats(const bool bNew)
Definition: shellio.hxx:113
static VclPtr< reference_type > Create(Arg &&... arg)
static bool runAsync(const std::shared_ptr< DialogController > &rController, const std::function< void(sal_Int32)> &)
int nCount
URL aURL
DECL_LINK(CheckNameHdl, SvxNameDialog &, bool)
virtual void SetValue(tools::Long nNew) override
#define ERRCODE_IO_GENERAL
#define ERRCODE_NONE
Reference< XColumn > xColumn
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:196
std::unique_ptr< weld::Button > m_xOKButton
LanguageType GetAppLanguage()
Definition: init.cxx:725
OUString aName
constexpr OUStringLiteral FILTER_WW8
WinWord 97 filter.
Definition: iodetect.hxx:36
constexpr OUStringLiteral FILTER_XML
XML filter.
Definition: iodetect.hxx:38
LINEEND_CR
#define SAL_WARN_IF(condition, area, stream)
IMPL_LINK(SwSaveWarningBox_Impl, ModifyHdl, weld::Entry &, rEdit, void)
#define MM_DOCTYPE_TEXT
#define MM_DOCTYPE_HTML
static void lcl_UpdateEmailSettingsFromGlobalConfig(SwMailMergeConfigItem &rConfigItem)
Replace email server settings in rConfigItem with those set in Writer's global mail merge config sett...
#define MM_DOCTYPE_WORD
#define MM_DOCTYPE_PDF
static OUString lcl_GetColumnValueOf(const OUString &rColumn, Reference< container::XNameAccess > const &rxColAccess)
#define MM_DOCTYPE_OOO
IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::Toggleable &, void)
static OUString lcl_GetExtensionForDocType(sal_uLong nDocType)
const char * sName
bool UCB_DeleteFile(const OUString &rURL)
Definition: swunohelper.cxx:59
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
OUString CallSaveAsDialog(weld::Window *pParent, OUString &rFilter)
bool CheckMailAddress(std::u16string_view aMailAddress)
SVL_DLLPUBLIC Link< OUString *, bool > const & GetMaybeFileHdl()
SVL_DLLPUBLIC OUString SmartRel2Abs(INetURLObject const &rTheBaseURIRef, OUString const &rTheRelURIRef, Link< OUString *, bool > const &rMaybeFileHdl=Link< OUString *, bool >(), bool bCheckFileExists=true, bool bIgnoreFragment=false, INetURLObject::EncodeMechanism eEncodeMechanism=INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
@ Exception
OUString setToken(const OUString &rIn, sal_Int32 nToken, sal_Unicode cTok, std::u16string_view rNewToken)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
constexpr T & temporary(T &&x)
OUString CreateTempName()
const char GetValue[]
#define ERRCTX_SFX_SAVEASDOC
constexpr auto SFX_INTERFACE_NONE
sal_uIntPtr sal_uLong
OUString VCL_DLLPUBLIC GetStandardText(StandardButtonType eButton)
sal_Int32 nDBRow
sw::mark::IMark * startPageInTarget
#define STR_SW_EVENT_MAIL_MERGE
Definition: swevent.hxx:28
#define STR_SW_EVENT_MAIL_MERGE_END
Definition: swevent.hxx:29
SwView * GetActiveView()
Definition: swmodul1.cxx:116
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
RET_OK
RET_CANCEL
RET_YES
size_t pos