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