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 m_bIsEmptyAllowed;
168 DECL_LINK( ModifyHdl, weld::Entry&, void);
169public:
170 SwSendQueryBox_Impl(weld::Window* pParent, const OUString& 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 m_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 OUString& rID,
213 const OUString& rUIXMLDescription)
214 : SwMessageAndEditDialog(pParent, rID, rUIXMLDescription)
215 , m_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(m_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 if (SwView* pView = GetActiveView())
268 {
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);
275 }
276
277 m_xOKButton->connect_clicked(LINK(this, SwMMResultSaveDialog, SaveOutputHdl_Impl));
278}
279
281{
282}
283
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"))
294{
295 m_xPrinterLB->make_sorted();
296
297 m_xPrinterLB->connect_changed(LINK(this, SwMMResultPrintDialog, PrinterChangeHdl_Impl));
298 m_xPrinterSettingsPB->connect_clicked(LINK(this, SwMMResultPrintDialog, PrinterSetupHdl_Impl));
299
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);
305
306 m_xOKButton->connect_clicked(LINK(this, SwMMResultPrintDialog, PrintHdl_Impl));
307
309}
310
312{
313}
314
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"))
334{
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 ));
339
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);
345
346 m_xOKButton->connect_clicked(LINK(this, SwMMResultEmailDialog, SendDocumentsHdl_Impl));
347
348 m_xPasswordCB->set_sensitive(false);
349 m_xPasswordFT->set_sensitive(false);
350 m_xPasswordLB->set_sensitive(false);
351
353}
354
356{
357}
358
360{
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;
369
370 for (unsigned int i = 0; i < nCount; ++i)
371 {
372 m_xPrinterLB->append_text( rPrinters[i] );
373 if( !bMergePrinterExists && rPrinters[i] == xConfigItem->GetSelectedPrinter() )
374 bMergePrinterExists = true;
375 }
376
377 assert(xConfigItem);
378 if(!bMergePrinterExists)
379 {
380 SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
381 m_xPrinterLB->set_active_text(pPrinter->GetName());
382 }
383 else
384 {
385 m_xPrinterLB->set_active_text(xConfigItem->GetSelectedPrinter());
386 }
387 PrinterChangeHdl_Impl(*m_xPrinterLB);
388
389 sal_Int32 count = xConfigItem->GetMergedDocumentCount();
390 m_xFromNF->set_max(count);
391 m_xToNF->set_value(count);
392 m_xToNF->set_max(count);
393}
394
396{
397 SwView* pView = GetActiveView();
398 if (!pView)
399 return;
400 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
401 assert(xConfigItem);
402
403 SwView* pSourceView = xConfigItem->GetSourceView();
404 OSL_ENSURE(pSourceView, "no source view exists");
405 if (pSourceView)
406 {
407 SwDocShell* pDocShell = pSourceView->GetDocShell();
408 if (pDocShell->HasName())
409 {
410 INetURLObject aTmp(pDocShell->GetMedium()->GetName());
411 m_xAttachmentED->set_text(aTmp.getName(
413 }
414 }
415
416 if (m_xAttachmentED->get_text().isEmpty())
417 {
418 OUString sAttach = "." + lcl_GetExtensionForDocType(m_xSendAsLB->get_active_id().toUInt32());
419 m_xAttachmentED->set_text(sAttach);
420
421 }
422
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();
430
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))
435 {
436 m_xMailToLB->append_text(rField);
437 m_xPasswordLB->append_text(rField);
438 }
439
440 m_xMailToLB->set_active(0);
441 m_xPasswordLB->set_active(0);
442
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);
451
452 // HTML format pre-selected
453 m_xSendAsLB->set_active(3);
454 SendTypeHdl_Impl(*m_xSendAsLB);
455
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);
460}
461
462IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
463{
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);
468}
469
471{
472 bool bEnable = m_xPasswordCB->get_active();
473
474 m_xPasswordFT->set_sensitive(bEnable);
475 m_xPasswordLB->set_sensitive(bEnable);
476}
477
478IMPL_LINK_NOARG(SwMMResultPrintDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
479{
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);
484}
485
486IMPL_LINK_NOARG(SwMMResultEmailDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
487{
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);
492}
493
495{
496 SwCopyToDialog aDlg(m_xDialog.get());
497 aDlg.SetCC(m_sCC );
498 aDlg.SetBCC(m_sBCC);
499 if (aDlg.run() == RET_OK)
500 {
501 m_sCC = aDlg.GetCC() ;
502 m_sBCC = aDlg.GetBCC();
503 }
504}
505
506namespace {
507
508int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
509{
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();
522 return page;
523}
524
525int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
526{
527 SwView* pTargetView = pConfigItem->GetTargetView();
528 assert( pTargetView );
529 SwWrtShell& shell = pTargetView->GetWrtShell();
530 shell.Push();
531 if (document < int(pConfigItem->GetMergedDocumentCount()) - 1)
532 {
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();
537 }
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
541 }
542 sal_uInt16 page;
543 if (!bIgnoreEmpty)
544 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
545 else
546 page = shell.GetPageNumSeqNonEmpty();
548 return page;
549}
550
551} // anonymous namespace
552
554{
555 SwView* pView = GetActiveView();
556 if (!pView)
557 return;
558 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
559 assert(xConfigItem);
560
561 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
562 sal_uInt32 nBegin = 0;
563 sal_uInt32 nEnd = nDocumentCount;
564
565 if (m_xFromRB->get_active())
566 {
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;
571 }
572
573 xConfigItem->SetBeginEnd(nBegin, nEnd);
574
575 if (!xConfigItem->GetTargetView())
577
578 SwView* pTargetView = xConfigItem->GetTargetView();
579 assert(pTargetView);
580
581 OUString sFilter;
582 OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
583 if (sPath.isEmpty())
584 {
585 // just return back to the dialog
586 return;
587 }
588
589 if (m_xSaveAsOneRB->get_active())
590 {
591 uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", sFilter) };
592
593 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
594 ErrCode nErrorCode = ERRCODE_NONE;
595 try
596 {
597 xStore->storeToURL( sPath, aValues );
598 }
599 catch (const task::ErrorCodeIOException& rErrorEx)
600 {
601 nErrorCode = ErrCode(rErrorEx.ErrCode);
602 }
603 catch (const Exception&)
604 {
605 nErrorCode = ERRCODE_IO_GENERAL;
606 }
607 if( nErrorCode != ERRCODE_NONE )
608 {
610 ErrorHandler::HandleError( nErrorCode );
611 }
612 }
613 else
614 {
615 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
618 std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
620 SwDocShell::Factory().GetFilterContainer() );
621
622 uno::Sequence< beans::PropertyValue > aValues(1);
623 beans::PropertyValue* pValues = aValues.getArray();
624 pValues[0].Name = "FilterName";
625 pValues[0].Value <<= pSfxFlt->GetFilterName();
626
627 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
628 ErrCode nErrorCode = ERRCODE_NONE;
629 try
630 {
631 xStore->storeToURL( sTargetTempURL, aValues );
632 }
633 catch (const task::ErrorCodeIOException& rErrorEx)
634 {
635 nErrorCode = ErrCode(rErrorEx.ErrCode);
636 }
637 catch (const Exception&)
638 {
639 nErrorCode = ERRCODE_IO_GENERAL;
640 }
641 if( nErrorCode != ERRCODE_NONE )
642 {
644 ErrorHandler::HandleError( nErrorCode );
645 }
646
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();
656 });
657
658 for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin && !m_bCancelSaving; ++nDoc)
659 {
660 INetURLObject aURL(sPath);
661 OUString sExtension = aURL.getExtension();
662 if (sExtension.isEmpty())
663 {
664 sExtension = pSfxFlt->GetWildcard().getGlob().getToken(1, '.');
665 sPath += "." + sExtension;
666 }
667 OUString sStat = SwResId(STR_STATSTR_LETTER) + " " + OUString::number(nDoc + 1);
668 xSaveMonitor->m_xPrintInfo->set_label(sStat);
669
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();
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 );
688
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));
696
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);
705
706 while(true)
707 {
708 //time for other slots is needed
710
711 bool bFailed = false;
712 try
713 {
714 pValues[0].Value <<= sFilter;
715 uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY);
716 xTempStore->storeToURL( sOutPath, aValues );
717 }
718 catch (const uno::Exception&)
719 {
720 bFailed = true;
721 }
722
723 if(bFailed)
724 {
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
729 {
730 xTempDocShell->DoClose();
731 m_xDialog->response(RET_OK);
732 return;
733 }
734 }
735 else
736 {
737 xTempDocShell->DoClose();
738 m_xDialog->response(RET_OK);
739 break;
740 }
741 }
742 }
743 if (xSaveMonitor)
744 xSaveMonitor->response(RET_OK);
745 ::osl::File::remove( sTargetTempURL );
746 }
747
748 m_xDialog->response(RET_OK);
749}
750
751IMPL_LINK(SwMMResultPrintDialog, PrinterChangeHdl_Impl, weld::ComboBox&, rBox, void)
752{
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)
759 {
760 const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false );
761
762 if( pInfo )
763 {
764 if ( !m_pTempPrinter )
765 {
766 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
767 }
768 else
769 {
770 if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
771 (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
772 {
773 m_pTempPrinter.disposeAndClear();
774 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
775 }
776 }
777 }
778 else if( ! m_pTempPrinter )
779 m_pTempPrinter = VclPtr<Printer>::Create();
780
781 m_xPrinterSettingsPB->set_sensitive(m_pTempPrinter->HasSupport(PrinterSupport::SetupDialog));
782 }
783 else
784 m_xPrinterSettingsPB->set_sensitive(false);
785
786 xConfigItem->SetSelectedPrinter(rBox.get_active_text());
787}
788
790{
791 SwView* pView = GetActiveView();
792 if (!pView)
793 return;
794 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
795 assert(xConfigItem);
796
797 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
798 sal_uInt32 nBegin = 0;
799 sal_uInt32 nEnd = nDocumentCount;
800
801 if (m_xFromRB->get_active())
802 {
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;
807 }
808
809 xConfigItem->SetBeginEnd(nBegin, nEnd);
810
811 if(!xConfigItem->GetTargetView())
813
814 SwView* pTargetView = xConfigItem->GetTargetView();
815 assert(pTargetView);
816
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 =
821 const int nStartPage = documentStartPageNumber(xConfigItem.get(), 0, bIgnoreEmptyPages);
822 const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - nBegin - 1, bIgnoreEmptyPages);
823
824 const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage));
825
826 pTargetView->SetMailMergeConfigItem(xConfigItem);
827 if(m_pTempPrinter)
828 {
829 SfxPrinter *const pDocumentPrinter = pTargetView->GetWrtShell()
831 pDocumentPrinter->SetPrinterProps(m_pTempPrinter);
832 // this should be able to handle setting its own printer
833 pTargetView->SetPrinter(pDocumentPrinter);
834 }
835
836 SfxObjectShell* pObjSh = pTargetView->GetViewFrame().GetObjectShell();
838
839 uno::Sequence aProps{ comphelper::makePropertyValue("MonitorVisible", true),
840 comphelper::makePropertyValue("Pages", sPages) };
841
842 pTargetView->ExecPrint( aProps, false, true );
843 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), pObjSh));
844
845 m_xDialog->response(RET_OK);
846}
847
849{
850 if (m_pTempPrinter)
851 m_pTempPrinter->Setup(m_xDialog.get());
852}
853
854IMPL_LINK(SwMMResultEmailDialog, SendTypeHdl_Impl, weld::ComboBox&, rBox, void)
855{
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)
862 {
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())
867 {
868 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
869 if( 2 > nTokenCount)
870 {
871 sAttach += ".";
872 ++nTokenCount;
873 }
874 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
875 m_xAttachmentED->set_text(sAttach);
876 }
877 }
878
879 if(bIsPDF)
880 {
881 m_xPasswordCB->set_sensitive(true);
882 m_xPasswordFT->set_sensitive(true);
883 m_xPasswordLB->set_sensitive(true);
884 CheckHdl(*m_xPasswordCB);
885 }
886 else
887 {
888 m_xPasswordCB->set_sensitive(false);
889 m_xPasswordFT->set_sensitive(false);
890 m_xPasswordLB->set_sensitive(false);
891 }
892}
893
895{
896 // work around crash when calling constructor with no active view
897 if (!GetActiveView())
898 {
899 SAL_WARN("sw", "ignoring SendAs button click, because no active view");
900 return;
901 }
902 SwMailBodyDialog aDlg(m_xDialog.get());
903 aDlg.SetBody(m_sBody);
904 if (RET_OK == aDlg.run())
905 {
906 m_sBody = aDlg.GetBody();
907 }
908}
909
910// Send documents as e-mail
912{
913 SwView* pView = GetActiveView();
914 if (!pView)
915 return;
916 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
917 assert(xConfigItem);
918
919 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
920 sal_uInt32 nBegin = 0;
921 sal_uInt32 nEnd = nDocumentCount;
922
923 if (m_xFromRB->get_active())
924 {
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;
929 }
930
931 xConfigItem->SetBeginEnd(nBegin, nEnd);
932
933 if (!xConfigItem->GetTargetView())
935
936 //get the composed document
937 SwView* pTargetView = xConfigItem->GetTargetView();
938 SAL_WARN_IF(!pTargetView, "sw.ui", "No TargetView in SwMailMergeConfigItem");
939
940 if (xConfigItem->GetMailServer().isEmpty() ||
941 !SwMailMergeHelper::CheckMailAddress(xConfigItem->GetMailAddress()) )
942 {
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 )
949 {
950 SwView* pConfigView = pTargetView ? pTargetView : pView;
951 SfxAllItemSet aSet(pConfigView->GetPool());
952 SwMailConfigDlg aDlg(m_xDialog.get(), aSet);
953 nRet = aDlg.run();
954 }
955
956 if(nRet != RET_OK && nRet != RET_YES)
957 return; // back to the dialog
958
959 // SwMailConfigDlg writes mail merge email settings only to (global) config,
960 // so copy them to the existing config item
962 }
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 )
971 {
972 case MM_DOCTYPE_OOO:
973 {
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);
979 }
980 break;
981 case MM_DOCTYPE_PDF:
982 {
983 pSfxFlt = pFilterContainer->GetFilter4FilterName(
984 "writer_pdf_Export",
985 SfxFilterFlags::EXPORT);
986 }
987 break;
988 case MM_DOCTYPE_WORD:
989 {
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 )
996 {
997 if( pFilter->GetUserData() == FILTER_WW8 && pFilter->CanExport() )
998 {
999 pSfxFlt = pFilter;
1000 break;
1001 }
1002 pFilter = aIter.Next();
1003 }
1004
1005 }
1006 break;
1007 case MM_DOCTYPE_HTML:
1008 {
1009 bAsBody = true;
1010 eEncoding = RTL_TEXTENCODING_UTF8;
1011 }
1012 break;
1013 case MM_DOCTYPE_TEXT:
1014 {
1015 bAsBody = true;
1016 pSfxFlt = pFilterContainer->GetFilter4FilterName(
1017 "Text (encoded)", SfxFilterFlags::EXPORT);
1018 }
1019 break;
1020 }
1021 if(!pSfxFlt)
1022 pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
1023
1024 if(!pSfxFlt)
1025 {
1026 m_xDialog->response(RET_OK);
1027 return;
1028 }
1029 OUString sMimeType = pSfxFlt->GetMimeType();
1030
1031 if (m_xSubjectED->get_text().isEmpty())
1032 {
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())
1038 {
1039 if (!xQuery->GetValue().isEmpty())
1040 m_xSubjectED->set_text(xQuery->GetValue());
1041 }
1042 else
1043 return; // back to the dialog
1044 }
1045 if(!bAsBody && m_xAttachmentED->get_text().isEmpty())
1046 {
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())
1051 {
1052 OUString sAttach(xQuery->GetValue());
1053 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
1054 if (2 > nTokenCount)
1055 {
1056 sAttach += ".";
1057 ++nTokenCount;
1058 }
1059 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType(
1060 m_xSendAsLB->get_active_id().toUInt32()));
1061 m_xAttachmentED->set_text(sAttach);
1062 }
1063 else
1064 return; // back to the dialog
1065 }
1066
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))
1072 {
1073 m_xDialog->response(RET_OK);
1074 return;
1075 }
1076
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))
1080 {
1081 m_xDialog->response(RET_OK);
1082 return;
1083 }
1084
1085 OUString sFilterOptions;
1086 if(MM_DOCTYPE_TEXT == nDocType)
1087 {
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 );
1095 }
1096 else if(MM_DOCTYPE_HTML == nDocType)
1097 {
1098 sFilterOptions = "EmbedImages";
1099 }
1100 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
1103 std::shared_ptr<const SfxFilter> pTargetSfxFlt = SwIoSystem::GetFilterOfFormat(
1104 FILTER_XML,
1105 SwDocShell::Factory().GetFilterContainer() );
1106
1107 uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", pTargetSfxFlt->GetFilterName()) };
1108
1109 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1110 xStore->storeToURL( sTargetTempURL, aValues );
1111
1112 //create the send dialog
1113 std::shared_ptr<SwSendMailDialog> xDlg = std::make_shared<SwSendMailDialog>(Application::GetDefDialogParent(), *xConfigItem);
1114
1115 xDlg->StartSend(nEnd - nBegin);
1116 weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){});
1117
1118 //help to force painting the dialog
1119 //TODO/CLEANUP
1120 //predetermined breaking point
1122 m_xDialog->response(RET_OK);
1123 for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin; ++nDoc)
1124 {
1125 SwDocMergeInfo& rInfo = xConfigItem->GetDocumentMergeInfo(nDoc);
1126
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();
1149
1150 //then save it
1151 SfxStringItem aName(SID_FILE_NAME,
1155
1156 {
1157 bool withFilterOptions = MM_DOCTYPE_TEXT == nDocType || MM_DOCTYPE_HTML == nDocType;
1158 bool withPasswordOptions = m_xPasswordCB->get_active();
1159
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);
1163
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();
1168
1169 pFilterValues[nOpt].Name = "FilterName";
1170 pFilterValues[nOpt].Value <<= pSfxFlt->GetFilterName();
1171
1172 if(withFilterOptions)
1173 {
1174 nOpt++;
1175 pFilterValues[nOpt].Name = "FilterOptions";
1176 pFilterValues[nOpt].Value <<= sFilterOptions;
1177 }
1178
1179 if(withPasswordOptions)
1180 {
1181 nOpt++;
1182 pFilterValues[nOpt].Name = "EncryptFile";
1183 pFilterValues[nOpt].Value <<= true;
1184 nOpt++;
1185 pFilterValues[nOpt].Name = "DocumentOpenPassword";
1186 pFilterValues[nOpt].Value <<= sPassword;
1187 }
1188
1189 uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1190 xTempStore->storeToURL( aName.GetValue(), aFilterValues );
1191 }
1192 xTempDocShell->DoClose();
1193
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)
1202 {
1203 {
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
1210 {
1211 OSL_FAIL("no output file created?");
1212 continue;
1213 }
1214 OStringBuffer sLine;
1215 bool bDone = pInStream->ReadLine( sLine );
1216 while ( bDone )
1217 {
1218 sBody.append( OStringToOUString(sLine, eEncoding) + "\n");
1219 bDone = pInStream->ReadLine( sLine );
1220 }
1221 }
1222 //remove the temporary file
1223 SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
1224 }
1225 else
1226 {
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)
1232 {
1233 sAttachment += ".";
1234 sAttachment = comphelper::string::setToken(sAttachment, nTokenCount, '.', sExtension);
1235 }
1236 else if (o3tl::getToken(sAttachment, nTokenCount - 1, '.') != sExtension)
1237 sAttachment += sExtension;
1238 aDesc.sAttachmentName = sAttachment;
1239 aDesc.sMimeType = sMimeType;
1240
1241 if (xConfigItem->IsGreetingLine(true))
1242 {
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))
1247 {
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 ?
1254
1255 sGreeting = SwAddressPreview::FillData(
1256 xConfigItem->GetGreetings(eGenderType)
1257 [xConfigItem->GetCurrentGreeting(eGenderType)],
1258 *xConfigItem);
1259 }
1260 else
1261 {
1262 sGreeting =
1263 xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL)
1264 [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];
1265
1266 }
1267 sGreeting += "\n";
1268 sBody.insert(0, sGreeting);
1269 }
1270 }
1271 aDesc.sBodyContent = sBody.makeStringAndClear();
1272 if(MM_DOCTYPE_HTML == nDocType)
1273 {
1274 aDesc.sBodyMimeType = "text/html; charset=" +
1275 OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
1276 }
1277 else
1278 aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
1279
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
1286 //stop creating of data when dialog has been closed
1287 if (!xDlg->getDialog()->get_visible())
1288 {
1289 break;
1290 }
1291 }
1292 xDlg->EnableDestruction();
1293 ::osl::File::remove( sTargetTempURL );
1294}
1295
1296/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
SfxApplication * SfxGetpApp()
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static bool Reschedule(bool bHandleAllCurrentEvents=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:559
void SetLanguage(LanguageType nVal)
Definition: shellio.hxx:80
void SetParaFlags(LineEnd eVal)
Definition: shellio.hxx:83
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:3214
ErrCode LoadStylesFromFile(const OUString &rURL, SwgReaderOption &rOpt, bool bUnoCall)
Definition: docsh2.cxx:1607
static OUString GetEventName(sal_Int32 nId)
Definition: docsh.cxx:1327
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
void ReplaceDefaults(const SwDoc &rSource)
Definition: docnew.cxx:851
void ReplaceCompatibilityOptions(const SwDoc &rSource)
Definition: docnew.cxx:881
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:252
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:1140
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:2819
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
virtual sal_uInt16 SetPrinter(SfxPrinter *pNew, SfxPrinterChangeFlags nDiff=SFX_PRINTER_ALL) override
Definition: viewprt.cxx:99
std::shared_ptr< SwMailMergeConfigItem > const & GetMailMergeConfigItem() const
Definition: view0.cxx:135
SwDocShell * GetDocShell()
Definition: view.cxx:1193
void SetMailMergeConfigItem(std::shared_ptr< SwMailMergeConfigItem > const &rConfigItem)
Definition: view0.cxx:129
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
void SetNumRules(const bool bNew)
Definition: shellio.hxx:126
void SetTextFormats(const bool bNew)
Definition: shellio.hxx:123
void SetMerge(const bool bNew)
Definition: shellio.hxx:129
void SetPageDescs(const bool bNew)
Definition: shellio.hxx:120
void SetFrameFormats(const bool bNew)
Definition: shellio.hxx:117
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
OUString sName
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:184
std::unique_ptr< weld::Button > m_xOKButton
LanguageType GetAppLanguage()
Definition: init.cxx:741
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)
#define SAL_WARN(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)
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:365
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:115
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
RET_OK
RET_CANCEL
RET_YES
size_t pos