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