LibreOffice Module sw (master)  1
mmconfigitem.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 
21 #include <mmconfigitem.hxx>
22 #include <vector>
23 #include <swtypes.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/frame/XDispatch.hpp>
27 #include <com/sun/star/sdbc/XDataSource.hpp>
28 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/sdbc/XRowSet.hpp>
32 #include <com/sun/star/view/XSelectionSupplier.hpp>
34 #include <comphelper/types.hxx>
35 #include <com/sun/star/sdb/CommandType.hpp>
36 #include <comphelper/sequence.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <sal/log.hxx>
39 #include <unotools/configitem.hxx>
40 #include <tools/diagnose_ex.h>
41 #include <mailmergehelper.hxx>
42 #include <swunohelper.hxx>
43 #include <dbmgr.hxx>
44 #include <view.hxx>
45 #include <unodispatch.hxx>
46 #include <wrtsh.hxx>
47 #include <dbui.hrc>
48 
49 using namespace utl;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::sdb;
55 using namespace ::com::sun::star::sdbc;
56 using namespace ::com::sun::star::sdbcx;
57 
58 constexpr OUStringLiteral cAddressDataAssignments = u"AddressDataAssignments";
59 const char cDBColumnAssignments[] = "DBColumnAssignments";
60 const char cDataSourceName[] = "DataSource/DataSourceName";
61 const char cDataTableName[] = "DataSource/DataTableName" ;
62 const char cDataCommandType[] = "DataSource/DataCommandType";
63 
64 #define SECURE_PORT 587
65 #define DEFAULT_PORT 25
66 #define POP_PORT 110
67 #define POP_SECURE_PORT 995
68 #define IMAP_PORT 143
69 #define IMAP_SECURE_PORT 993
70 
71 namespace {
72 
73 struct DBAddressDataAssignment
74 {
75  SwDBData aDBData;
76  Sequence< OUString> aDBColumnAssignments;
77  //if loaded the name of the node has to be saved
78  OUString sConfigNodeName;
79  //all created or changed assignments need to be stored
80  bool bColumnAssignmentsChanged;
81 
82  DBAddressDataAssignment() :
83  bColumnAssignmentsChanged(false)
84  {}
85 };
86 
87 }
88 
90 {
91  friend class SwMailMergeConfigItem;
94  Reference< XColumnsSupplier> m_xColumnsSupplier;
95  Reference< XResultSet> m_xResultSet;
97  OUString m_sFilter;
99 
100  std::vector<DBAddressDataAssignment> m_aAddressDataAssignments;
101  std::vector< OUString> m_aAddressBlocks;
105 
109 
112  std::vector< OUString> m_aFemaleGreetingLines;
114  std::vector< OUString> m_aMaleGreetingLines;
116  std::vector< OUString> m_aNeutralGreetingLines;
119  uno::Sequence< OUString> m_aSavedDocuments;
120 
123 
124  //mail settings
126  OUString m_sMailAddress;
127  OUString m_sMailReplyTo;
128  OUString m_sMailServer;
129  OUString m_sMailUserName;
130  OUString m_sMailPassword;
131 
133  OUString m_sInServerName;
134  sal_Int16 m_nInServerPort;
138 
139  sal_Int16 m_nMailPort;
143 
145 
146  std::vector<std::pair<OUString, int>> m_AddressHeaderSA;
147 
148  //these addresses are not stored in the configuration
149  std::vector< SwDocMergeInfo > m_aMergeInfos;
150 
151  //we do overwrite the usersettings in a special case
152  //then we do remind the usersettings here
157 
158  static const Sequence< OUString>& GetPropertyNames();
159 
160  virtual void ImplCommit() override;
161 
162 public:
164 
165  virtual void Notify( const css::uno::Sequence< OUString >& aPropertyNames ) override;
166  Sequence< OUString> GetAddressBlocks(bool bConvertToConfig = false) const;
167  void SetAddressBlocks(
168  const Sequence< OUString>& rBlocks,
169  bool bConvertFromConfig = false);
170  uno::Sequence< OUString>
172  bool bConvertToConfig = false) const;
174  const uno::Sequence< OUString>& rBlocks,
175  bool bConvertFromConfig = false);
176 
177  void SetCurrentAddressBlockIndex( sal_Int32 nSet );
178  sal_Int32 GetCurrentAddressBlockIndex() const
179  { return m_nCurrentAddressBlock; }
180  sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const;
181  void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex);
182 
183 };
184 
186  ConfigItem("Office.Writer/MailMergeWizard", ConfigItemMode::NONE),
187  m_nResultSetCursorPos(-1),
188  m_nCurrentAddressBlock(0),
189  m_bIsAddressBlock(true),
190  m_bIsHideEmptyParagraphs(false),
191  m_bIsOutputToLetter(true),
192  m_bIncludeCountry(false),
193  m_bIsGreetingLine(true),
194  m_bIsIndividualGreetingLine(false),
195  m_nCurrentFemaleGreeting(0),
196  m_nCurrentMaleGreeting(0),
197  m_nCurrentNeutralGreeting(0),
198  m_bIsGreetingLineInMail(false),
199  m_bIsIndividualGreetingLineInMail(false),
200  m_bIsSMPTAfterPOP(false),
201  m_nInServerPort( POP_SECURE_PORT ),
202  m_bInServerPOP( true ),
203  m_nMailPort(SECURE_PORT),
204  m_bIsMailReplyTo(false),
205  m_bIsSecureConnection(true),
206  m_bIsAuthentication(false),
207 
208  m_bIsEMailSupported(false),
209  m_bUserSettingWereOverwritten(false),
210  m_bIsAddressBlock_LastUserSetting(false),
211  m_bIsGreetingLineInMail_LastUserSetting(false),
212  m_bIsGreetingLine_LastUserSetting(false)
213 {
214  for (size_t i = 0; i < SAL_N_ELEMENTS(SA_ADDRESS_HEADER); ++i)
215  {
216  m_AddressHeaderSA.emplace_back(SwResId(SA_ADDRESS_HEADER[i].first), SA_ADDRESS_HEADER[i].second);
217  }
218 
219  const Sequence<OUString>& rNames = GetPropertyNames();
220  Sequence<Any> aValues = GetProperties(rNames);
221  const Any* pValues = aValues.getConstArray();
222  assert(aValues.getLength() == rNames.getLength());
223  if(aValues.getLength() == rNames.getLength())
224  {
225  for(int nProp = 0; nProp < rNames.getLength(); nProp++)
226  {
227  switch(nProp)
228  {
229  case 0: pValues[nProp] >>= m_bIsOutputToLetter; break;
230  case 1: pValues[nProp] >>= m_bIncludeCountry; break;
231  case 2: pValues[nProp] >>= m_sExcludeCountry; break;
232  case 3:
233  {
234  Sequence< OUString> aBlocks;
235  pValues[nProp] >>= aBlocks;
236  SetAddressBlocks(aBlocks, true);
237  }
238  break;
239  case 4: pValues[nProp] >>= m_bIsAddressBlock; break;
240  case 5: pValues[nProp] >>= m_bIsGreetingLine; break;
241  case 6: pValues[nProp] >>= m_bIsIndividualGreetingLine; break;
242  case 7 :
243  case 8 :
244  case 9 :
245  {
246  Sequence< OUString> aGreetings;
247  pValues[nProp] >>= aGreetings;
249  SwMailMergeConfigItem::FEMALE + nProp - 7), aGreetings, true);
250  }
251  break;
252 
253  case 10: pValues[nProp] >>= m_nCurrentFemaleGreeting; break;
254  case 11: pValues[nProp] >>= m_nCurrentMaleGreeting; break;
255  case 12: pValues[nProp] >>= m_nCurrentNeutralGreeting; break;
256  case 13: pValues[nProp] >>= m_sFemaleGenderValue; break;
257  case 14: pValues[nProp] >>= m_sMailDisplayName; break;
258  case 15: pValues[nProp] >>= m_sMailAddress; break;
259  case 16: pValues[nProp] >>= m_bIsMailReplyTo; break;
260  case 17: pValues[nProp] >>= m_sMailReplyTo; break;
261  case 18: pValues[nProp] >>= m_sMailServer; break;
262  case 19: pValues[nProp] >>= m_nMailPort; break;
263  case 20: pValues[nProp] >>= m_bIsSecureConnection; break;
264  case 21: pValues[nProp] >>= m_bIsAuthentication; break;
265  case 22: pValues[nProp] >>= m_sMailUserName; break;
266  case 23: pValues[nProp] >>= m_sMailPassword; break;
267  case 24 :pValues[nProp] >>= m_aDBData.sDataSource; break;
268  case 25 :pValues[nProp] >>= m_aDBData.sCommand; break;
269  case 26 :
270  {
271  short nTemp = 0;
272  if(pValues[nProp] >>= nTemp)
273  m_aDBData.nCommandType = nTemp;
274  }
275  break;
276  case 27: pValues[nProp] >>= m_sFilter; break;
277  case 28: pValues[nProp] >>= m_aSavedDocuments; break;
278  case 29:
279  pValues[nProp] >>= m_bIsEMailSupported;
280  break;
281  case 30: pValues[nProp] >>= m_bIsGreetingLineInMail; break;
282  case 31: pValues[nProp] >>= m_bIsIndividualGreetingLineInMail; break;
283  case 32: pValues[nProp] >>= m_bIsSMPTAfterPOP; break;
284  case 33: pValues[nProp] >>= m_sInServerName; break;
285  case 34: pValues[nProp] >>= m_nInServerPort; break;
286  case 35: pValues[nProp] >>= m_bInServerPOP; break;
287  case 36: pValues[nProp] >>= m_sInServerUserName; break;
288  case 37: pValues[nProp] >>= m_sInServerPassword; break;
289  case 38: pValues[nProp] >>= m_bIsHideEmptyParagraphs; break;
290  case 39: pValues[nProp] >>= m_nCurrentAddressBlock; break;
291  }
292  }
293  ClearModified();
294  }
295  //read the list of data base assignments
297  if(aAssignments.hasElements())
298  {
299  //create a list of property names to load the URLs of all data bases
300  const OUString* pAssignments = aAssignments.getConstArray();
301  Sequence< OUString > aAssignProperties(4 * aAssignments.getLength());
302  OUString* pAssignProperties = aAssignProperties.getArray();
303  sal_Int32 nAssign;
304  for(nAssign = 0; nAssign < aAssignProperties.getLength(); nAssign += 4)
305  {
306  OUString sAssignPath = OUString::Concat(cAddressDataAssignments) +
307  "/" +
308  pAssignments[nAssign / 4] +
309  "/";
310  pAssignProperties[nAssign] = sAssignPath;
311  pAssignProperties[nAssign] += cDataSourceName;
312  pAssignProperties[nAssign + 1] = sAssignPath;
313  pAssignProperties[nAssign + 1] += cDataTableName;
314  pAssignProperties[nAssign + 2] = sAssignPath;
315  pAssignProperties[nAssign + 2] += cDataCommandType;
316  pAssignProperties[nAssign + 3] = sAssignPath;
317  pAssignProperties[nAssign + 3] += cDBColumnAssignments;
318  }
319  Sequence<Any> aAssignValues = GetProperties(aAssignProperties);
320  const Any* pAssignValues = aAssignValues.getConstArray();
321  for(nAssign = 0; nAssign < aAssignValues.getLength(); nAssign += 4 )
322  {
323  DBAddressDataAssignment aAssignment;
324  pAssignValues[nAssign] >>= aAssignment.aDBData.sDataSource;
325  pAssignValues[nAssign + 1] >>= aAssignment.aDBData.sCommand;
326  pAssignValues[nAssign + 2] >>= aAssignment.aDBData.nCommandType;
327  pAssignValues[nAssign + 3] >>= aAssignment.aDBColumnAssignments;
328  aAssignment.sConfigNodeName = pAssignments[nAssign / 4];
329  m_aAddressDataAssignments.push_back(aAssignment);
330  }
331  }
332  //check if the saved documents still exist
333  if(m_aSavedDocuments.hasElements())
334  {
335  uno::Sequence< OUString > aTempDocuments(m_aSavedDocuments.getLength());
336  auto begin = aTempDocuments.getArray();
337  OUString* pTempDocuments = std::copy_if(std::cbegin(m_aSavedDocuments), std::cend(m_aSavedDocuments), begin,
338  [](const OUString& rDoc) { return SWUnoHelper::UCB_IsFile( rDoc ); });
339  sal_Int32 nIndex = static_cast<sal_Int32>(std::distance(begin, pTempDocuments));
340  if(nIndex < m_aSavedDocuments.getLength())
341  {
342  m_aSavedDocuments.swap(aTempDocuments);
343  m_aSavedDocuments.realloc(nIndex);
344  }
345  }
346 }
347 
349 {
350  if(m_aAddressBlocks.size() >= sal::static_int_cast<sal_uInt32, sal_Int32>(nSet))
351  {
352  m_nCurrentAddressBlock = nSet;
353  SetModified();
354  }
355 }
356 
357 static OUString lcl_CreateNodeName(Sequence<OUString>& rAssignments )
358 {
359  sal_Int32 nStart = rAssignments.getLength();
360  OUString sNewName;
361  //search if the name exists
362  while(true)
363  {
364  sNewName = "_" + OUString::number(nStart++);
365  if(comphelper::findValue(rAssignments, sNewName) == -1)
366  break;
367  }
368  // add the new name to the array of existing names
369  rAssignments.realloc(rAssignments.getLength() + 1);
370  rAssignments.getArray()[rAssignments.getLength() - 1] = sNewName;
371  return sNewName;
372 }
373 
374 static void lcl_ConvertToNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders )
375 {
376  //convert the strings used for UI to numbers used for the configuration
377  OUString sBlock(rBlock.replaceAll("\n", "\\n"));
378  for (size_t i = 0; i < rHeaders.size(); ++i)
379  {
380  OUString sHeader = "<" + rHeaders[i].first + ">";
381  OUString sReplace = "<" + OUStringChar(sal_Unicode('0' + i)) + ">";
382  sBlock = sBlock.replaceAll(sHeader, sReplace);
383  }
384  rBlock = sBlock;
385 }
386 
387 static void lcl_ConvertFromNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders)
388 {
389  //convert the numbers used for the configuration to strings used for UI to numbers
390  //doesn't use ReplaceAll to prevent expansion of numbers inside of the headers
391  SwAddressIterator aGreetingIter(rBlock.replaceAll("\\n", "\n"));
392  OUStringBuffer sBlock;
393  while(aGreetingIter.HasMore())
394  {
395  SwMergeAddressItem aNext = aGreetingIter.Next();
396  if(aNext.bIsColumn)
397  {
398  //the text should be 1 characters long
399  sal_Unicode cChar = aNext.sText[0];
400  if(cChar >= '0' && cChar <= 'c')
401  {
402  sBlock.append("<");
403  sal_uInt16 nHeader = cChar - '0';
404  if(nHeader < rHeaders.size())
405  sBlock.append(rHeaders[nHeader].first);
406  sBlock.append(">");
407  }
408  else
409  {
410  SAL_WARN("sw.ui", "parse error in address block or greeting line");
411  }
412  }
413  else
414  sBlock.append(aNext.sText);
415  }
416  rBlock = sBlock.makeStringAndClear();
417 }
418 
420 {
421  static Sequence<OUString> aNames {
422  "OutputToLetter", // 0
423  "IncludeCountry", // 1
424  "ExcludeCountry", // 2
425  "AddressBlockSettings", // 3
426  "IsAddressBlock", // 4
427  "IsGreetingLine", // 5
428  "IsIndividualGreetingLine", // 6
429  "FemaleGreetingLines", // 7
430  "MaleGreetingLines", // 8
431  "NeutralGreetingLines", // 9
432  "CurrentFemaleGreeting", // 10
433  "CurrentMaleGreeting", // 11
434  "CurrentNeutralGreeting", // 12
435  "FemaleGenderValue", // 13
436  "MailDisplayName", // 14
437  "MailAddress", // 15
438  "IsMailReplyTo", // 16
439  "MailReplyTo", // 17
440  "MailServer", // 18
441  "MailPort", // 19
442  "IsSecureConnection", // 20
443  "IsAuthentication", // 21
444  "MailUserName", // 22
445  "MailPassword", // 23
446  "DataSource/DataSourceName", // 24
447  "DataSource/DataTableName", // 25
448  "DataSource/DataCommandType",// 26
449  "Filter", // 27
450  "SavedDocuments", // 28
451  "EMailSupported", // 29
452  "IsEMailGreetingLine", //30
453  "IsEMailIndividualGreetingLine", //31
454  "IsSMPTAfterPOP", //32
455  "InServerName", //33
456  "InServerPort", //34
457  "InServerIsPOP", //35
458  "InServerUserName", //36
459  "InServerPassword", //37
460  "IsHideEmptyParagraphs", //38
461  "CurrentAddressBlock" //39
462  };
463  return aNames;
464 }
465 
466 void SwMailMergeConfigItem_Impl::Notify( const css::uno::Sequence< OUString >& ) {}
467 
469 {
471  Sequence<Any> aValues(aNames.getLength());
472  Any* pValues = aValues.getArray();
473 
474  for(int nProp = 0; nProp < aNames.getLength(); nProp++)
475  {
476  switch(nProp)
477  {
478  case 0: pValues[nProp] <<= m_bIsOutputToLetter; break;
479  case 1: pValues[nProp] <<= m_bIncludeCountry; break;
480  case 2: pValues[nProp] <<= m_sExcludeCountry; break;
481  case 3: pValues[nProp] <<= GetAddressBlocks(true); break;
482  case 4:
483  {
485  pValues[nProp] <<= m_bIsAddressBlock_LastUserSetting;
486  else
487  pValues[nProp] <<= m_bIsAddressBlock;
488  break;
489  }
490  case 5:
491  {
493  pValues[nProp] <<= m_bIsGreetingLine_LastUserSetting;
494  else
495  pValues[nProp] <<= m_bIsGreetingLine;
496  break;
497  }
498  case 6: pValues[nProp] <<= m_bIsIndividualGreetingLine; break;
499  case 7:
500  case 8:
501  case 9:
502  pValues[nProp] <<= GetGreetings(
504  SwMailMergeConfigItem::FEMALE + nProp - 7), true);
505  break;
506  case 10: pValues[nProp] <<= m_nCurrentFemaleGreeting; break;
507  case 11: pValues[nProp] <<= m_nCurrentMaleGreeting; break;
508  case 12: pValues[nProp] <<= m_nCurrentNeutralGreeting; break;
509  case 13: pValues[nProp] <<= m_sFemaleGenderValue; break;
510  case 14: pValues[nProp] <<= m_sMailDisplayName; break;
511  case 15: pValues[nProp] <<= m_sMailAddress; break;
512  case 16: pValues[nProp] <<= m_bIsMailReplyTo; break;
513  case 17: pValues[nProp] <<= m_sMailReplyTo; break;
514  case 18: pValues[nProp] <<= m_sMailServer; break;
515  case 19: pValues[nProp] <<= m_nMailPort; break;
516  case 20: pValues[nProp] <<= m_bIsSecureConnection; break;
517  case 21: pValues[nProp] <<= m_bIsAuthentication; break;
518  case 22: pValues[nProp] <<= m_sMailUserName; break;
519  case 23: pValues[nProp] <<= m_sMailPassword; break;
520  case 24 :pValues[nProp] <<= m_aDBData.sDataSource; break;
521  case 25 :pValues[nProp] <<= m_aDBData.sCommand; break;
522  case 26 :pValues[nProp] <<= m_aDBData.nCommandType; break;
523  case 27 :pValues[nProp] <<= m_sFilter; break;
524  case 28 :pValues[nProp] <<= m_aSavedDocuments; break;
525  case 29: pValues[nProp] <<= m_bIsEMailSupported; break;
526  case 30:
527  {
529  pValues[nProp] <<= m_bIsGreetingLineInMail_LastUserSetting;
530  else
531  pValues[nProp] <<= m_bIsGreetingLineInMail;
532  break;
533  }
534  case 31: pValues[nProp] <<= m_bIsIndividualGreetingLineInMail; break;
535  case 32: pValues[nProp] <<= m_bIsSMPTAfterPOP; break;
536  case 33: pValues[nProp] <<= m_sInServerName; break;
537  case 34: pValues[nProp] <<= m_nInServerPort; break;
538  case 35: pValues[nProp] <<= m_bInServerPOP; break;
539  case 36: pValues[nProp] <<= m_sInServerUserName; break;
540  case 37: pValues[nProp] <<= m_sInServerPassword; break;
541  case 38: pValues[nProp] <<= m_bIsHideEmptyParagraphs; break;
542  case 39: pValues[nProp] <<= m_nCurrentAddressBlock; break;
543  }
544  }
545  PutProperties(aNames, aValues);
546  //store the changed / new assignments
547 
548  //load the existing node names to find new names
550 
551  for(const auto& rAssignment : m_aAddressDataAssignments)
552  {
553  if(rAssignment.bColumnAssignmentsChanged)
554  {
555  //create a new node name
556  OUString sNewNode = !rAssignment.sConfigNodeName.isEmpty() ?
557  rAssignment.sConfigNodeName :
558  lcl_CreateNodeName(aAssignments);
559  OUString sSlash = "/";
560  OUString sNodePath = cAddressDataAssignments + sSlash + sNewNode + sSlash;
561  //only one new entry is written
562  Sequence< PropertyValue > aNewValues(4);
563  PropertyValue* pNewValues = aNewValues.getArray();
564  pNewValues[0].Name = sNodePath;
565  pNewValues[0].Name += cDataSourceName;
566  pNewValues[0].Value <<= rAssignment.aDBData.sDataSource;
567  pNewValues[1].Name = sNodePath;
568  pNewValues[1].Name += cDataTableName;
569  pNewValues[1].Value <<= rAssignment.aDBData.sCommand;
570  pNewValues[2].Name = sNodePath;
571  pNewValues[2].Name += cDataCommandType;
572  pNewValues[2].Value <<= rAssignment.aDBData.nCommandType;
573  pNewValues[3].Name = sNodePath;
574  pNewValues[3].Name += cDBColumnAssignments;
575  pNewValues[3].Value <<= rAssignment.aDBColumnAssignments;
576 
578  }
579  }
580 
582 }
583 
585  bool bConvertToConfig) const
586 {
588  std::transform(m_aAddressBlocks.begin(), m_aAddressBlocks.end(), aRet.getArray(),
589  [this, bConvertToConfig](const OUString& rBlock) -> OUString {
590  OUString sBlock = rBlock;
591  if(bConvertToConfig)
593  return sBlock;
594  });
595  return aRet;
596 }
597 
599  const Sequence< OUString>& rBlocks,
600  bool bConvertFromConfig)
601 {
602  m_aAddressBlocks.clear();
603  std::transform(rBlocks.begin(), rBlocks.end(), std::back_inserter(m_aAddressBlocks),
604  [this, bConvertFromConfig](const OUString& rBlock) -> OUString {
605  OUString sBlock = rBlock;
606  if(bConvertFromConfig)
608  return sBlock;
609  });
611  SetModified();
612 }
613 
615  SwMailMergeConfigItem::Gender eType, bool bConvertToConfig) const
616 {
617  const std::vector< OUString>& rGreetings =
621  Sequence< OUString> aRet(rGreetings.size());
622  std::transform(rGreetings.begin(), rGreetings.end(), aRet.getArray(),
623  [this, bConvertToConfig](const OUString& rGreeting) -> OUString {
624  OUString sGreeting = rGreeting;
625  if(bConvertToConfig)
627  return sGreeting;
628  });
629  return aRet;
630 }
631 
634  const Sequence< OUString>& rSetGreetings,
635  bool bConvertFromConfig)
636 {
637  std::vector< OUString>& rGreetings =
641 
642  rGreetings.clear();
643  std::transform(rSetGreetings.begin(), rSetGreetings.end(), std::back_inserter(rGreetings),
644  [this, bConvertFromConfig](const OUString& rGreeting) -> OUString {
645  OUString sGreeting = rGreeting;
646  if(bConvertFromConfig)
648  return sGreeting;
649  });
650  SetModified();
651 }
652 
654  SwMailMergeConfigItem::Gender eType) const
655 {
656  sal_Int32 nRet;
657  switch(eType)
658  {
661  default: nRet = m_nCurrentNeutralGreeting; break;
662  }
663  return nRet;
664 }
665 
667  SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
668 {
669  bool bChanged = false;
670  switch(eType)
671  {
673  bChanged = m_nCurrentFemaleGreeting != nIndex;
674  m_nCurrentFemaleGreeting = nIndex;
675  break;
677  bChanged = m_nCurrentMaleGreeting != nIndex;
678  m_nCurrentMaleGreeting = nIndex;
679  break;
680  default:
681  bChanged = m_nCurrentNeutralGreeting != nIndex;
682  m_nCurrentNeutralGreeting = nIndex;
683  }
684  if(bChanged)
685  SetModified();
686 }
687 
690  m_bAddressInserted(false),
691  m_bGreetingInserted(false),
692  m_nGreetingMoves(0),
693  m_nBegin(0),
694  m_nEnd(0),
695  m_pSourceView(nullptr),
696  m_pTargetView(nullptr)
697 {
698 }
699 
701 {
702  if (m_xDBChangedListener.is())
703  {
704  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
705  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
706  m_xDBChangedListener.clear();
707  }
708 }
709 
711 {
712  const SwDBData& rDBData = m_pSourceView->GetWrtShell().GetDBData();
713  SetCurrentDBData(rDBData);
714 }
715 
717 {
719 }
720 
722 {
723  if(m_pImpl->IsModified())
724  m_pImpl->Commit();
725 }
726 
727 const std::vector<std::pair<OUString, int>>& SwMailMergeConfigItem::GetDefaultAddressHeaders() const
728 {
729  return m_pImpl->m_AddressHeaderSA;
730 }
731 
733  const Sequence< OUString>& rBlocks)
734 {
735  m_pImpl->SetAddressBlocks(rBlocks);
736 }
737 
739 {
740  return m_pImpl->GetAddressBlocks();
741 }
742 
744 {
745  return m_pImpl->m_bIsAddressBlock && IsOutputToLetter();
746 }
747 
749 {
750  m_pImpl->m_bUserSettingWereOverwritten = false;
751  if(m_pImpl->m_bIsAddressBlock != bSet)
752  {
753  m_pImpl->m_bIsAddressBlock = bSet;
754  m_pImpl->SetModified();
755  }
756 }
757 
759 {
760  return m_pImpl->m_bIsHideEmptyParagraphs;
761 }
762 
764 {
765  if(m_pImpl->m_bIsHideEmptyParagraphs != bSet)
766  {
767  m_pImpl->m_bIsHideEmptyParagraphs = bSet;
768  m_pImpl->SetModified();
769  }
770 }
771 
773 {
774  return m_pImpl->m_bIncludeCountry;
775 }
776 
778 {
779  return m_pImpl->m_sExcludeCountry;
780 }
781 
782 void SwMailMergeConfigItem::SetCountrySettings(bool bSet, const OUString& rCountry)
783 {
784  if(m_pImpl->m_sExcludeCountry != rCountry ||
785  m_pImpl->m_bIncludeCountry != bSet)
786  {
787  m_pImpl->m_bIncludeCountry = bSet;
788  m_pImpl->m_sExcludeCountry = bSet ? rCountry : OUString();
789  m_pImpl->SetModified();
790  }
791 }
792 
794  Reference< XDataSource> const & xSource,
795  const SharedConnection& rConnection,
796  Reference< XColumnsSupplier> const & xColumnsSupplier,
797  const SwDBData& rDBData)
798 {
799  m_pImpl->m_xSource = xSource ;
800  m_pImpl->m_xConnection = rConnection ;
801  m_pImpl->m_xColumnsSupplier = xColumnsSupplier;
802  m_pImpl->m_aDBData = rDBData;
803  m_pImpl->m_xResultSet = nullptr;
804  m_pImpl->m_nResultSetCursorPos = 0;
805  m_pImpl->SetModified();
806 }
807 
809 {
810  return m_pImpl->m_xSource;
811 }
812 
814 {
815  return m_pImpl->m_xConnection;
816 }
817 
818 Reference< XColumnsSupplier> const & SwMailMergeConfigItem::GetColumnsSupplier()
819 {
820  if(!m_pImpl->m_xColumnsSupplier.is() && m_pImpl->m_xConnection.is())
821  {
822  m_pImpl->m_xColumnsSupplier = SwDBManager::GetColumnSupplier(m_pImpl->m_xConnection,
823  m_pImpl->m_aDBData.sCommand,
824  m_pImpl->m_aDBData.nCommandType == CommandType::TABLE ?
826  }
827  return m_pImpl->m_xColumnsSupplier;
828 }
829 
831 {
832  return m_pImpl->m_aDBData;
833 }
834 
836 {
837  if(m_pImpl->m_aDBData != rDBData)
838  {
839  m_pImpl->m_aDBData = rDBData;
840  m_pImpl->m_xConnection.clear();
841  m_pImpl->m_xSource = nullptr;
842  m_pImpl->m_xResultSet = nullptr;
843  m_pImpl->m_xColumnsSupplier = nullptr;
844  m_pImpl->SetModified();
845  }
846 }
847 
848 Reference< XResultSet> const & SwMailMergeConfigItem::GetResultSet() const
849 {
850  if(!m_pImpl->m_xConnection.is() && !m_pImpl->m_aDBData.sDataSource.isEmpty())
851  {
852  m_pImpl->m_xConnection.reset(
853  SwDBManager::GetConnection(m_pImpl->m_aDBData.sDataSource, m_pImpl->m_xSource, m_pSourceView),
855  );
856  }
857  if(!m_pImpl->m_xResultSet.is() && m_pImpl->m_xConnection.is())
858  {
859  try
860  {
861  Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
862 
863  Reference<XRowSet> xRowSet( xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY );
864  Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
865  xRowProperties->setPropertyValue("DataSourceName", makeAny(m_pImpl->m_aDBData.sDataSource));
866  xRowProperties->setPropertyValue("Command", makeAny(m_pImpl->m_aDBData.sCommand));
867  xRowProperties->setPropertyValue("CommandType", makeAny(m_pImpl->m_aDBData.nCommandType));
868  xRowProperties->setPropertyValue("FetchSize", makeAny(sal_Int32(10)));
869  xRowProperties->setPropertyValue("ActiveConnection", makeAny(m_pImpl->m_xConnection.getTyped()));
870  try
871  {
872  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
873  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
874  }
875  catch (const Exception&)
876  {
877  TOOLS_WARN_EXCEPTION("sw.ui", "");
878  }
879  xRowSet->execute();
880  m_pImpl->m_xResultSet = xRowSet.get();
881  m_pImpl->m_xResultSet->first();
882  m_pImpl->m_nResultSetCursorPos = 1;
883  }
884  catch (const Exception&)
885  {
886  TOOLS_WARN_EXCEPTION("sw.ui", "SwMailMergeConfigItem::GetResultSet()");
887  }
888  }
889  return m_pImpl->m_xResultSet;
890 }
891 
893 {
894  m_pImpl->m_xConnection.clear();
895  if(m_pImpl->m_xResultSet.is())
896  {
897  ::comphelper::disposeComponent( m_pImpl->m_xResultSet );
898  }
899 }
900 
902 {
903  return m_pImpl->m_sFilter;
904 }
905 
906 void SwMailMergeConfigItem::SetFilter(OUString const & rFilter)
907 {
908  if(m_pImpl->m_sFilter == rFilter)
909  return;
910 
911  m_pImpl->m_sFilter = rFilter;
912  m_pImpl->SetModified();
913  Reference<XPropertySet> xRowProperties(m_pImpl->m_xResultSet, UNO_QUERY);
914  if(!xRowProperties.is())
915  return;
916 
917  try
918  {
919  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
920  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
921  uno::Reference<XRowSet> xRowSet( m_pImpl->m_xResultSet, UNO_QUERY_THROW );
922  xRowSet->execute();
923  }
924  catch (const Exception&)
925  {
926  TOOLS_WARN_EXCEPTION("sw.ui", "SwMailMergeConfigItem::SetFilter()");
927  }
928 }
929 
930 sal_Int32 SwMailMergeConfigItem::MoveResultSet(sal_Int32 nTarget)
931 {
932  if(!m_pImpl->m_xResultSet.is())
933  GetResultSet();
934  if(m_pImpl->m_xResultSet.is())
935  {
936  try
937  {
938  //no action if the resultset is already at the right position
939  if(m_pImpl->m_xResultSet->getRow() != nTarget)
940  {
941  if(nTarget > 0)
942  {
943  bool bMoved = m_pImpl->m_xResultSet->absolute(nTarget);
944  if(!bMoved)
945  {
946  if(nTarget > 1)
947  m_pImpl->m_xResultSet->last();
948  else if(nTarget == 1)
949  m_pImpl->m_xResultSet->first();
950  }
951  }
952  else if(nTarget == -1)
953  m_pImpl->m_xResultSet->last();
954  m_pImpl->m_nResultSetCursorPos = m_pImpl->m_xResultSet->getRow();
955  }
956  }
957  catch (const Exception&)
958  {
959  }
960  }
961  return m_pImpl->m_nResultSetCursorPos;
962 }
963 
964 bool SwMailMergeConfigItem::IsResultSetFirstLast(bool& bIsFirst, bool& bIsLast)
965 {
966  bool bRet = false;
967  if(!m_pImpl->m_xResultSet.is())
968  GetResultSet();
969  if(m_pImpl->m_xResultSet.is())
970  {
971  try
972  {
973  bIsFirst = m_pImpl->m_xResultSet->isFirst();
974  bIsLast = m_pImpl->m_xResultSet->isLast();
975  bRet = true;
976  }
977  catch (const Exception&)
978  {
979  }
980  }
981  return bRet;
982 }
983 
985 {
986  return m_pImpl->m_nResultSetCursorPos;
987 }
988 
989 bool SwMailMergeConfigItem::IsRecordIncluded(sal_uInt32 nRecord) const
990  { return nRecord > m_nBegin && nRecord <= m_nEnd; }
991 
992 bool SwMailMergeConfigItem::IsRecordExcluded(sal_uInt32 nRecord) const
993  { return m_aExcludedRecords.find(nRecord) != m_aExcludedRecords.end(); }
994 
995 void SwMailMergeConfigItem::ExcludeRecord(sal_Int32 nRecord, bool bExclude)
996 {
997  if(bExclude)
998  m_aExcludedRecords.insert(nRecord);
999  else
1000  m_aExcludedRecords.erase(nRecord);
1001 }
1002 
1003 uno::Sequence<uno::Any> SwMailMergeConfigItem::GetSelection() const
1004 {
1005  if(!m_pImpl->m_xResultSet.is())
1006  GetResultSet();
1007  if(!m_pImpl->m_xResultSet.is())
1008  return {};
1009  m_pImpl->m_xResultSet->last();
1010  sal_uInt32 nResultSetSize = m_pImpl->m_xResultSet->getRow()+1;
1011  std::vector<uno::Any> vResult;
1012  for(sal_uInt32 nIdx=1; nIdx<nResultSetSize;++nIdx)
1013  if( !IsRecordExcluded(nIdx) && IsRecordIncluded(nIdx) )
1014  vResult.push_back(uno::makeAny<sal_uInt32>(nIdx));
1015  return comphelper::containerToSequence(vResult);
1016 }
1017 
1018 
1019 const uno::Sequence< OUString>&
1021 {
1022  return m_pImpl->m_aSavedDocuments;
1023 }
1024 
1026 {
1027  return m_pImpl->m_bIsOutputToLetter || !IsMailAvailable();
1028 }
1029 
1031 {
1032  if(m_pImpl->m_bIsOutputToLetter != bSet)
1033  {
1034  m_pImpl->m_bIsOutputToLetter = bSet;
1035  m_pImpl->SetModified();
1036  }
1037 }
1038 
1040 {
1041  return bInEMail ?
1042  m_pImpl->m_bIsIndividualGreetingLineInMail :
1043  m_pImpl->m_bIsIndividualGreetingLine;
1044 }
1045 
1047  bool bSet, bool bInEMail)
1048 {
1049  if(bInEMail)
1050  {
1051  if(m_pImpl->m_bIsIndividualGreetingLineInMail != bSet)
1052  {
1053  m_pImpl->m_bIsIndividualGreetingLineInMail = bSet;
1054  m_pImpl->SetModified();
1055  }
1056  }
1057  else
1058  {
1059  if(m_pImpl->m_bIsIndividualGreetingLine != bSet)
1060  {
1061  m_pImpl->m_bIsIndividualGreetingLine = bSet;
1062  m_pImpl->SetModified();
1063  }
1064  }
1065 }
1066 
1067 bool SwMailMergeConfigItem::IsGreetingLine(bool bInEMail) const
1068 {
1069  return bInEMail ? m_pImpl->m_bIsGreetingLineInMail : m_pImpl->m_bIsGreetingLine;
1070 }
1071 
1072 void SwMailMergeConfigItem::SetGreetingLine(bool bSet, bool bInEMail)
1073 {
1074  m_pImpl->m_bUserSettingWereOverwritten = false;
1075  if(bInEMail)
1076  {
1077  if(m_pImpl->m_bIsGreetingLineInMail != bSet)
1078  {
1079  m_pImpl->m_bIsGreetingLineInMail = bSet;
1080  m_pImpl->SetModified();
1081  }
1082  }
1083  else
1084  {
1085  if(m_pImpl->m_bIsGreetingLine != bSet)
1086  {
1087  m_pImpl->m_bIsGreetingLine = bSet;
1088  m_pImpl->SetModified();
1089  }
1090  }
1091 }
1092 
1094  Gender eType ) const
1095 {
1096  return m_pImpl->GetGreetings(eType);
1097 }
1098 
1100  Gender eType, const Sequence< OUString>& rSetGreetings)
1101 {
1102  m_pImpl->SetGreetings( eType, rSetGreetings);
1103 }
1104 
1106  SwMailMergeConfigItem::Gender eType) const
1107 {
1108  return m_pImpl->GetCurrentGreeting(eType);
1109 }
1110 
1112 {
1113  m_pImpl->SetCurrentGreeting(eType, nIndex);
1114 }
1115 
1117 {
1118  return m_pImpl->m_sFemaleGenderValue;
1119 }
1120 
1122 {
1123  if( m_pImpl->m_sFemaleGenderValue != rValue )
1124  {
1125  m_pImpl->m_sFemaleGenderValue = rValue;
1126  m_pImpl->SetModified();
1127  }
1128 }
1129 
1131  const SwDBData& rDBData ) const
1132 {
1133  Sequence< OUString> aRet;
1134  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1135  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1136  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1137  {
1138  aRet = aAssignIter->aDBColumnAssignments;
1139  }
1140  return aRet;
1141 }
1142 
1143 // returns the name that is assigned as e-mail column of the current data base
1144 OUString SwMailMergeConfigItem::GetAssignedColumn(sal_uInt32 nColumn) const
1145 {
1146  OUString sRet;
1147  Sequence< OUString> aAssignment = GetColumnAssignment( m_pImpl->m_aDBData );
1148  if(aAssignment.getLength() > sal::static_int_cast< sal_Int32, sal_uInt32>(nColumn) && !aAssignment[nColumn].isEmpty())
1149  sRet = aAssignment[nColumn];
1150  else if(nColumn < m_pImpl->m_AddressHeaderSA.size())
1151  sRet = m_pImpl->m_AddressHeaderSA[nColumn].first;
1152  return sRet;
1153 }
1154 
1156  const Sequence< OUString>& rList)
1157 {
1158  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1159  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1160  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1161  {
1162  if(aAssignIter->aDBColumnAssignments != rList)
1163  {
1164  aAssignIter->aDBColumnAssignments = rList;
1165  aAssignIter->bColumnAssignmentsChanged = true;
1166  }
1167  }
1168  else
1169  {
1170  DBAddressDataAssignment aAssignment;
1171  aAssignment.aDBData = rDBData;
1172  aAssignment.aDBColumnAssignments = rList;
1173  aAssignment.bColumnAssignmentsChanged = true;
1174  m_pImpl->m_aAddressDataAssignments.push_back(aAssignment);
1175  }
1176  m_pImpl->SetModified();
1177 }
1178 
1180 {
1181  bool bResult = true;
1182  Reference< XResultSet> xResultSet = GetResultSet();
1183  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1184  if(!xColsSupp.is())
1185  return false;
1186  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1187 
1188  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1189  Sequence< OUString> aAssignment =
1191  const OUString* pAssignment = aAssignment.getConstArray();
1192  const Sequence< OUString> aBlocks = GetAddressBlocks();
1193 
1194  if(aBlocks.getLength() <= m_pImpl->GetCurrentAddressBlockIndex())
1195  return false;
1196  SwAddressIterator aIter(aBlocks[m_pImpl->GetCurrentAddressBlockIndex()]);
1197  while(aIter.HasMore())
1198  {
1199  SwMergeAddressItem aItem = aIter.Next();
1200  if(aItem.bIsColumn)
1201  {
1202  OUString sConvertedColumn = aItem.sText;
1203  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1204  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1205  {
1206  if (rHeaders[nColumn].first == aItem.sText &&
1207  !pAssignment[nColumn].isEmpty())
1208  {
1209  sConvertedColumn = pAssignment[nColumn];
1210  break;
1211  }
1212  }
1213  //find out if the column exists in the data base
1214  if(!xCols->hasByName(sConvertedColumn))
1215  {
1216  bResult = false;
1217  break;
1218  }
1219  }
1220  }
1221  return bResult;
1222 }
1223 
1225 {
1226  bool bResult = true;
1227 
1228  if(!IsIndividualGreeting(false))
1229  return true;
1230 
1231  Reference< XResultSet> xResultSet = GetResultSet();
1232  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1233  if(!xColsSupp.is())
1234  return false;
1235  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1236  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1237 
1238  Sequence< OUString> aAssignment =
1240  const OUString* pAssignment = aAssignment.getConstArray();
1241 
1243  sal_Int32 nCurrentFemale = GetCurrentGreeting(SwMailMergeConfigItem::FEMALE);
1245  sal_Int32 nCurrentMale = GetCurrentGreeting(SwMailMergeConfigItem::MALE);
1246  OUString sMale, sFemale;
1247  if(rFemaleEntries.getLength() > nCurrentFemale)
1248  sFemale = rFemaleEntries[nCurrentFemale];
1249  if(rMaleEntries.getLength() > nCurrentMale)
1250  sMale = rMaleEntries[nCurrentMale];
1251 
1252  OUString sAddress = sFemale + sMale;
1253  SwAddressIterator aIter(sAddress);
1254  while(aIter.HasMore())
1255  {
1256  SwMergeAddressItem aItem = aIter.Next();
1257  if(aItem.bIsColumn)
1258  {
1259  OUString sConvertedColumn = aItem.sText;
1260  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1261  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1262  {
1263  if (rHeaders[nColumn].first == aItem.sText &&
1264  !pAssignment[nColumn].isEmpty())
1265  {
1266  sConvertedColumn = pAssignment[nColumn];
1267  break;
1268  }
1269  }
1270  //find out if the column exists in the data base
1271  if(!xCols->hasByName(sConvertedColumn))
1272  {
1273  bResult = false;
1274  break;
1275  }
1276  }
1277  }
1278  return bResult;
1279 }
1280 
1282 {
1283  return m_pImpl->m_sMailDisplayName;
1284 }
1285 
1287 {
1288  if(m_pImpl->m_sMailDisplayName != rName)
1289  {
1290  m_pImpl->m_sMailDisplayName = rName;
1291  m_pImpl->SetModified();
1292  }
1293 }
1294 
1296 {
1297  return m_pImpl->m_sMailAddress;
1298 }
1299 
1300 void SwMailMergeConfigItem::SetMailAddress(const OUString& rAddress)
1301 {
1302  if(m_pImpl->m_sMailAddress != rAddress )
1303  {
1304  m_pImpl->m_sMailAddress = rAddress;
1305  m_pImpl->SetModified();
1306  }
1307 }
1308 
1310 {
1311  return m_pImpl->m_bIsMailReplyTo;
1312 }
1313 
1315 {
1316  if(m_pImpl->m_bIsMailReplyTo != bSet)
1317  {
1318  m_pImpl->m_bIsMailReplyTo = bSet;
1319  m_pImpl->SetModified();
1320  }
1321 }
1322 
1324 {
1325  return m_pImpl->m_sMailReplyTo;
1326 }
1327 
1328 void SwMailMergeConfigItem::SetMailReplyTo(const OUString& rReplyTo)
1329 {
1330  if(m_pImpl->m_sMailReplyTo != rReplyTo)
1331  {
1332  m_pImpl->m_sMailReplyTo = rReplyTo;
1333  m_pImpl->SetModified();
1334  }
1335 }
1336 
1338 {
1339  return m_pImpl->m_sMailServer;
1340 }
1341 
1342 void SwMailMergeConfigItem::SetMailServer(const OUString& rAddress)
1343 {
1344  if(m_pImpl->m_sMailServer != rAddress)
1345  {
1346  m_pImpl->m_sMailServer = rAddress;
1347  m_pImpl->SetModified();
1348  }
1349 }
1350 
1352 {
1353  // provide appropriate TCP port, based on SSL/STARTTLS status, if current port is one of the defaults
1354  switch (m_pImpl->m_nMailPort)
1355  {
1356  case SECURE_PORT:
1357  case DEFAULT_PORT:
1358  return m_pImpl->m_bIsSecureConnection ? SECURE_PORT : DEFAULT_PORT;
1359  default:
1360  return m_pImpl->m_nMailPort;
1361  }
1362 }
1363 
1365 {
1366  if(m_pImpl->m_nMailPort != nSet)
1367  {
1368  m_pImpl->m_nMailPort = nSet;
1369  m_pImpl->SetModified();
1370  }
1371 }
1372 
1374 {
1375  return m_pImpl->m_bIsSecureConnection;
1376 }
1377 
1379 {
1380  if(m_pImpl->m_bIsSecureConnection != bSet)
1381  {
1382  m_pImpl->m_bIsSecureConnection = bSet;
1383  m_pImpl->SetModified();
1384  }
1385 }
1386 
1388 {
1389  return m_pImpl->m_bIsAuthentication;
1390 }
1391 
1393 {
1394  if(m_pImpl->m_bIsAuthentication != bSet)
1395  {
1396  m_pImpl->m_bIsAuthentication = bSet;
1397  m_pImpl->SetModified();
1398  }
1399 }
1400 
1402 {
1403  return m_pImpl->m_sMailUserName;
1404 }
1405 
1406 void SwMailMergeConfigItem::SetMailUserName(const OUString& rName)
1407 {
1408  if(m_pImpl->m_sMailUserName != rName)
1409  {
1410  m_pImpl->m_sMailUserName = rName;
1411  m_pImpl->SetModified();
1412  }
1413 }
1414 
1416 {
1417  return m_pImpl->m_sMailPassword;
1418 }
1419 
1420 void SwMailMergeConfigItem::SetMailPassword(const OUString& rPassword)
1421 {
1422  if(m_pImpl->m_sMailPassword != rPassword)
1423  {
1424  m_pImpl->m_sMailPassword = rPassword;
1425  m_pImpl->SetModified();
1426  }
1427 }
1428 
1430 {
1431  return m_pImpl->m_bIsSMPTAfterPOP;
1432 }
1433 
1435 {
1436  if( m_pImpl->m_bIsSMPTAfterPOP != bSet)
1437  {
1438  m_pImpl->m_bIsSMPTAfterPOP = bSet;
1439  m_pImpl->SetModified();
1440  }
1441 }
1442 
1444 {
1445  return m_pImpl->m_sInServerName;
1446 }
1447 
1448 void SwMailMergeConfigItem::SetInServerName(const OUString& rServer)
1449 {
1450  if(m_pImpl->m_sInServerName != rServer)
1451  {
1452  m_pImpl->m_sInServerName = rServer;
1453  m_pImpl->SetModified();
1454  }
1455 }
1456 
1458 {
1459  // provide appropriate TCP port as user toggles between POP/IMAP if current port is one of the defaults
1460  switch (m_pImpl->m_nInServerPort)
1461  {
1462  case POP_SECURE_PORT:
1463  case POP_PORT:
1464  case IMAP_SECURE_PORT:
1465  case IMAP_PORT:
1466  if ( m_pImpl->m_bInServerPOP )
1467  return m_pImpl->m_bIsSecureConnection ? POP_SECURE_PORT : POP_PORT;
1468  else
1469  return m_pImpl->m_bIsSecureConnection ? IMAP_SECURE_PORT : IMAP_PORT;
1470  default:
1471  return m_pImpl->m_nInServerPort;
1472  }
1473 }
1474 
1476 {
1477  if( m_pImpl->m_nInServerPort != nSet)
1478  {
1479  m_pImpl->m_nInServerPort = nSet;
1480  m_pImpl->SetModified();
1481  }
1482 }
1483 
1485 {
1486  return m_pImpl->m_bInServerPOP;
1487 }
1488 
1490 {
1491  if( m_pImpl->m_bInServerPOP != bSet)
1492  {
1493  m_pImpl->m_bInServerPOP = bSet;
1494  m_pImpl->SetModified();
1495  }
1496 }
1497 
1499 {
1500  return m_pImpl->m_sInServerUserName;
1501 }
1502 
1504 {
1505  if( m_pImpl->m_sInServerUserName != rName)
1506  {
1507  m_pImpl->m_sInServerUserName = rName;
1508  m_pImpl->SetModified();
1509  }
1510 }
1511 
1513 {
1514  return m_pImpl->m_sInServerPassword;
1515 }
1516 
1517 void SwMailMergeConfigItem::SetInServerPassword(const OUString& rPassword)
1518 {
1519  if(m_pImpl->m_sInServerPassword != rPassword)
1520  {
1521  m_pImpl->m_sInServerPassword = rPassword;
1522  m_pImpl->SetModified();
1523  }
1524 }
1525 
1527 {
1528  m_bGreetingInserted = false;
1529  m_bAddressInserted = false;
1530 }
1531 
1533 {
1534  return m_pImpl->m_bIsEMailSupported;
1535 }
1536 
1538 {
1539  m_pImpl->m_aMergeInfos.push_back(rInfo);
1540 }
1541 
1543 {
1544  assert(nDocument < m_pImpl->m_aMergeInfos.size());
1545  return m_pImpl->m_aMergeInfos[nDocument];
1546 }
1547 
1548 
1550 {
1551  if(m_pTargetView)
1552  return m_pImpl->m_aMergeInfos.size();
1553  else
1554  {
1555  sal_Int32 nRestore = GetResultSetPosition();
1556  MoveResultSet(-1);
1557  sal_Int32 nRet = GetResultSetPosition();
1558  MoveResultSet( nRestore );
1559  nRet -= m_aExcludedRecords.size();
1560  return nRet >= 0 ? nRet : 0;
1561  }
1562 }
1563 
1565 {
1566  SfxViewShell* pViewShell = SfxViewShell::GetFirst( false, checkSfxViewShell<SwView> );
1567  while(pViewShell)
1568  {
1569  if(pViewShell == pView)
1570  return pView;
1571 
1572  pViewShell = SfxViewShell::GetNext( *pViewShell, false, checkSfxViewShell<SwView> );
1573  }
1574  return nullptr;
1575 }
1576 
1578 {
1579  //make sure that the pointer is really valid - the document may have been closed manually
1580  if(m_pTargetView)
1581  {
1583  }
1584  return m_pTargetView;
1585 }
1586 
1588 {
1589  m_pTargetView = pView;
1590  //reset the document merge counter
1591  if(!m_pTargetView)
1592  {
1593  m_pImpl->m_aMergeInfos.clear();
1594  }
1595 }
1596 
1598 {
1600  return m_pSourceView;
1601 }
1602 
1603 namespace {
1604 
1605 //This implements XSelectionChangeListener and XDispatch because the
1606 //broadcaster uses this combo to determine if to send the database-changed
1607 //update. Its probably that listening to statusChanged at some other level is
1608 //equivalent to this. See the other call to SwXDispatch::GetDBChangeURL for
1609 //the broadcaster of the event.
1610 class DBChangeListener : public cppu::WeakImplHelper<css::view::XSelectionChangeListener, css::frame::XDispatch>
1611 {
1613 public:
1614  explicit DBChangeListener(SwMailMergeConfigItem& rParent)
1615  : m_rParent(rParent)
1616  {
1617  }
1618 
1619  virtual void SAL_CALL selectionChanged(const EventObject& /*rEvent*/) override
1620  {
1621  }
1622 
1623  virtual void SAL_CALL disposing(const EventObject&) override
1624  {
1625  m_rParent.stopDBChangeListening();
1626  }
1627 
1628  virtual void SAL_CALL dispatch(const css::util::URL& rURL, const css::uno::Sequence< css::beans::PropertyValue >& /*rArgs*/) override
1629  {
1630  if (rURL.Complete.equalsAscii(SwXDispatch::GetDBChangeURL()))
1631  m_rParent.updateCurrentDBDataFromDocument();
1632  }
1633 
1634  virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1635  {
1636  }
1637 
1638  virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1639  {
1640  }
1641 };
1642 
1643 }
1644 
1646 {
1647  if (m_xDBChangedListener.is())
1648  {
1649  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1650  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
1651  m_xDBChangedListener.clear();
1652  }
1653 
1654  m_pSourceView = pView;
1655 
1656  if (!m_pSourceView)
1657  return;
1658 
1659  std::vector<OUString> aDBNameList;
1660  std::vector<OUString> aAllDBNames;
1661  m_pSourceView->GetWrtShell().GetAllUsedDB( aDBNameList, &aAllDBNames );
1662  if(!aDBNameList.empty())
1663  {
1664  // if fields are available there is usually no need of an addressblock and greeting
1665  if(!m_pImpl->m_bUserSettingWereOverwritten)
1666  {
1667  if( m_pImpl->m_bIsAddressBlock
1668  || m_pImpl->m_bIsGreetingLineInMail
1669  || m_pImpl->m_bIsGreetingLine )
1670  {
1671  //store user settings
1672  m_pImpl->m_bUserSettingWereOverwritten = true;
1673  m_pImpl->m_bIsAddressBlock_LastUserSetting = m_pImpl->m_bIsAddressBlock;
1674  m_pImpl->m_bIsGreetingLineInMail_LastUserSetting = m_pImpl->m_bIsGreetingLineInMail;
1675  m_pImpl->m_bIsGreetingLine_LastUserSetting = m_pImpl->m_bIsGreetingLine;
1676 
1677  //set all to false
1678  m_pImpl->m_bIsAddressBlock = false;
1679  m_pImpl->m_bIsGreetingLineInMail = false;
1680  m_pImpl->m_bIsGreetingLine = false;
1681 
1682  m_pImpl->SetModified();
1683  }
1684  }
1685  }
1686  else if( m_pImpl->m_bUserSettingWereOverwritten )
1687  {
1688  //restore last user settings:
1689  m_pImpl->m_bIsAddressBlock = m_pImpl->m_bIsAddressBlock_LastUserSetting;
1690  m_pImpl->m_bIsGreetingLineInMail = m_pImpl->m_bIsGreetingLineInMail_LastUserSetting;
1691  m_pImpl->m_bIsGreetingLine = m_pImpl->m_bIsGreetingLine_LastUserSetting;
1692 
1693  m_pImpl->m_bUserSettingWereOverwritten = false;
1694  }
1695 
1696  if (!m_xDBChangedListener.is())
1697  {
1698  m_xDBChangedListener.set(new DBChangeListener(*this));
1699  }
1700 
1701  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1702  xSupplier->addSelectionChangeListener(m_xDBChangedListener);
1703 }
1704 
1706 {
1707  m_pImpl->SetCurrentAddressBlockIndex( nSet );
1708 }
1709 
1711 {
1712  return m_pImpl->GetCurrentAddressBlockIndex();
1713 }
1714 
1715 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const Sequence< OUString > & GetPropertyNames()
SwMergeAddressItem Next()
bool HasMore() const
bool IsHideEmptyParagraphs() const
static OUString lcl_CreateNodeName(Sequence< OUString > &rAssignments)
OUString const & GetMailServer() const
sal_Int32 nIndex
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
static bool SetSetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
static css::uno::Sequence< OUString > GetNodeNames(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, ConfigNameFormat eFormat)
void SetGreetings(Gender eType, const css::uno::Sequence< OUString > &rBlocks)
void SetCurrentDBData(const SwDBData &rDBData)
void SetGreetingLine(bool bSet, bool bInEMail)
void Notify(SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, const SwRect *pOldRect=nullptr)
Notify the background based on the difference between old and new rectangle.
Definition: frmtool.cxx:3210
css::uno::Sequence< css::uno::Any > GetSelection() const
static css::uno::Reference< css::sdbcx::XColumnsSupplier > GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection > const &xConnection, const OUString &rTableOrQuery, SwDBSelect eTableOrQuery=SwDBSelect::UNKNOWN)
Definition: dbmgr.cxx:1876
OUString const & GetMailAddress() const
void SetMailDisplayName(const OUString &rName)
std::vector< OUString > m_aFemaleGreetingLines
std::vector< OUString > m_aNeutralGreetingLines
void SetCurrentGreeting(Gender eType, sal_Int32 nIndex)
bool IsSecureConnection() const
void SetInServerPassword(const OUString &rPassword)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
void SetMailServer(const OUString &rAddress)
void SetIndividualGreeting(bool bSet, bool bInEMail)
OUString & GetExcludeCountry() const
OUString sDataSource
Definition: swdbdata.hxx:30
ConfigItemMode
css::uno::Reference< css::view::XSelectionChangeListener > m_xDBChangedListener
#define IMAP_SECURE_PORT
sal_Int32 GetCurrentAddressBlockIndex() const
void SetCurrentConnection(css::uno::Reference< css::sdbc::XDataSource > const &xSource, const SharedConnection &rConnection, css::uno::Reference< css::sdbcx::XColumnsSupplier > const &xColumnsSupplier, const SwDBData &rDBData)
std::vector< SwDocMergeInfo > m_aMergeInfos
void SetTargetView(SwView *pView)
const SwDBData & GetCurrentDBData() const
void SetMailReplyTo(bool bSet)
bool IsResultSetFirstLast(bool &bIsFirst, bool &bIsLast)
sal_Int16 GetMailPort() const
sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const
constexpr OUStringLiteral cAddressDataAssignments
void SetMailPassword(const OUString &rPassword)
void SetInServerPOP(bool bSet)
const char cDBColumnAssignments[]
virtual DECL_LISTENERMULTIPLEXER_END void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
const char cDataTableName[]
void ClearModified()
Reference< XColumnsSupplier > m_xColumnsSupplier
void SetSMTPAfterPOP(bool bSet)
bool UCB_IsFile(const OUString &rURL)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:413
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames) override
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
sal_uInt16 sal_Unicode
NONE
css::uno::Reference< css::sdbcx::XColumnsSupplier > const & GetColumnsSupplier()
enumrange< T >::Iterator begin(enumrange< T >)
css::uno::Sequence< OUString > GetAddressBlocks() const
SwDocMergeInfo & GetDocumentMergeInfo(sal_uInt32 nDocument)
void SetMailAddress(const OUString &rAddress)
uno::Sequence< OUString > m_aSavedDocuments
void SetInServerPort(sal_Int16 nSet)
static SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
void SetAuthentication(bool bSet)
SharedConnection const & GetConnection() const
css::uno::Sequence< OUString > GetGreetings(Gender eType) const
void AddMergedDocument(SwDocMergeInfo const &rInfo)
void updateCurrentDBDataFromDocument()
static void lcl_ConvertFromNumbers(OUString &rBlock, const std::vector< std::pair< OUString, int >> &rHeaders)
bool IsAuthentication() const
OUString const & GetInServerPassword() const
sal_Int16 GetInServerPort() const
#define SAL_N_ELEMENTS(arr)
static bool PutProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, const css::uno::Sequence< css::uno::Any > &rValues, bool bAllLocales)
css::uno::Reference< css::sdbc::XResultSet > const & GetResultSet() const
sal_uInt32 GetMergedDocumentCount()
const char cDataCommandType[]
std::set< sal_Int32 > m_aExcludedRecords
const css::uno::Sequence< OUString > & GetSavedDocuments() const
static css::uno::Sequence< css::uno::Any > GetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, bool bAllLocales)
static void lcl_ConvertToNumbers(OUString &rBlock, const std::vector< std::pair< OUString, int >> &rHeaders)
const char cDataSourceName[]
const std::vector< std::pair< OUString, int > > & GetDefaultAddressHeaders() const
#define TOOLS_WARN_EXCEPTION(area, stream)
#define IMAP_PORT
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:300
int i
void SetFemaleGenderValue(const OUString &rValue)
void SetSecureConnection(bool bSet)
std::vector< std::pair< OUString, int > > m_AddressHeaderSA
static const char * GetDBChangeURL()
void ExcludeRecord(sal_Int32 nRecord, bool bExclude)
void SetAddressBlocks(const Sequence< OUString > &rBlocks, bool bConvertFromConfig=false)
void SetHideEmptyParagraphs(bool bSet)
bool IsGreetingFieldsAssigned() const
static css::uno::Reference< css::sdbc::XConnection > GetConnection(const OUString &rDataSource, css::uno::Reference< css::sdbc::XDataSource > &rxSource, const SwView *pView)
Definition: dbmgr.cxx:1853
void SetAddressBlock(bool bSet)
float u
bool IsRecordExcluded(sal_uInt32 nRecord) const
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:290
OUString const & GetMailReplyTo() const
sal_Int32 GetResultSetPosition() const
void SetFilter(OUString const &)
uno::Sequence< OUString > GetGreetings(SwMailMergeConfigItem::Gender eType, bool bConvertToConfig=false) const
void SetGreetings(SwMailMergeConfigItem::Gender eType, const uno::Sequence< OUString > &rBlocks, bool bConvertFromConfig=false)
static SwView * lcl_ExistsView(SwView *pView)
std::vector< OUString > m_aMaleGreetingLines
static SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
sal_Int32 MoveResultSet(sal_Int32 nTarget)
bool IsInServerPOP() const
void SetInServerName(const OUString &rServer)
css::uno::Sequence< OUString > GetColumnAssignment(const SwDBData &rDBData) const
OUString const & GetMailDisplayName() const
#define POP_PORT
sal_Int32 GetCurrentGreeting(Gender eType) const
#define DEFAULT_PORT
OUString const & GetInServerUserName() const
const PropertyValue * pValues
void SetCurrentAddressBlockIndex(sal_Int32 nSet)
void SetOutputToLetter(bool bSet)
void SetMailUserName(const OUString &rName)
bool IsIndividualGreeting(bool bInEMail) const
Reference< XResultSet > m_xResultSet
Reference< XMultiServiceFactory > getProcessServiceFactory()
bool IsMailAvailable() const
void SetSourceView(SwView *pView)
SharedConnection m_xConnection
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString GetAssignedColumn(sal_uInt32 nColumn) const
bool IsGreetingLine(bool bInEMail) const
void SetMailPort(sal_Int16 nSet)
std::vector< OUString > m_aAddressBlocks
std::unique_ptr< SwMailMergeConfigItem_Impl > m_pImpl
void SetColumnAssignment(const SwDBData &rDBData, const css::uno::Sequence< OUString > &)
#define POP_SECURE_PORT
css::uno::Reference< css::sdbc::XDataSource > const & GetSource() const
const OUString & GetFemaleGenderValue() const
bool IsIncludeCountry() const
void SetCurrentAddressBlockIndex(sal_Int32 nSet)
void SetAddressBlocks(const css::uno::Sequence< OUString > &rBlocks)
bool IsSMTPAfterPOP() const
void SetCountrySettings(bool bSet, const OUString &sCountry)
void SetInServerUserName(const OUString &rName)
bool IsRecordIncluded(sal_uInt32 nRecord) const
#define SAL_WARN(area, stream)
css::view::XSelectionSupplier * GetUNOObject()
Definition: view0.cxx:111
bool IsAddressBlock() const
void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
sal_Int32 GetCurrentAddressBlockIndex() const
XSLTFilter & m_rParent
OUString & GetFilter() const
constexpr OUStringLiteral first
OUString const & GetMailPassword() const
bool IsMailReplyTo() const
bool IsAddressFieldsAssigned() const
OUString sCommand
Definition: swdbdata.hxx:31
virtual void ImplCommit() override
std::vector< DBAddressDataAssignment > m_aAddressDataAssignments
#define SECURE_PORT
OUString const & GetMailUserName() const
Definition: view.hxx:144
OUString const & GetInServerName() const
bool IsOutputToLetter() const
Reference< XDataSource > m_xSource
Sequence< OUString > GetAddressBlocks(bool bConvertToConfig=false) const
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)