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/instance.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 #include <unomid.h>
49 
50 using namespace utl;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::sdb;
56 using namespace ::com::sun::star::sdbc;
57 using namespace ::com::sun::star::sdbcx;
58 
59 const char cAddressDataAssignments[] = "AddressDataAssignments";
60 const char cDBColumnAssignments[] = "DBColumnAssignments";
61 const char cDataSourceName[] = "DataSource/DataSourceName";
62 const char cDataTableName[] = "DataSource/DataTableName" ;
63 const char cDataCommandType[] = "DataSource/DataCommandType";
64 
65 #define SECURE_PORT 587
66 #define DEFAULT_PORT 25
67 #define POP_PORT 110
68 #define POP_SECURE_PORT 995
69 #define IMAP_PORT 143
70 #define IMAP_SECURE_PORT 993
71 
73 {
76  //if loaded the name of the node has to be saved
77  OUString sConfigNodeName;
78  //all created or changed assignments need to be stored
80 
82  bColumnAssignmentsChanged(false)
83  {}
84 };
85 
87 {
88  friend class SwMailMergeConfigItem;
91  Reference< XColumnsSupplier> m_xColumnsSupplier;
92  Reference< XResultSet> m_xResultSet;
94  OUString m_sFilter;
96 
97  std::vector<DBAddressDataAssignment> m_aAddressDataAssignments;
98  std::vector< OUString> m_aAddressBlocks;
102 
106 
109  std::vector< OUString> m_aFemaleGreetingLines;
111  std::vector< OUString> m_aMaleGreetingLines;
113  std::vector< OUString> m_aNeutralGreetingLines;
116  uno::Sequence< OUString> m_aSavedDocuments;
117 
120 
121  //mail settings
123  OUString m_sMailAddress;
124  OUString m_sMailReplyTo;
125  OUString m_sMailServer;
126  OUString m_sMailUserName;
127  OUString m_sMailPassword;
128 
130  OUString m_sInServerName;
131  sal_Int16 m_nInServerPort;
135 
136  sal_Int16 m_nMailPort;
140 
142 
143  std::vector<std::pair<OUString, int>> m_AddressHeaderSA;
144 
145  //these addresses are not stored in the configuration
146  std::vector< SwDocMergeInfo > m_aMergeInfos;
147 
148  //we do overwrite the usersettings in a special case
149  //then we do remind the usersettings here
154 
155  static const Sequence< OUString>& GetPropertyNames();
156 
157  virtual void ImplCommit() override;
158 
159 public:
161 
162  virtual void Notify( const css::uno::Sequence< OUString >& aPropertyNames ) override;
163  const Sequence< OUString>
164  GetAddressBlocks(bool bConvertToConfig = false) const;
165  void SetAddressBlocks(
166  const Sequence< OUString>& rBlocks,
167  bool bConvertFromConfig = false);
168  const uno::Sequence< OUString>
170  bool bConvertToConfig = false) const;
172  const uno::Sequence< OUString>& rBlocks,
173  bool bConvertFromConfig = false);
174 
175  void SetCurrentAddressBlockIndex( sal_Int32 nSet );
176  sal_Int32 GetCurrentAddressBlockIndex() const
177  { return m_nCurrentAddressBlock; }
178  sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const;
179  void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex);
180 
181 };
182 
184  ConfigItem("Office.Writer/MailMergeWizard", ConfigItemMode::NONE),
185  m_nResultSetCursorPos(-1),
186  m_nCurrentAddressBlock(0),
187  m_bIsAddressBlock(true),
188  m_bIsHideEmptyParagraphs(false),
189  m_bIsOutputToLetter(true),
190  m_bIncludeCountry(false),
191  m_bIsGreetingLine(true),
192  m_bIsIndividualGreetingLine(false),
193  m_nCurrentFemaleGreeting(0),
194  m_nCurrentMaleGreeting(0),
195  m_nCurrentNeutralGreeting(0),
196  m_bIsGreetingLineInMail(false),
197  m_bIsIndividualGreetingLineInMail(false),
198  m_bIsSMPTAfterPOP(false),
199  m_nInServerPort( POP_SECURE_PORT ),
200  m_bInServerPOP( true ),
201  m_nMailPort(SECURE_PORT),
202  m_bIsMailReplyTo(false),
203  m_bIsSecureConnection(true),
204  m_bIsAuthentication(false),
205 
206  m_bIsEMailSupported(false),
207  m_bUserSettingWereOverwritten(false),
208  m_bIsAddressBlock_LastUserSetting(false),
209  m_bIsGreetingLineInMail_LastUserSetting(false),
210  m_bIsGreetingLine_LastUserSetting(false)
211 {
212  for (size_t i = 0; i < SAL_N_ELEMENTS(SA_ADDRESS_HEADER); ++i)
213  {
214  m_AddressHeaderSA.emplace_back(SwResId(SA_ADDRESS_HEADER[i].first), SA_ADDRESS_HEADER[i].second);
215  }
216 
217  const Sequence<OUString>& rNames = GetPropertyNames();
218  Sequence<Any> aValues = GetProperties(rNames);
219  const Any* pValues = aValues.getConstArray();
220  assert(aValues.getLength() == rNames.getLength());
221  if(aValues.getLength() == rNames.getLength())
222  {
223  for(int nProp = 0; nProp < rNames.getLength(); nProp++)
224  {
225  switch(nProp)
226  {
227  case 0: pValues[nProp] >>= m_bIsOutputToLetter; break;
228  case 1: pValues[nProp] >>= m_bIncludeCountry; break;
229  case 2: pValues[nProp] >>= m_sExcludeCountry; break;
230  case 3:
231  {
232  Sequence< OUString> aBlocks;
233  pValues[nProp] >>= aBlocks;
234  SetAddressBlocks(aBlocks, true);
235  }
236  break;
237  case 4: pValues[nProp] >>= m_bIsAddressBlock; break;
238  case 5: pValues[nProp] >>= m_bIsGreetingLine; break;
239  case 6: pValues[nProp] >>= m_bIsIndividualGreetingLine; break;
240  case 7 :
241  case 8 :
242  case 9 :
243  {
244  Sequence< OUString> aGreetings;
245  pValues[nProp] >>= aGreetings;
247  SwMailMergeConfigItem::FEMALE + nProp - 7), aGreetings, true);
248  }
249  break;
250 
251  case 10: pValues[nProp] >>= m_nCurrentFemaleGreeting; break;
252  case 11: pValues[nProp] >>= m_nCurrentMaleGreeting; break;
253  case 12: pValues[nProp] >>= m_nCurrentNeutralGreeting; break;
254  case 13: pValues[nProp] >>= m_sFemaleGenderValue; break;
255  case 14: pValues[nProp] >>= m_sMailDisplayName; break;
256  case 15: pValues[nProp] >>= m_sMailAddress; break;
257  case 16: pValues[nProp] >>= m_bIsMailReplyTo; break;
258  case 17: pValues[nProp] >>= m_sMailReplyTo; break;
259  case 18: pValues[nProp] >>= m_sMailServer; break;
260  case 19: pValues[nProp] >>= m_nMailPort; break;
261  case 20: pValues[nProp] >>= m_bIsSecureConnection; break;
262  case 21: pValues[nProp] >>= m_bIsAuthentication; break;
263  case 22: pValues[nProp] >>= m_sMailUserName; break;
264  case 23: pValues[nProp] >>= m_sMailPassword; break;
265  case 24 :pValues[nProp] >>= m_aDBData.sDataSource; break;
266  case 25 :pValues[nProp] >>= m_aDBData.sCommand; break;
267  case 26 :
268  {
269  short nTemp = 0;
270  if(pValues[nProp] >>= nTemp)
271  m_aDBData.nCommandType = nTemp;
272  }
273  break;
274  case 27: pValues[nProp] >>= m_sFilter; break;
275  case 28: pValues[nProp] >>= m_aSavedDocuments; break;
276  case 29:
277  pValues[nProp] >>= m_bIsEMailSupported;
278  break;
279  case 30: pValues[nProp] >>= m_bIsGreetingLineInMail; break;
280  case 31: pValues[nProp] >>= m_bIsIndividualGreetingLineInMail; break;
281  case 32: pValues[nProp] >>= m_bIsSMPTAfterPOP; break;
282  case 33: pValues[nProp] >>= m_sInServerName; break;
283  case 34: pValues[nProp] >>= m_nInServerPort; break;
284  case 35: pValues[nProp] >>= m_bInServerPOP; break;
285  case 36: pValues[nProp] >>= m_sInServerUserName; break;
286  case 37: pValues[nProp] >>= m_sInServerPassword; break;
287  case 38: pValues[nProp] >>= m_bIsHideEmptyParagraphs; break;
288  case 39: pValues[nProp] >>= m_nCurrentAddressBlock; break;
289  }
290  }
291  }
292  //read the list of data base assignments
294  if(aAssignments.hasElements())
295  {
296  //create a list of property names to load the URLs of all data bases
297  const OUString* pAssignments = aAssignments.getConstArray();
298  Sequence< OUString > aAssignProperties(4 * aAssignments.getLength());
299  OUString* pAssignProperties = aAssignProperties.getArray();
300  sal_Int32 nAssign;
301  for(nAssign = 0; nAssign < aAssignProperties.getLength(); nAssign += 4)
302  {
303  OUString sAssignPath = cAddressDataAssignments;
304  sAssignPath += "/";
305  sAssignPath += pAssignments[nAssign / 4];
306  sAssignPath += "/";
307  pAssignProperties[nAssign] = sAssignPath;
308  pAssignProperties[nAssign] += cDataSourceName;
309  pAssignProperties[nAssign + 1] = sAssignPath;
310  pAssignProperties[nAssign + 1] += cDataTableName;
311  pAssignProperties[nAssign + 2] = sAssignPath;
312  pAssignProperties[nAssign + 2] += cDataCommandType;
313  pAssignProperties[nAssign + 3] = sAssignPath;
314  pAssignProperties[nAssign + 3] += cDBColumnAssignments;
315  }
316  Sequence<Any> aAssignValues = GetProperties(aAssignProperties);
317  const Any* pAssignValues = aAssignValues.getConstArray();
318  for(nAssign = 0; nAssign < aAssignValues.getLength(); nAssign += 4 )
319  {
320  DBAddressDataAssignment aAssignment;
321  pAssignValues[nAssign] >>= aAssignment.aDBData.sDataSource;
322  pAssignValues[nAssign + 1] >>= aAssignment.aDBData.sCommand;
323  pAssignValues[nAssign + 2] >>= aAssignment.aDBData.nCommandType;
324  pAssignValues[nAssign + 3] >>= aAssignment.aDBColumnAssignments;
325  aAssignment.sConfigNodeName = pAssignments[nAssign / 4];
326  m_aAddressDataAssignments.push_back(aAssignment);
327  }
328  }
329  //check if the saved documents still exist
330  if(m_aSavedDocuments.hasElements())
331  {
332  uno::Sequence< OUString > aTempDocuments(m_aSavedDocuments.getLength());
333  OUString* pTempDocuments = std::copy_if(m_aSavedDocuments.begin(), m_aSavedDocuments.end(), aTempDocuments.begin(),
334  [](const OUString& rDoc) { return SWUnoHelper::UCB_IsFile( rDoc ); });
335  sal_Int32 nIndex = static_cast<sal_Int32>(std::distance(aTempDocuments.begin(), pTempDocuments));
336  if(nIndex < m_aSavedDocuments.getLength())
337  {
338  m_aSavedDocuments = aTempDocuments;
339  m_aSavedDocuments.realloc(nIndex);
340  }
341  }
342 }
343 
345 {
346  if(m_aAddressBlocks.size() >= sal::static_int_cast<sal_uInt32, sal_Int32>(nSet))
347  {
348  m_nCurrentAddressBlock = nSet;
349  SetModified();
350  }
351 }
352 
353 static OUString lcl_CreateNodeName(Sequence<OUString>& rAssignments )
354 {
355  sal_Int32 nStart = rAssignments.getLength();
356  OUString sNewName;
357  //search if the name exists
358  while(true)
359  {
360  sNewName = "_" + OUString::number(nStart++);
361  if(comphelper::findValue(rAssignments, sNewName) == -1)
362  break;
363  }
364  // add the new name to the array of existing names
365  rAssignments.realloc(rAssignments.getLength() + 1);
366  rAssignments.getArray()[rAssignments.getLength() - 1] = sNewName;
367  return sNewName;
368 }
369 
370 static void lcl_ConvertToNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders )
371 {
372  //convert the strings used for UI to numbers used for the configuration
373  OUString sBlock(rBlock.replaceAll("\n", "\\n"));
374  for (size_t i = 0; i < rHeaders.size(); ++i)
375  {
376  OUString sHeader = "<" + rHeaders[i].first + ">";
377  OUString sReplace = "<" + OUStringLiteral1('0' + i) + ">";
378  sBlock = sBlock.replaceAll(sHeader, sReplace);
379  }
380  rBlock = sBlock;
381 }
382 
383 static void lcl_ConvertFromNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders)
384 {
385  //convert the numbers used for the configuration to strings used for UI to numbers
386  //doesn't use ReplaceAll to prevent expansion of numbers inside of the headers
387  SwAddressIterator aGreetingIter(rBlock.replaceAll("\\n", "\n"));
388  OUStringBuffer sBlock;
389  while(aGreetingIter.HasMore())
390  {
391  SwMergeAddressItem aNext = aGreetingIter.Next();
392  if(aNext.bIsColumn)
393  {
394  //the text should be 1 characters long
395  sal_Unicode cChar = aNext.sText[0];
396  if(cChar >= '0' && cChar <= 'c')
397  {
398  sBlock.append("<");
399  sal_uInt16 nHeader = cChar - '0';
400  if(nHeader < rHeaders.size())
401  sBlock.append(rHeaders[nHeader].first);
402  sBlock.append(">");
403  }
404  else
405  {
406  SAL_WARN("sw.ui", "parse error in address block or greeting line");
407  }
408  }
409  else
410  sBlock.append(aNext.sText);
411  }
412  rBlock = sBlock.makeStringAndClear();
413 }
414 
416 {
417  static Sequence<OUString> aNames {
418  "OutputToLetter", // 0
419  "IncludeCountry", // 1
420  "ExcludeCountry", // 2
421  "AddressBlockSettings", // 3
422  "IsAddressBlock", // 4
423  "IsGreetingLine", // 5
424  "IsIndividualGreetingLine", // 6
425  "FemaleGreetingLines", // 7
426  "MaleGreetingLines", // 8
427  "NeutralGreetingLines", // 9
428  "CurrentFemaleGreeting", // 10
429  "CurrentMaleGreeting", // 11
430  "CurrentNeutralGreeting", // 12
431  "FemaleGenderValue", // 13
432  "MailDisplayName", // 14
433  "MailAddress", // 15
434  "IsMailReplyTo", // 16
435  "MailReplyTo", // 17
436  "MailServer", // 18
437  "MailPort", // 19
438  "IsSecureConnection", // 20
439  "IsAuthentication", // 21
440  "MailUserName", // 22
441  "MailPassword", // 23
442  "DataSource/DataSourceName", // 24
443  "DataSource/DataTableName", // 25
444  "DataSource/DataCommandType",// 26
445  "Filter", // 27
446  "SavedDocuments", // 28
447  "EMailSupported", // 29
448  "IsEMailGreetingLine", //30
449  "IsEMailIndividualGreetingLine", //31
450  "IsSMPTAfterPOP", //32
451  "InServerName", //33
452  "InServerPort", //34
453  "InServerIsPOP", //35
454  "InServerUserName", //36
455  "InServerPassword", //37
456  "IsHideEmptyParagraphs", //38
457  "CurrentAddressBlock" //39
458  };
459  return aNames;
460 }
461 
462 void SwMailMergeConfigItem_Impl::Notify( const css::uno::Sequence< OUString >& ) {}
463 
465 {
467  Sequence<Any> aValues(aNames.getLength());
468  Any* pValues = aValues.getArray();
469 
470  for(int nProp = 0; nProp < aNames.getLength(); nProp++)
471  {
472  switch(nProp)
473  {
474  case 0: pValues[nProp] <<= m_bIsOutputToLetter; break;
475  case 1: pValues[nProp] <<= m_bIncludeCountry; break;
476  case 2: pValues[nProp] <<= m_sExcludeCountry; break;
477  case 3: pValues[nProp] <<= GetAddressBlocks(true); break;
478  case 4:
479  {
481  pValues[nProp] <<= m_bIsAddressBlock_LastUserSetting;
482  else
483  pValues[nProp] <<= m_bIsAddressBlock;
484  break;
485  }
486  case 5:
487  {
489  pValues[nProp] <<= m_bIsGreetingLine_LastUserSetting;
490  else
491  pValues[nProp] <<= m_bIsGreetingLine;
492  break;
493  }
494  case 6: pValues[nProp] <<= m_bIsIndividualGreetingLine; break;
495  case 7:
496  case 8:
497  case 9:
498  pValues[nProp] <<= GetGreetings(
500  SwMailMergeConfigItem::FEMALE + nProp - 7), true);
501  break;
502  case 10: pValues[nProp] <<= m_nCurrentFemaleGreeting; break;
503  case 11: pValues[nProp] <<= m_nCurrentMaleGreeting; break;
504  case 12: pValues[nProp] <<= m_nCurrentNeutralGreeting; break;
505  case 13: pValues[nProp] <<= m_sFemaleGenderValue; break;
506  case 14: pValues[nProp] <<= m_sMailDisplayName; break;
507  case 15: pValues[nProp] <<= m_sMailAddress; break;
508  case 16: pValues[nProp] <<= m_bIsMailReplyTo; break;
509  case 17: pValues[nProp] <<= m_sMailReplyTo; break;
510  case 18: pValues[nProp] <<= m_sMailServer; break;
511  case 19: pValues[nProp] <<= m_nMailPort; break;
512  case 20: pValues[nProp] <<= m_bIsSecureConnection; break;
513  case 21: pValues[nProp] <<= m_bIsAuthentication; break;
514  case 22: pValues[nProp] <<= m_sMailUserName; break;
515  case 23: pValues[nProp] <<= m_sMailPassword; break;
516  case 24 :pValues[nProp] <<= m_aDBData.sDataSource; break;
517  case 25 :pValues[nProp] <<= m_aDBData.sCommand; break;
518  case 26 :pValues[nProp] <<= static_cast<short>(m_aDBData.nCommandType); break;
519  case 27 :pValues[nProp] <<= m_sFilter; break;
520  case 28 :pValues[nProp] <<= m_aSavedDocuments; break;
521  case 29: pValues[nProp] <<= m_bIsEMailSupported; break;
522  case 30:
523  {
525  pValues[nProp] <<= m_bIsGreetingLineInMail_LastUserSetting;
526  else
527  pValues[nProp] <<= m_bIsGreetingLineInMail;
528  break;
529  }
530  case 31: pValues[nProp] <<= m_bIsIndividualGreetingLineInMail; break;
531  case 32: pValues[nProp] <<= m_bIsSMPTAfterPOP; break;
532  case 33: pValues[nProp] <<= m_sInServerName; break;
533  case 34: pValues[nProp] <<= m_nInServerPort; break;
534  case 35: pValues[nProp] <<= m_bInServerPOP; break;
535  case 36: pValues[nProp] <<= m_sInServerUserName; break;
536  case 37: pValues[nProp] <<= m_sInServerPassword; break;
537  case 38: pValues[nProp] <<= m_bIsHideEmptyParagraphs; break;
538  case 39: pValues[nProp] <<= m_nCurrentAddressBlock; break;
539  }
540  }
541  PutProperties(aNames, aValues);
542  //store the changed / new assignments
543 
544  //load the existing node names to find new names
546 
547  for(const auto& rAssignment : m_aAddressDataAssignments)
548  {
549  if(rAssignment.bColumnAssignmentsChanged)
550  {
551  //create a new node name
552  OUString sNewNode = !rAssignment.sConfigNodeName.isEmpty() ?
553  rAssignment.sConfigNodeName :
554  lcl_CreateNodeName(aAssignments);
555  OUString sSlash = "/";
556  OUString sNodePath = cAddressDataAssignments;
557  sNodePath += sSlash;
558  sNodePath += sNewNode;
559  sNodePath += sSlash;
560  //only one new entry is written
561  Sequence< PropertyValue > aNewValues(4);
562  PropertyValue* pNewValues = aNewValues.getArray();
563  pNewValues[0].Name = sNodePath;
564  pNewValues[0].Name += cDataSourceName;
565  pNewValues[0].Value <<= rAssignment.aDBData.sDataSource;
566  pNewValues[1].Name = sNodePath;
567  pNewValues[1].Name += cDataTableName;
568  pNewValues[1].Value <<= rAssignment.aDBData.sCommand;
569  pNewValues[2].Name = sNodePath;
570  pNewValues[2].Name += cDataCommandType;
571  pNewValues[2].Value <<= rAssignment.aDBData.nCommandType;
572  pNewValues[3].Name = sNodePath;
573  pNewValues[3].Name += cDBColumnAssignments;
574  pNewValues[3].Value <<= rAssignment.aDBColumnAssignments;
575 
577  }
578  }
579 
581 }
582 
584  bool bConvertToConfig) const
585 {
587  std::transform(m_aAddressBlocks.begin(), m_aAddressBlocks.end(), aRet.begin(),
588  [this, bConvertToConfig](const OUString& rBlock) -> OUString {
589  OUString sBlock = rBlock;
590  if(bConvertToConfig)
592  return sBlock;
593  });
594  return aRet;
595 }
596 
598  const Sequence< OUString>& rBlocks,
599  bool bConvertFromConfig)
600 {
601  m_aAddressBlocks.clear();
602  std::transform(rBlocks.begin(), rBlocks.end(), std::back_inserter(m_aAddressBlocks),
603  [this, bConvertFromConfig](const OUString& rBlock) -> OUString {
604  OUString sBlock = rBlock;
605  if(bConvertFromConfig)
607  return sBlock;
608  });
610  SetModified();
611 }
612 
614  SwMailMergeConfigItem::Gender eType, bool bConvertToConfig) const
615 {
616  const std::vector< OUString>& rGreetings =
620  Sequence< OUString> aRet(rGreetings.size());
621  std::transform(rGreetings.begin(), rGreetings.end(), aRet.begin(),
622  [this, bConvertToConfig](const OUString& rGreeting) -> OUString {
623  OUString sGreeting = rGreeting;
624  if(bConvertToConfig)
626  return sGreeting;
627  });
628  return aRet;
629 }
630 
633  const Sequence< OUString>& rSetGreetings,
634  bool bConvertFromConfig)
635 {
636  std::vector< OUString>& rGreetings =
640 
641  rGreetings.clear();
642  std::transform(rSetGreetings.begin(), rSetGreetings.end(), std::back_inserter(rGreetings),
643  [this, bConvertFromConfig](const OUString& rGreeting) -> OUString {
644  OUString sGreeting = rGreeting;
645  if(bConvertFromConfig)
647  return sGreeting;
648  });
649  SetModified();
650 }
651 
653  SwMailMergeConfigItem::Gender eType) const
654 {
655  sal_Int32 nRet;
656  switch(eType)
657  {
660  default: nRet = m_nCurrentNeutralGreeting; break;
661  }
662  return nRet;
663 }
664 
666  SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
667 {
668  bool bChanged = false;
669  switch(eType)
670  {
672  bChanged = m_nCurrentFemaleGreeting != nIndex;
673  m_nCurrentFemaleGreeting = nIndex;
674  break;
676  bChanged = m_nCurrentMaleGreeting != nIndex;
677  m_nCurrentMaleGreeting = nIndex;
678  break;
679  default:
680  bChanged = m_nCurrentNeutralGreeting != nIndex;
681  m_nCurrentNeutralGreeting = nIndex;
682  }
683  if(bChanged)
684  SetModified();
685 }
686 
689  m_bAddressInserted(false),
690  m_bGreetingInserted(false),
691  m_nGreetingMoves(0),
692  m_pSourceView(nullptr),
693  m_pTargetView(nullptr)
694 {
695 }
696 
698 {
699  if (m_xDBChangedListener.is())
700  {
701  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
702  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
703  m_xDBChangedListener.clear();
704  }
705 }
706 
708 {
709  const SwDBData& rDBData = m_pSourceView->GetWrtShell().GetDBDesc();
710  SetCurrentDBData(rDBData);
711 }
712 
714 {
716 }
717 
719 {
720  if(m_pImpl->IsModified())
721  m_pImpl->Commit();
722 }
723 
724 const std::vector<std::pair<OUString, int>>& SwMailMergeConfigItem::GetDefaultAddressHeaders() const
725 {
726  return m_pImpl->m_AddressHeaderSA;
727 }
728 
730  const Sequence< OUString>& rBlocks)
731 {
732  m_pImpl->SetAddressBlocks(rBlocks);
733 }
734 
736 {
737  return m_pImpl->GetAddressBlocks();
738 }
739 
741 {
742  return m_pImpl->m_bIsAddressBlock && IsOutputToLetter();
743 }
744 
746 {
747  m_pImpl->m_bUserSettingWereOverwritten = false;
748  if(m_pImpl->m_bIsAddressBlock != bSet)
749  {
750  m_pImpl->m_bIsAddressBlock = bSet;
751  m_pImpl->SetModified();
752  }
753 }
754 
756 {
757  return m_pImpl->m_bIsHideEmptyParagraphs;
758 }
759 
761 {
762  if(m_pImpl->m_bIsHideEmptyParagraphs != bSet)
763  {
764  m_pImpl->m_bIsHideEmptyParagraphs = bSet;
765  m_pImpl->SetModified();
766  }
767 }
768 
770 {
771  return m_pImpl->m_bIncludeCountry;
772 }
773 
775 {
776  return m_pImpl->m_sExcludeCountry;
777 }
778 
779 void SwMailMergeConfigItem::SetCountrySettings(bool bSet, const OUString& rCountry)
780 {
781  if(m_pImpl->m_sExcludeCountry != rCountry ||
782  m_pImpl->m_bIncludeCountry != bSet)
783  {
784  m_pImpl->m_bIncludeCountry = bSet;
785  m_pImpl->m_sExcludeCountry = bSet ? rCountry : OUString();
786  m_pImpl->SetModified();
787  }
788 }
789 
791  Reference< XDataSource> const & xSource,
792  const SharedConnection& rConnection,
793  Reference< XColumnsSupplier> const & xColumnsSupplier,
794  const SwDBData& rDBData)
795 {
796  m_pImpl->m_xSource = xSource ;
797  m_pImpl->m_xConnection = rConnection ;
798  m_pImpl->m_xColumnsSupplier = xColumnsSupplier;
799  m_pImpl->m_aDBData = rDBData;
800  m_pImpl->m_xResultSet = nullptr;
801  m_pImpl->m_nResultSetCursorPos = 0;
802  m_pImpl->SetModified();
803 }
804 
806 {
807  return m_pImpl->m_xSource;
808 }
809 
811 {
812  return m_pImpl->m_xConnection;
813 }
814 
815 Reference< XColumnsSupplier> const & SwMailMergeConfigItem::GetColumnsSupplier()
816 {
817  if(!m_pImpl->m_xColumnsSupplier.is() && m_pImpl->m_xConnection.is())
818  {
819  m_pImpl->m_xColumnsSupplier = SwDBManager::GetColumnSupplier(m_pImpl->m_xConnection,
820  m_pImpl->m_aDBData.sCommand,
821  m_pImpl->m_aDBData.nCommandType == CommandType::TABLE ?
823  }
824  return m_pImpl->m_xColumnsSupplier;
825 }
826 
828 {
829  return m_pImpl->m_aDBData;
830 }
831 
833 {
834  if(m_pImpl->m_aDBData != rDBData)
835  {
836  m_pImpl->m_aDBData = rDBData;
837  m_pImpl->m_xConnection.clear();
838  m_pImpl->m_xSource = nullptr;
839  m_pImpl->m_xResultSet = nullptr;
840  m_pImpl->m_xColumnsSupplier = nullptr;
841  m_pImpl->SetModified();
842  }
843 }
844 
845 Reference< XResultSet> const & SwMailMergeConfigItem::GetResultSet() const
846 {
847  if(!m_pImpl->m_xConnection.is() && !m_pImpl->m_aDBData.sDataSource.isEmpty())
848  {
849  m_pImpl->m_xConnection.reset(
850  SwDBManager::GetConnection(m_pImpl->m_aDBData.sDataSource, m_pImpl->m_xSource, m_pSourceView),
852  );
853  }
854  if(!m_pImpl->m_xResultSet.is() && m_pImpl->m_xConnection.is())
855  {
856  try
857  {
859 
860  Reference<XRowSet> xRowSet( xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY );
861  Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
862  xRowProperties->setPropertyValue("DataSourceName", makeAny(m_pImpl->m_aDBData.sDataSource));
863  xRowProperties->setPropertyValue("Command", makeAny(m_pImpl->m_aDBData.sCommand));
864  xRowProperties->setPropertyValue("CommandType", makeAny(m_pImpl->m_aDBData.nCommandType));
865  xRowProperties->setPropertyValue("FetchSize", makeAny(sal_Int32(10)));
866  xRowProperties->setPropertyValue("ActiveConnection", makeAny(m_pImpl->m_xConnection.getTyped()));
867  try
868  {
869  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
870  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
871  }
872  catch (const Exception&)
873  {
874  css::uno::Any ex( cppu::getCaughtException() );
875  SAL_WARN("sw.ui", "exception caught: " << exceptionToString(ex));
876  }
877  xRowSet->execute();
878  m_pImpl->m_xResultSet = xRowSet.get();
879  m_pImpl->m_xResultSet->first();
880  m_pImpl->m_nResultSetCursorPos = 1;
881  }
882  catch (const Exception&)
883  {
884  css::uno::Any ex( cppu::getCaughtException() );
885  SAL_WARN("sw.ui", "exception caught in: SwMailMergeConfigItem::GetResultSet() " << exceptionToString(ex));
886  }
887  }
888  return m_pImpl->m_xResultSet;
889 }
890 
892 {
893  m_pImpl->m_xConnection.clear();
894  if(m_pImpl->m_xResultSet.is())
895  {
896  ::comphelper::disposeComponent( m_pImpl->m_xResultSet );
897  }
898 }
899 
901 {
902  return m_pImpl->m_sFilter;
903 }
904 
905 void SwMailMergeConfigItem::SetFilter(OUString const & rFilter)
906 {
907  if(m_pImpl->m_sFilter != rFilter)
908  {
909  m_pImpl->m_sFilter = rFilter;
910  m_pImpl->SetModified();
911  Reference<XPropertySet> xRowProperties(m_pImpl->m_xResultSet, UNO_QUERY);
912  if(xRowProperties.is())
913  {
914  try
915  {
916  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
917  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
918  uno::Reference<XRowSet> xRowSet( m_pImpl->m_xResultSet, UNO_QUERY_THROW );
919  xRowSet->execute();
920  }
921  catch (const Exception&)
922  {
923  css::uno::Any ex( cppu::getCaughtException() );
924  SAL_WARN("sw.ui", "exception caught in SwMailMergeConfigItem::SetFilter(): " << exceptionToString(ex));
925  }
926  }
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::IsRecordExcluded(sal_Int32 nRecord) const
990  { return m_aExcludedRecords.find(nRecord) != m_aExcludedRecords.end(); }
991 
992 void SwMailMergeConfigItem::ExcludeRecord(sal_Int32 nRecord, bool bExclude)
993 {
994  if(bExclude)
995  m_aExcludedRecords.insert(nRecord);
996  else
997  m_aExcludedRecords.erase(nRecord);
998 }
999 
1000 uno::Sequence<uno::Any> SwMailMergeConfigItem::GetSelection() const
1001 {
1002  if(!m_pImpl->m_xResultSet.is())
1003  GetResultSet();
1004  if(!m_pImpl->m_xResultSet.is())
1005  return {};
1006  m_pImpl->m_xResultSet->last();
1007  sal_Int32 nResultSetSize = m_pImpl->m_xResultSet->getRow()+1;
1008  std::vector<uno::Any> vResult;
1009  vResult.reserve(nResultSetSize);
1010  for(sal_Int32 nIdx=1; nIdx<nResultSetSize;++nIdx)
1011  if(!IsRecordExcluded(nIdx))
1012  vResult.push_back(uno::makeAny<sal_Int32>(nIdx));
1013  return comphelper::containerToSequence(vResult);
1014 }
1015 
1016 
1017 const uno::Sequence< OUString>&
1019 {
1020  return m_pImpl->m_aSavedDocuments;
1021 }
1022 
1024 {
1025  return m_pImpl->m_bIsOutputToLetter || !IsMailAvailable();
1026 }
1027 
1029 {
1030  if(m_pImpl->m_bIsOutputToLetter != bSet)
1031  {
1032  m_pImpl->m_bIsOutputToLetter = bSet;
1033  m_pImpl->SetModified();
1034  }
1035 }
1036 
1038 {
1039  return bInEMail ?
1040  m_pImpl->m_bIsIndividualGreetingLineInMail :
1041  m_pImpl->m_bIsIndividualGreetingLine;
1042 }
1043 
1045  bool bSet, bool bInEMail)
1046 {
1047  if(bInEMail)
1048  {
1049  if(m_pImpl->m_bIsIndividualGreetingLineInMail != bSet)
1050  {
1051  m_pImpl->m_bIsIndividualGreetingLineInMail = bSet;
1052  m_pImpl->SetModified();
1053  }
1054  }
1055  else
1056  {
1057  if(m_pImpl->m_bIsIndividualGreetingLine != bSet)
1058  {
1059  m_pImpl->m_bIsIndividualGreetingLine = bSet;
1060  m_pImpl->SetModified();
1061  }
1062  }
1063 }
1064 
1065 bool SwMailMergeConfigItem::IsGreetingLine(bool bInEMail) const
1066 {
1067  return bInEMail ? m_pImpl->m_bIsGreetingLineInMail : m_pImpl->m_bIsGreetingLine;
1068 }
1069 
1070 void SwMailMergeConfigItem::SetGreetingLine(bool bSet, bool bInEMail)
1071 {
1072  m_pImpl->m_bUserSettingWereOverwritten = false;
1073  if(bInEMail)
1074  {
1075  if(m_pImpl->m_bIsGreetingLineInMail != bSet)
1076  {
1077  m_pImpl->m_bIsGreetingLineInMail = bSet;
1078  m_pImpl->SetModified();
1079  }
1080  }
1081  else
1082  {
1083  if(m_pImpl->m_bIsGreetingLine != bSet)
1084  {
1085  m_pImpl->m_bIsGreetingLine = bSet;
1086  m_pImpl->SetModified();
1087  }
1088  }
1089 }
1090 
1092  Gender eType ) const
1093 {
1094  return m_pImpl->GetGreetings(eType);
1095 }
1096 
1098  Gender eType, const Sequence< OUString>& rSetGreetings)
1099 {
1100  m_pImpl->SetGreetings( eType, rSetGreetings);
1101 }
1102 
1104  SwMailMergeConfigItem::Gender eType) const
1105 {
1106  return m_pImpl->GetCurrentGreeting(eType);
1107 }
1108 
1110 {
1111  m_pImpl->SetCurrentGreeting(eType, nIndex);
1112 }
1113 
1115 {
1116  return m_pImpl->m_sFemaleGenderValue;
1117 }
1118 
1120 {
1121  if( m_pImpl->m_sFemaleGenderValue != rValue )
1122  {
1123  m_pImpl->m_sFemaleGenderValue = rValue;
1124  m_pImpl->SetModified();
1125  }
1126 }
1127 
1129  const SwDBData& rDBData ) const
1130 {
1131  Sequence< OUString> aRet;
1132  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1133  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1134  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1135  {
1136  aRet = aAssignIter->aDBColumnAssignments;
1137  }
1138  return aRet;
1139 }
1140 
1141 // returns the name that is assigned as e-mail column of the current data base
1142 OUString SwMailMergeConfigItem::GetAssignedColumn(sal_uInt32 nColumn) const
1143 {
1144  OUString sRet;
1145  Sequence< OUString> aAssignment = GetColumnAssignment( m_pImpl->m_aDBData );
1146  if(aAssignment.getLength() > sal::static_int_cast< sal_Int32, sal_uInt32>(nColumn) && !aAssignment[nColumn].isEmpty())
1147  sRet = aAssignment[nColumn];
1148  else if(nColumn < m_pImpl->m_AddressHeaderSA.size())
1149  sRet = m_pImpl->m_AddressHeaderSA[nColumn].first;
1150  return sRet;
1151 }
1152 
1154  const Sequence< OUString>& rList)
1155 {
1156  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1157  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1158  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1159  {
1160  if(aAssignIter->aDBColumnAssignments != rList)
1161  {
1162  aAssignIter->aDBColumnAssignments = rList;
1163  aAssignIter->bColumnAssignmentsChanged = true;
1164  }
1165  }
1166  else
1167  {
1168  DBAddressDataAssignment aAssignment;
1169  aAssignment.aDBData = rDBData;
1170  aAssignment.aDBColumnAssignments = rList;
1171  aAssignment.bColumnAssignmentsChanged = true;
1172  m_pImpl->m_aAddressDataAssignments.push_back(aAssignment);
1173  }
1174  m_pImpl->SetModified();
1175 }
1176 
1178 {
1179  bool bResult = true;
1180  Reference< XResultSet> xResultSet = GetResultSet();
1181  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1182  if(!xColsSupp.is())
1183  return false;
1184  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1185 
1186  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1187  Sequence< OUString> aAssignment =
1189  const OUString* pAssignment = aAssignment.getConstArray();
1190  const Sequence< OUString> aBlocks = GetAddressBlocks();
1191 
1192  if(aBlocks.getLength() <= m_pImpl->GetCurrentAddressBlockIndex())
1193  return false;
1194  SwAddressIterator aIter(aBlocks[m_pImpl->GetCurrentAddressBlockIndex()]);
1195  while(aIter.HasMore())
1196  {
1197  SwMergeAddressItem aItem = aIter.Next();
1198  if(aItem.bIsColumn)
1199  {
1200  OUString sConvertedColumn = aItem.sText;
1201  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1202  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1203  {
1204  if (rHeaders[nColumn].first == aItem.sText &&
1205  !pAssignment[nColumn].isEmpty())
1206  {
1207  sConvertedColumn = pAssignment[nColumn];
1208  break;
1209  }
1210  }
1211  //find out if the column exists in the data base
1212  if(!xCols->hasByName(sConvertedColumn))
1213  {
1214  bResult = false;
1215  break;
1216  }
1217  }
1218  }
1219  return bResult;
1220 }
1221 
1223 {
1224  bool bResult = true;
1225 
1226  if(!IsIndividualGreeting(false))
1227  return true;
1228 
1229  Reference< XResultSet> xResultSet = GetResultSet();
1230  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1231  if(!xColsSupp.is())
1232  return false;
1233  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1234  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1235 
1236  Sequence< OUString> aAssignment =
1238  const OUString* pAssignment = aAssignment.getConstArray();
1239 
1241  sal_Int32 nCurrentFemale = GetCurrentGreeting(SwMailMergeConfigItem::FEMALE);
1243  sal_Int32 nCurrentMale = GetCurrentGreeting(SwMailMergeConfigItem::MALE);
1244  OUString sMale, sFemale;
1245  if(rFemaleEntries.getLength() > nCurrentFemale)
1246  sFemale = rFemaleEntries[nCurrentFemale];
1247  if(rMaleEntries.getLength() > nCurrentMale)
1248  sMale = rMaleEntries[nCurrentMale];
1249 
1250  OUString sAddress( sFemale );
1251  sAddress += sMale;
1252  SwAddressIterator aIter(sAddress);
1253  while(aIter.HasMore())
1254  {
1255  SwMergeAddressItem aItem = aIter.Next();
1256  if(aItem.bIsColumn)
1257  {
1258  OUString sConvertedColumn = aItem.sText;
1259  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1260  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1261  {
1262  if (rHeaders[nColumn].first == aItem.sText &&
1263  !pAssignment[nColumn].isEmpty())
1264  {
1265  sConvertedColumn = pAssignment[nColumn];
1266  break;
1267  }
1268  }
1269  //find out if the column exists in the data base
1270  if(!xCols->hasByName(sConvertedColumn))
1271  {
1272  bResult = false;
1273  break;
1274  }
1275  }
1276  }
1277  return bResult;
1278 }
1279 
1281 {
1282  return m_pImpl->m_sMailDisplayName;
1283 }
1284 
1286 {
1287  if(m_pImpl->m_sMailDisplayName != rName)
1288  {
1289  m_pImpl->m_sMailDisplayName = rName;
1290  m_pImpl->SetModified();
1291  }
1292 }
1293 
1295 {
1296  return m_pImpl->m_sMailAddress;
1297 }
1298 
1299 void SwMailMergeConfigItem::SetMailAddress(const OUString& rAddress)
1300 {
1301  if(m_pImpl->m_sMailAddress != rAddress )
1302  {
1303  m_pImpl->m_sMailAddress = rAddress;
1304  m_pImpl->SetModified();
1305  }
1306 }
1307 
1309 {
1310  return m_pImpl->m_bIsMailReplyTo;
1311 }
1312 
1314 {
1315  if(m_pImpl->m_bIsMailReplyTo != bSet)
1316  {
1317  m_pImpl->m_bIsMailReplyTo = bSet;
1318  m_pImpl->SetModified();
1319  }
1320 }
1321 
1323 {
1324  return m_pImpl->m_sMailReplyTo;
1325 }
1326 
1327 void SwMailMergeConfigItem::SetMailReplyTo(const OUString& rReplyTo)
1328 {
1329  if(m_pImpl->m_sMailReplyTo != rReplyTo)
1330  {
1331  m_pImpl->m_sMailReplyTo = rReplyTo;
1332  m_pImpl->SetModified();
1333  }
1334 }
1335 
1337 {
1338  return m_pImpl->m_sMailServer;
1339 }
1340 
1341 void SwMailMergeConfigItem::SetMailServer(const OUString& rAddress)
1342 {
1343  if(m_pImpl->m_sMailServer != rAddress)
1344  {
1345  m_pImpl->m_sMailServer = rAddress;
1346  m_pImpl->SetModified();
1347  }
1348 }
1349 
1351 {
1352  // provide appropriate TCP port, based on SSL/STARTTLS status, if current port is one of the defaults
1353  switch (m_pImpl->m_nMailPort)
1354  {
1355  case SECURE_PORT:
1356  case DEFAULT_PORT:
1357  return m_pImpl->m_bIsSecureConnection ? SECURE_PORT : DEFAULT_PORT;
1358  break;
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  break;
1471  default:
1472  return m_pImpl->m_nInServerPort;
1473  }
1474 }
1475 
1477 {
1478  if( m_pImpl->m_nInServerPort != nSet)
1479  {
1480  m_pImpl->m_nInServerPort = nSet;
1481  m_pImpl->SetModified();
1482  }
1483 }
1484 
1486 {
1487  return m_pImpl->m_bInServerPOP;
1488 }
1489 
1491 {
1492  if( m_pImpl->m_bInServerPOP != bSet)
1493  {
1494  m_pImpl->m_bInServerPOP = bSet;
1495  m_pImpl->SetModified();
1496  }
1497 }
1498 
1500 {
1501  return m_pImpl->m_sInServerUserName;
1502 }
1503 
1505 {
1506  if( m_pImpl->m_sInServerUserName != rName)
1507  {
1508  m_pImpl->m_sInServerUserName = rName;
1509  m_pImpl->SetModified();
1510  }
1511 }
1512 
1514 {
1515  return m_pImpl->m_sInServerPassword;
1516 }
1517 
1518 void SwMailMergeConfigItem::SetInServerPassword(const OUString& rPassword)
1519 {
1520  if(m_pImpl->m_sInServerPassword != rPassword)
1521  {
1522  m_pImpl->m_sInServerPassword = rPassword;
1523  m_pImpl->SetModified();
1524  }
1525 }
1526 
1528 {
1529  m_bGreetingInserted = false;
1530  m_bAddressInserted = false;
1531 }
1532 
1534 {
1535  return m_pImpl->m_bIsEMailSupported;
1536 }
1537 
1539 {
1540  m_pImpl->m_aMergeInfos.push_back(rInfo);
1541 }
1542 
1544 {
1545  assert(nDocument < m_pImpl->m_aMergeInfos.size());
1546  return m_pImpl->m_aMergeInfos[nDocument];
1547 }
1548 
1549 
1551 {
1552  if(m_pTargetView)
1553  return m_pImpl->m_aMergeInfos.size();
1554  else
1555  {
1556  sal_Int32 nRestore = GetResultSetPosition();
1557  MoveResultSet(-1);
1558  sal_Int32 nRet = GetResultSetPosition();
1559  MoveResultSet( nRestore );
1560  nRet -= m_aExcludedRecords.size();
1561  return nRet >= 0 ? nRet : 0;
1562  }
1563 }
1564 
1566 {
1567  SfxViewShell* pViewShell = SfxViewShell::GetFirst( false, checkSfxViewShell<SwView> );
1568  while(pViewShell)
1569  {
1570  if(pViewShell == pView)
1571  return pView;
1572 
1573  pViewShell = SfxViewShell::GetNext( *pViewShell, false, checkSfxViewShell<SwView> );
1574  }
1575  return nullptr;
1576 }
1577 
1579 {
1580  //make sure that the pointer is really valid - the document may have been closed manually
1581  if(m_pTargetView)
1582  {
1584  }
1585  return m_pTargetView;
1586 }
1587 
1589 {
1590  m_pTargetView = pView;
1591  //reset the document merge counter
1592  if(!m_pTargetView)
1593  {
1594  m_pImpl->m_aMergeInfos.clear();
1595  }
1596 }
1597 
1599 {
1601  return m_pSourceView;
1602 }
1603 
1604 //This implements XSelectionChangeListener and XDispatch because the
1605 //broadcaster uses this combo to determine if to send the database-changed
1606 //update. Its probably that listening to statusChanged at some other level is
1607 //equivalent to this. See the other call to SwXDispatch::GetDBChangeURL for
1608 //the broadcaster of the event.
1609 class DBChangeListener : public cppu::WeakImplHelper<css::view::XSelectionChangeListener, css::frame::XDispatch>
1610 {
1612 public:
1614  : m_rParent(rParent)
1615  {
1616  }
1617 
1618  virtual void SAL_CALL selectionChanged(const EventObject& /*rEvent*/) override
1619  {
1620  }
1621 
1622  virtual void SAL_CALL disposing(const EventObject&) override
1623  {
1624  m_rParent.stopDBChangeListening();
1625  }
1626 
1627  virtual void SAL_CALL dispatch(const css::util::URL& rURL, const css::uno::Sequence< css::beans::PropertyValue >& /*rArgs*/) override
1628  {
1629  if (rURL.Complete.equalsAscii(SwXDispatch::GetDBChangeURL()))
1630  m_rParent.updateCurrentDBDataFromDocument();
1631  }
1632 
1633  virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1634  {
1635  }
1636 
1637  virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1638  {
1639  }
1640 };
1641 
1643 {
1644  if (m_xDBChangedListener.is())
1645  {
1646  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1647  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
1648  m_xDBChangedListener.clear();
1649  }
1650 
1651  m_pSourceView = pView;
1652 
1653  if (!m_pSourceView)
1654  return;
1655 
1656  std::vector<OUString> aDBNameList;
1657  std::vector<OUString> aAllDBNames;
1658  m_pSourceView->GetWrtShell().GetAllUsedDB( aDBNameList, &aAllDBNames );
1659  if(!aDBNameList.empty())
1660  {
1661  // if fields are available there is usually no need of an addressblock and greeting
1662  if(!m_pImpl->m_bUserSettingWereOverwritten)
1663  {
1664  if( m_pImpl->m_bIsAddressBlock
1665  || m_pImpl->m_bIsGreetingLineInMail
1666  || m_pImpl->m_bIsGreetingLine )
1667  {
1668  //store user settings
1669  m_pImpl->m_bUserSettingWereOverwritten = true;
1670  m_pImpl->m_bIsAddressBlock_LastUserSetting = m_pImpl->m_bIsAddressBlock;
1671  m_pImpl->m_bIsGreetingLineInMail_LastUserSetting = m_pImpl->m_bIsGreetingLineInMail;
1672  m_pImpl->m_bIsGreetingLine_LastUserSetting = m_pImpl->m_bIsGreetingLine;
1673 
1674  //set all to false
1675  m_pImpl->m_bIsAddressBlock = false;
1676  m_pImpl->m_bIsGreetingLineInMail = false;
1677  m_pImpl->m_bIsGreetingLine = false;
1678 
1679  m_pImpl->SetModified();
1680  }
1681  }
1682  }
1683  else if( m_pImpl->m_bUserSettingWereOverwritten )
1684  {
1685  //restore last user settings:
1686  m_pImpl->m_bIsAddressBlock = m_pImpl->m_bIsAddressBlock_LastUserSetting;
1687  m_pImpl->m_bIsGreetingLineInMail = m_pImpl->m_bIsGreetingLineInMail_LastUserSetting;
1688  m_pImpl->m_bIsGreetingLine = m_pImpl->m_bIsGreetingLine_LastUserSetting;
1689 
1690  m_pImpl->m_bUserSettingWereOverwritten = false;
1691  }
1692 
1693  if (!m_xDBChangedListener.is())
1694  {
1695  m_xDBChangedListener.set(new DBChangeListener(*this));
1696  }
1697 
1698  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1699  xSupplier->addSelectionChangeListener(m_xDBChangedListener);
1700 }
1701 
1703 {
1704  m_pImpl->SetCurrentAddressBlockIndex( nSet );
1705 }
1706 
1708 {
1709  return m_pImpl->GetCurrentAddressBlockIndex();
1710 }
1711 
1712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL dispatch(const css::util::URL &rURL, const css::uno::Sequence< css::beans::PropertyValue > &) override
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 nCommandType
Definition: swdbdata.hxx:32
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:2924
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:1969
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< OUString > &_rList, const OUString &_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
SharedConnection const & GetConnection()
void SetMailReplyTo(bool bSet)
bool IsResultSetFirstLast(bool &bIsFirst, bool &bIsLast)
sal_Int16 GetMailPort() const
sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const
void SetMailPassword(const OUString &rPassword)
void SetInServerPOP(bool bSet)
static const sal_Char * GetDBChangeURL()
const char cDBColumnAssignments[]
css::uno::Reference< css::sdbc::XDataSource > const & GetSource()
const char cDataTableName[]
Reference< XColumnsSupplier > m_xColumnsSupplier
void SetSMTPAfterPOP(bool bSet)
virtual void SAL_CALL disposing(const EventObject &) override
bool UCB_IsFile(const OUString &rURL)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:400
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames) override
sal_uInt16 sal_Unicode
NONE
css::uno::Reference< css::sdbcx::XColumnsSupplier > const & GetColumnsSupplier()
bool SetSetProperties(const OUString &rNode, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
Any SAL_CALL getCaughtException()
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)
SwMailMergeConfigItem & m_rParent
bool IsRecordExcluded(sal_Int32 nRecord) 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)
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 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 IMAP_PORT
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:313
void SetFemaleGenderValue(const OUString &rValue)
bool PutProperties(const css::uno::Sequence< OUString > &rNames, const css::uno::Sequence< css::uno::Any > &rValues)
void SetSecureConnection(bool bSet)
std::vector< std::pair< OUString, int > > m_AddressHeaderSA
void ExcludeRecord(sal_Int32 nRecord, bool bExclude)
void SetAddressBlocks(const Sequence< OUString > &rBlocks, bool bConvertFromConfig=false)
int i
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:1946
void SetAddressBlock(bool bSet)
const SwDBData & GetDBDesc() const
Definition: edfld.cxx:303
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames)
const Sequence< OUString > GetAddressBlocks(bool bConvertToConfig=false) const
OUString const & GetMailReplyTo() const
sal_Int32 GetResultSetPosition() const
void SetFilter(OUString const &)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
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)
OString exceptionToString(const css::uno::Any &caught)
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
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)
DBChangeListener(SwMailMergeConfigItem &rParent)
OUString GetAssignedColumn(sal_uInt32 nColumn) const
const css::uno::Sequence< OUString > GetAddressBlocks() 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
const OUString & GetFemaleGenderValue() const
virtual void SAL_CALL selectionChanged(const EventObject &) override
bool IsIncludeCountry() const
void SetCurrentAddressBlockIndex(sal_Int32 nSet)
void SetAddressBlocks(const css::uno::Sequence< OUString > &rBlocks)
bool IsSMTPAfterPOP() const
css::uno::Sequence< OUString > GetNodeNames(const OUString &rNode)
void SetCountrySettings(bool bSet, const OUString &sCountry)
void SetInServerUserName(const OUString &rName)
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &, const css::util::URL &) override
void SAL_CALL first(const css::awt::SpinEvent &rEvent) override
#define SAL_WARN(area, stream)
css::view::XSelectionSupplier * GetUNOObject()
Definition: view0.cxx:119
bool IsAddressBlock() const
const uno::Sequence< OUString > GetGreetings(SwMailMergeConfigItem::Gender eType, bool bConvertToConfig=false) const
void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
sal_Int32 GetCurrentAddressBlockIndex() const
const char cAddressDataAssignments[]
OUString & GetFilter() const
OUString const & GetMailPassword() const
bool IsMailReplyTo() const
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &, const css::util::URL &) override
bool IsAddressFieldsAssigned() const
OUString sCommand
Definition: swdbdata.hxx:31
virtual void ImplCommit() override
Sequence< OUString > aDBColumnAssignments
std::vector< DBAddressDataAssignment > m_aAddressDataAssignments
#define SECURE_PORT
OUString const & GetMailUserName() const
Definition: view.hxx:146
OUString const & GetInServerName() const
bool IsOutputToLetter() const
Reference< XDataSource > m_xSource
const css::uno::Sequence< OUString > GetGreetings(Gender eType) const
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)