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  Sequence< OUString> GetAddressBlocks(bool bConvertToConfig = false) const;
164  void SetAddressBlocks(
165  const Sequence< OUString>& rBlocks,
166  bool bConvertFromConfig = false);
167  uno::Sequence< OUString>
169  bool bConvertToConfig = false) const;
171  const uno::Sequence< OUString>& rBlocks,
172  bool bConvertFromConfig = false);
173 
174  void SetCurrentAddressBlockIndex( sal_Int32 nSet );
175  sal_Int32 GetCurrentAddressBlockIndex() const
176  { return m_nCurrentAddressBlock; }
177  sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const;
178  void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex);
179 
180 };
181 
183  ConfigItem("Office.Writer/MailMergeWizard", ConfigItemMode::NONE),
184  m_nResultSetCursorPos(-1),
185  m_nCurrentAddressBlock(0),
186  m_bIsAddressBlock(true),
187  m_bIsHideEmptyParagraphs(false),
188  m_bIsOutputToLetter(true),
189  m_bIncludeCountry(false),
190  m_bIsGreetingLine(true),
191  m_bIsIndividualGreetingLine(false),
192  m_nCurrentFemaleGreeting(0),
193  m_nCurrentMaleGreeting(0),
194  m_nCurrentNeutralGreeting(0),
195  m_bIsGreetingLineInMail(false),
196  m_bIsIndividualGreetingLineInMail(false),
197  m_bIsSMPTAfterPOP(false),
198  m_nInServerPort( POP_SECURE_PORT ),
199  m_bInServerPOP( true ),
200  m_nMailPort(SECURE_PORT),
201  m_bIsMailReplyTo(false),
202  m_bIsSecureConnection(true),
203  m_bIsAuthentication(false),
204 
205  m_bIsEMailSupported(false),
206  m_bUserSettingWereOverwritten(false),
207  m_bIsAddressBlock_LastUserSetting(false),
208  m_bIsGreetingLineInMail_LastUserSetting(false),
209  m_bIsGreetingLine_LastUserSetting(false)
210 {
211  for (size_t i = 0; i < SAL_N_ELEMENTS(SA_ADDRESS_HEADER); ++i)
212  {
213  m_AddressHeaderSA.emplace_back(SwResId(SA_ADDRESS_HEADER[i].first), SA_ADDRESS_HEADER[i].second);
214  }
215 
216  const Sequence<OUString>& rNames = GetPropertyNames();
217  Sequence<Any> aValues = GetProperties(rNames);
218  const Any* pValues = aValues.getConstArray();
219  assert(aValues.getLength() == rNames.getLength());
220  if(aValues.getLength() == rNames.getLength())
221  {
222  for(int nProp = 0; nProp < rNames.getLength(); nProp++)
223  {
224  switch(nProp)
225  {
226  case 0: pValues[nProp] >>= m_bIsOutputToLetter; break;
227  case 1: pValues[nProp] >>= m_bIncludeCountry; break;
228  case 2: pValues[nProp] >>= m_sExcludeCountry; break;
229  case 3:
230  {
231  Sequence< OUString> aBlocks;
232  pValues[nProp] >>= aBlocks;
233  SetAddressBlocks(aBlocks, true);
234  }
235  break;
236  case 4: pValues[nProp] >>= m_bIsAddressBlock; break;
237  case 5: pValues[nProp] >>= m_bIsGreetingLine; break;
238  case 6: pValues[nProp] >>= m_bIsIndividualGreetingLine; break;
239  case 7 :
240  case 8 :
241  case 9 :
242  {
243  Sequence< OUString> aGreetings;
244  pValues[nProp] >>= aGreetings;
246  SwMailMergeConfigItem::FEMALE + nProp - 7), aGreetings, true);
247  }
248  break;
249 
250  case 10: pValues[nProp] >>= m_nCurrentFemaleGreeting; break;
251  case 11: pValues[nProp] >>= m_nCurrentMaleGreeting; break;
252  case 12: pValues[nProp] >>= m_nCurrentNeutralGreeting; break;
253  case 13: pValues[nProp] >>= m_sFemaleGenderValue; break;
254  case 14: pValues[nProp] >>= m_sMailDisplayName; break;
255  case 15: pValues[nProp] >>= m_sMailAddress; break;
256  case 16: pValues[nProp] >>= m_bIsMailReplyTo; break;
257  case 17: pValues[nProp] >>= m_sMailReplyTo; break;
258  case 18: pValues[nProp] >>= m_sMailServer; break;
259  case 19: pValues[nProp] >>= m_nMailPort; break;
260  case 20: pValues[nProp] >>= m_bIsSecureConnection; break;
261  case 21: pValues[nProp] >>= m_bIsAuthentication; break;
262  case 22: pValues[nProp] >>= m_sMailUserName; break;
263  case 23: pValues[nProp] >>= m_sMailPassword; break;
264  case 24 :pValues[nProp] >>= m_aDBData.sDataSource; break;
265  case 25 :pValues[nProp] >>= m_aDBData.sCommand; break;
266  case 26 :
267  {
268  short nTemp = 0;
269  if(pValues[nProp] >>= nTemp)
270  m_aDBData.nCommandType = nTemp;
271  }
272  break;
273  case 27: pValues[nProp] >>= m_sFilter; break;
274  case 28: pValues[nProp] >>= m_aSavedDocuments; break;
275  case 29:
276  pValues[nProp] >>= m_bIsEMailSupported;
277  break;
278  case 30: pValues[nProp] >>= m_bIsGreetingLineInMail; break;
279  case 31: pValues[nProp] >>= m_bIsIndividualGreetingLineInMail; break;
280  case 32: pValues[nProp] >>= m_bIsSMPTAfterPOP; break;
281  case 33: pValues[nProp] >>= m_sInServerName; break;
282  case 34: pValues[nProp] >>= m_nInServerPort; break;
283  case 35: pValues[nProp] >>= m_bInServerPOP; break;
284  case 36: pValues[nProp] >>= m_sInServerUserName; break;
285  case 37: pValues[nProp] >>= m_sInServerPassword; break;
286  case 38: pValues[nProp] >>= m_bIsHideEmptyParagraphs; break;
287  case 39: pValues[nProp] >>= m_nCurrentAddressBlock; break;
288  }
289  }
290  }
291  //read the list of data base assignments
293  if(aAssignments.hasElements())
294  {
295  //create a list of property names to load the URLs of all data bases
296  const OUString* pAssignments = aAssignments.getConstArray();
297  Sequence< OUString > aAssignProperties(4 * aAssignments.getLength());
298  OUString* pAssignProperties = aAssignProperties.getArray();
299  sal_Int32 nAssign;
300  for(nAssign = 0; nAssign < aAssignProperties.getLength(); nAssign += 4)
301  {
302  OUString sAssignPath = cAddressDataAssignments;
303  sAssignPath += "/";
304  sAssignPath += pAssignments[nAssign / 4];
305  sAssignPath += "/";
306  pAssignProperties[nAssign] = sAssignPath;
307  pAssignProperties[nAssign] += cDataSourceName;
308  pAssignProperties[nAssign + 1] = sAssignPath;
309  pAssignProperties[nAssign + 1] += cDataTableName;
310  pAssignProperties[nAssign + 2] = sAssignPath;
311  pAssignProperties[nAssign + 2] += cDataCommandType;
312  pAssignProperties[nAssign + 3] = sAssignPath;
313  pAssignProperties[nAssign + 3] += cDBColumnAssignments;
314  }
315  Sequence<Any> aAssignValues = GetProperties(aAssignProperties);
316  const Any* pAssignValues = aAssignValues.getConstArray();
317  for(nAssign = 0; nAssign < aAssignValues.getLength(); nAssign += 4 )
318  {
319  DBAddressDataAssignment aAssignment;
320  pAssignValues[nAssign] >>= aAssignment.aDBData.sDataSource;
321  pAssignValues[nAssign + 1] >>= aAssignment.aDBData.sCommand;
322  pAssignValues[nAssign + 2] >>= aAssignment.aDBData.nCommandType;
323  pAssignValues[nAssign + 3] >>= aAssignment.aDBColumnAssignments;
324  aAssignment.sConfigNodeName = pAssignments[nAssign / 4];
325  m_aAddressDataAssignments.push_back(aAssignment);
326  }
327  }
328  //check if the saved documents still exist
329  if(m_aSavedDocuments.hasElements())
330  {
331  uno::Sequence< OUString > aTempDocuments(m_aSavedDocuments.getLength());
332  OUString* pTempDocuments = std::copy_if(m_aSavedDocuments.begin(), m_aSavedDocuments.end(), aTempDocuments.begin(),
333  [](const OUString& rDoc) { return SWUnoHelper::UCB_IsFile( rDoc ); });
334  sal_Int32 nIndex = static_cast<sal_Int32>(std::distance(aTempDocuments.begin(), pTempDocuments));
335  if(nIndex < m_aSavedDocuments.getLength())
336  {
337  m_aSavedDocuments = aTempDocuments;
338  m_aSavedDocuments.realloc(nIndex);
339  }
340  }
341 }
342 
344 {
345  if(m_aAddressBlocks.size() >= sal::static_int_cast<sal_uInt32, sal_Int32>(nSet))
346  {
347  m_nCurrentAddressBlock = nSet;
348  SetModified();
349  }
350 }
351 
352 static OUString lcl_CreateNodeName(Sequence<OUString>& rAssignments )
353 {
354  sal_Int32 nStart = rAssignments.getLength();
355  OUString sNewName;
356  //search if the name exists
357  while(true)
358  {
359  sNewName = "_" + OUString::number(nStart++);
360  if(comphelper::findValue(rAssignments, sNewName) == -1)
361  break;
362  }
363  // add the new name to the array of existing names
364  rAssignments.realloc(rAssignments.getLength() + 1);
365  rAssignments.getArray()[rAssignments.getLength() - 1] = sNewName;
366  return sNewName;
367 }
368 
369 static void lcl_ConvertToNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders )
370 {
371  //convert the strings used for UI to numbers used for the configuration
372  OUString sBlock(rBlock.replaceAll("\n", "\\n"));
373  for (size_t i = 0; i < rHeaders.size(); ++i)
374  {
375  OUString sHeader = "<" + rHeaders[i].first + ">";
376  OUString sReplace = "<" + OUStringLiteral1('0' + i) + ">";
377  sBlock = sBlock.replaceAll(sHeader, sReplace);
378  }
379  rBlock = sBlock;
380 }
381 
382 static void lcl_ConvertFromNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders)
383 {
384  //convert the numbers used for the configuration to strings used for UI to numbers
385  //doesn't use ReplaceAll to prevent expansion of numbers inside of the headers
386  SwAddressIterator aGreetingIter(rBlock.replaceAll("\\n", "\n"));
387  OUStringBuffer sBlock;
388  while(aGreetingIter.HasMore())
389  {
390  SwMergeAddressItem aNext = aGreetingIter.Next();
391  if(aNext.bIsColumn)
392  {
393  //the text should be 1 characters long
394  sal_Unicode cChar = aNext.sText[0];
395  if(cChar >= '0' && cChar <= 'c')
396  {
397  sBlock.append("<");
398  sal_uInt16 nHeader = cChar - '0';
399  if(nHeader < rHeaders.size())
400  sBlock.append(rHeaders[nHeader].first);
401  sBlock.append(">");
402  }
403  else
404  {
405  SAL_WARN("sw.ui", "parse error in address block or greeting line");
406  }
407  }
408  else
409  sBlock.append(aNext.sText);
410  }
411  rBlock = sBlock.makeStringAndClear();
412 }
413 
415 {
416  static Sequence<OUString> aNames {
417  "OutputToLetter", // 0
418  "IncludeCountry", // 1
419  "ExcludeCountry", // 2
420  "AddressBlockSettings", // 3
421  "IsAddressBlock", // 4
422  "IsGreetingLine", // 5
423  "IsIndividualGreetingLine", // 6
424  "FemaleGreetingLines", // 7
425  "MaleGreetingLines", // 8
426  "NeutralGreetingLines", // 9
427  "CurrentFemaleGreeting", // 10
428  "CurrentMaleGreeting", // 11
429  "CurrentNeutralGreeting", // 12
430  "FemaleGenderValue", // 13
431  "MailDisplayName", // 14
432  "MailAddress", // 15
433  "IsMailReplyTo", // 16
434  "MailReplyTo", // 17
435  "MailServer", // 18
436  "MailPort", // 19
437  "IsSecureConnection", // 20
438  "IsAuthentication", // 21
439  "MailUserName", // 22
440  "MailPassword", // 23
441  "DataSource/DataSourceName", // 24
442  "DataSource/DataTableName", // 25
443  "DataSource/DataCommandType",// 26
444  "Filter", // 27
445  "SavedDocuments", // 28
446  "EMailSupported", // 29
447  "IsEMailGreetingLine", //30
448  "IsEMailIndividualGreetingLine", //31
449  "IsSMPTAfterPOP", //32
450  "InServerName", //33
451  "InServerPort", //34
452  "InServerIsPOP", //35
453  "InServerUserName", //36
454  "InServerPassword", //37
455  "IsHideEmptyParagraphs", //38
456  "CurrentAddressBlock" //39
457  };
458  return aNames;
459 }
460 
461 void SwMailMergeConfigItem_Impl::Notify( const css::uno::Sequence< OUString >& ) {}
462 
464 {
466  Sequence<Any> aValues(aNames.getLength());
467  Any* pValues = aValues.getArray();
468 
469  for(int nProp = 0; nProp < aNames.getLength(); nProp++)
470  {
471  switch(nProp)
472  {
473  case 0: pValues[nProp] <<= m_bIsOutputToLetter; break;
474  case 1: pValues[nProp] <<= m_bIncludeCountry; break;
475  case 2: pValues[nProp] <<= m_sExcludeCountry; break;
476  case 3: pValues[nProp] <<= GetAddressBlocks(true); break;
477  case 4:
478  {
480  pValues[nProp] <<= m_bIsAddressBlock_LastUserSetting;
481  else
482  pValues[nProp] <<= m_bIsAddressBlock;
483  break;
484  }
485  case 5:
486  {
488  pValues[nProp] <<= m_bIsGreetingLine_LastUserSetting;
489  else
490  pValues[nProp] <<= m_bIsGreetingLine;
491  break;
492  }
493  case 6: pValues[nProp] <<= m_bIsIndividualGreetingLine; break;
494  case 7:
495  case 8:
496  case 9:
497  pValues[nProp] <<= GetGreetings(
499  SwMailMergeConfigItem::FEMALE + nProp - 7), true);
500  break;
501  case 10: pValues[nProp] <<= m_nCurrentFemaleGreeting; break;
502  case 11: pValues[nProp] <<= m_nCurrentMaleGreeting; break;
503  case 12: pValues[nProp] <<= m_nCurrentNeutralGreeting; break;
504  case 13: pValues[nProp] <<= m_sFemaleGenderValue; break;
505  case 14: pValues[nProp] <<= m_sMailDisplayName; break;
506  case 15: pValues[nProp] <<= m_sMailAddress; break;
507  case 16: pValues[nProp] <<= m_bIsMailReplyTo; break;
508  case 17: pValues[nProp] <<= m_sMailReplyTo; break;
509  case 18: pValues[nProp] <<= m_sMailServer; break;
510  case 19: pValues[nProp] <<= m_nMailPort; break;
511  case 20: pValues[nProp] <<= m_bIsSecureConnection; break;
512  case 21: pValues[nProp] <<= m_bIsAuthentication; break;
513  case 22: pValues[nProp] <<= m_sMailUserName; break;
514  case 23: pValues[nProp] <<= m_sMailPassword; break;
515  case 24 :pValues[nProp] <<= m_aDBData.sDataSource; break;
516  case 25 :pValues[nProp] <<= m_aDBData.sCommand; break;
517  case 26 :pValues[nProp] <<= static_cast<short>(m_aDBData.nCommandType); break;
518  case 27 :pValues[nProp] <<= m_sFilter; break;
519  case 28 :pValues[nProp] <<= m_aSavedDocuments; break;
520  case 29: pValues[nProp] <<= m_bIsEMailSupported; break;
521  case 30:
522  {
524  pValues[nProp] <<= m_bIsGreetingLineInMail_LastUserSetting;
525  else
526  pValues[nProp] <<= m_bIsGreetingLineInMail;
527  break;
528  }
529  case 31: pValues[nProp] <<= m_bIsIndividualGreetingLineInMail; break;
530  case 32: pValues[nProp] <<= m_bIsSMPTAfterPOP; break;
531  case 33: pValues[nProp] <<= m_sInServerName; break;
532  case 34: pValues[nProp] <<= m_nInServerPort; break;
533  case 35: pValues[nProp] <<= m_bInServerPOP; break;
534  case 36: pValues[nProp] <<= m_sInServerUserName; break;
535  case 37: pValues[nProp] <<= m_sInServerPassword; break;
536  case 38: pValues[nProp] <<= m_bIsHideEmptyParagraphs; break;
537  case 39: pValues[nProp] <<= m_nCurrentAddressBlock; break;
538  }
539  }
540  PutProperties(aNames, aValues);
541  //store the changed / new assignments
542 
543  //load the existing node names to find new names
545 
546  for(const auto& rAssignment : m_aAddressDataAssignments)
547  {
548  if(rAssignment.bColumnAssignmentsChanged)
549  {
550  //create a new node name
551  OUString sNewNode = !rAssignment.sConfigNodeName.isEmpty() ?
552  rAssignment.sConfigNodeName :
553  lcl_CreateNodeName(aAssignments);
554  OUString sSlash = "/";
555  OUString sNodePath = cAddressDataAssignments;
556  sNodePath += sSlash;
557  sNodePath += sNewNode;
558  sNodePath += sSlash;
559  //only one new entry is written
560  Sequence< PropertyValue > aNewValues(4);
561  PropertyValue* pNewValues = aNewValues.getArray();
562  pNewValues[0].Name = sNodePath;
563  pNewValues[0].Name += cDataSourceName;
564  pNewValues[0].Value <<= rAssignment.aDBData.sDataSource;
565  pNewValues[1].Name = sNodePath;
566  pNewValues[1].Name += cDataTableName;
567  pNewValues[1].Value <<= rAssignment.aDBData.sCommand;
568  pNewValues[2].Name = sNodePath;
569  pNewValues[2].Name += cDataCommandType;
570  pNewValues[2].Value <<= rAssignment.aDBData.nCommandType;
571  pNewValues[3].Name = sNodePath;
572  pNewValues[3].Name += cDBColumnAssignments;
573  pNewValues[3].Value <<= rAssignment.aDBColumnAssignments;
574 
576  }
577  }
578 
580 }
581 
583  bool bConvertToConfig) const
584 {
586  std::transform(m_aAddressBlocks.begin(), m_aAddressBlocks.end(), aRet.begin(),
587  [this, bConvertToConfig](const OUString& rBlock) -> OUString {
588  OUString sBlock = rBlock;
589  if(bConvertToConfig)
591  return sBlock;
592  });
593  return aRet;
594 }
595 
597  const Sequence< OUString>& rBlocks,
598  bool bConvertFromConfig)
599 {
600  m_aAddressBlocks.clear();
601  std::transform(rBlocks.begin(), rBlocks.end(), std::back_inserter(m_aAddressBlocks),
602  [this, bConvertFromConfig](const OUString& rBlock) -> OUString {
603  OUString sBlock = rBlock;
604  if(bConvertFromConfig)
606  return sBlock;
607  });
609  SetModified();
610 }
611 
613  SwMailMergeConfigItem::Gender eType, bool bConvertToConfig) const
614 {
615  const std::vector< OUString>& rGreetings =
619  Sequence< OUString> aRet(rGreetings.size());
620  std::transform(rGreetings.begin(), rGreetings.end(), aRet.begin(),
621  [this, bConvertToConfig](const OUString& rGreeting) -> OUString {
622  OUString sGreeting = rGreeting;
623  if(bConvertToConfig)
625  return sGreeting;
626  });
627  return aRet;
628 }
629 
632  const Sequence< OUString>& rSetGreetings,
633  bool bConvertFromConfig)
634 {
635  std::vector< OUString>& rGreetings =
639 
640  rGreetings.clear();
641  std::transform(rSetGreetings.begin(), rSetGreetings.end(), std::back_inserter(rGreetings),
642  [this, bConvertFromConfig](const OUString& rGreeting) -> OUString {
643  OUString sGreeting = rGreeting;
644  if(bConvertFromConfig)
646  return sGreeting;
647  });
648  SetModified();
649 }
650 
652  SwMailMergeConfigItem::Gender eType) const
653 {
654  sal_Int32 nRet;
655  switch(eType)
656  {
659  default: nRet = m_nCurrentNeutralGreeting; break;
660  }
661  return nRet;
662 }
663 
665  SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
666 {
667  bool bChanged = false;
668  switch(eType)
669  {
671  bChanged = m_nCurrentFemaleGreeting != nIndex;
672  m_nCurrentFemaleGreeting = nIndex;
673  break;
675  bChanged = m_nCurrentMaleGreeting != nIndex;
676  m_nCurrentMaleGreeting = nIndex;
677  break;
678  default:
679  bChanged = m_nCurrentNeutralGreeting != nIndex;
680  m_nCurrentNeutralGreeting = nIndex;
681  }
682  if(bChanged)
683  SetModified();
684 }
685 
688  m_bAddressInserted(false),
689  m_bGreetingInserted(false),
690  m_nGreetingMoves(0),
691  m_pSourceView(nullptr),
692  m_pTargetView(nullptr)
693 {
694 }
695 
697 {
698  if (m_xDBChangedListener.is())
699  {
700  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
701  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
702  m_xDBChangedListener.clear();
703  }
704 }
705 
707 {
708  const SwDBData& rDBData = m_pSourceView->GetWrtShell().GetDBDesc();
709  SetCurrentDBData(rDBData);
710 }
711 
713 {
715 }
716 
718 {
719  if(m_pImpl->IsModified())
720  m_pImpl->Commit();
721 }
722 
723 const std::vector<std::pair<OUString, int>>& SwMailMergeConfigItem::GetDefaultAddressHeaders() const
724 {
725  return m_pImpl->m_AddressHeaderSA;
726 }
727 
729  const Sequence< OUString>& rBlocks)
730 {
731  m_pImpl->SetAddressBlocks(rBlocks);
732 }
733 
735 {
736  return m_pImpl->GetAddressBlocks();
737 }
738 
740 {
741  return m_pImpl->m_bIsAddressBlock && IsOutputToLetter();
742 }
743 
745 {
746  m_pImpl->m_bUserSettingWereOverwritten = false;
747  if(m_pImpl->m_bIsAddressBlock != bSet)
748  {
749  m_pImpl->m_bIsAddressBlock = bSet;
750  m_pImpl->SetModified();
751  }
752 }
753 
755 {
756  return m_pImpl->m_bIsHideEmptyParagraphs;
757 }
758 
760 {
761  if(m_pImpl->m_bIsHideEmptyParagraphs != bSet)
762  {
763  m_pImpl->m_bIsHideEmptyParagraphs = bSet;
764  m_pImpl->SetModified();
765  }
766 }
767 
769 {
770  return m_pImpl->m_bIncludeCountry;
771 }
772 
774 {
775  return m_pImpl->m_sExcludeCountry;
776 }
777 
778 void SwMailMergeConfigItem::SetCountrySettings(bool bSet, const OUString& rCountry)
779 {
780  if(m_pImpl->m_sExcludeCountry != rCountry ||
781  m_pImpl->m_bIncludeCountry != bSet)
782  {
783  m_pImpl->m_bIncludeCountry = bSet;
784  m_pImpl->m_sExcludeCountry = bSet ? rCountry : OUString();
785  m_pImpl->SetModified();
786  }
787 }
788 
790  Reference< XDataSource> const & xSource,
791  const SharedConnection& rConnection,
792  Reference< XColumnsSupplier> const & xColumnsSupplier,
793  const SwDBData& rDBData)
794 {
795  m_pImpl->m_xSource = xSource ;
796  m_pImpl->m_xConnection = rConnection ;
797  m_pImpl->m_xColumnsSupplier = xColumnsSupplier;
798  m_pImpl->m_aDBData = rDBData;
799  m_pImpl->m_xResultSet = nullptr;
800  m_pImpl->m_nResultSetCursorPos = 0;
801  m_pImpl->SetModified();
802 }
803 
805 {
806  return m_pImpl->m_xSource;
807 }
808 
810 {
811  return m_pImpl->m_xConnection;
812 }
813 
814 Reference< XColumnsSupplier> const & SwMailMergeConfigItem::GetColumnsSupplier()
815 {
816  if(!m_pImpl->m_xColumnsSupplier.is() && m_pImpl->m_xConnection.is())
817  {
818  m_pImpl->m_xColumnsSupplier = SwDBManager::GetColumnSupplier(m_pImpl->m_xConnection,
819  m_pImpl->m_aDBData.sCommand,
820  m_pImpl->m_aDBData.nCommandType == CommandType::TABLE ?
822  }
823  return m_pImpl->m_xColumnsSupplier;
824 }
825 
827 {
828  return m_pImpl->m_aDBData;
829 }
830 
832 {
833  if(m_pImpl->m_aDBData != rDBData)
834  {
835  m_pImpl->m_aDBData = rDBData;
836  m_pImpl->m_xConnection.clear();
837  m_pImpl->m_xSource = nullptr;
838  m_pImpl->m_xResultSet = nullptr;
839  m_pImpl->m_xColumnsSupplier = nullptr;
840  m_pImpl->SetModified();
841  }
842 }
843 
844 Reference< XResultSet> const & SwMailMergeConfigItem::GetResultSet() const
845 {
846  if(!m_pImpl->m_xConnection.is() && !m_pImpl->m_aDBData.sDataSource.isEmpty())
847  {
848  m_pImpl->m_xConnection.reset(
849  SwDBManager::GetConnection(m_pImpl->m_aDBData.sDataSource, m_pImpl->m_xSource, m_pSourceView),
851  );
852  }
853  if(!m_pImpl->m_xResultSet.is() && m_pImpl->m_xConnection.is())
854  {
855  try
856  {
858 
859  Reference<XRowSet> xRowSet( xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY );
860  Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
861  xRowProperties->setPropertyValue("DataSourceName", makeAny(m_pImpl->m_aDBData.sDataSource));
862  xRowProperties->setPropertyValue("Command", makeAny(m_pImpl->m_aDBData.sCommand));
863  xRowProperties->setPropertyValue("CommandType", makeAny(m_pImpl->m_aDBData.nCommandType));
864  xRowProperties->setPropertyValue("FetchSize", makeAny(sal_Int32(10)));
865  xRowProperties->setPropertyValue("ActiveConnection", makeAny(m_pImpl->m_xConnection.getTyped()));
866  try
867  {
868  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
869  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
870  }
871  catch (const Exception&)
872  {
873  TOOLS_WARN_EXCEPTION("sw.ui", "");
874  }
875  xRowSet->execute();
876  m_pImpl->m_xResultSet = xRowSet.get();
877  m_pImpl->m_xResultSet->first();
878  m_pImpl->m_nResultSetCursorPos = 1;
879  }
880  catch (const Exception&)
881  {
882  TOOLS_WARN_EXCEPTION("sw.ui", "SwMailMergeConfigItem::GetResultSet()");
883  }
884  }
885  return m_pImpl->m_xResultSet;
886 }
887 
889 {
890  m_pImpl->m_xConnection.clear();
891  if(m_pImpl->m_xResultSet.is())
892  {
893  ::comphelper::disposeComponent( m_pImpl->m_xResultSet );
894  }
895 }
896 
898 {
899  return m_pImpl->m_sFilter;
900 }
901 
902 void SwMailMergeConfigItem::SetFilter(OUString const & rFilter)
903 {
904  if(m_pImpl->m_sFilter != rFilter)
905  {
906  m_pImpl->m_sFilter = rFilter;
907  m_pImpl->SetModified();
908  Reference<XPropertySet> xRowProperties(m_pImpl->m_xResultSet, UNO_QUERY);
909  if(xRowProperties.is())
910  {
911  try
912  {
913  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
914  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
915  uno::Reference<XRowSet> xRowSet( m_pImpl->m_xResultSet, UNO_QUERY_THROW );
916  xRowSet->execute();
917  }
918  catch (const Exception&)
919  {
920  TOOLS_WARN_EXCEPTION("sw.ui", "SwMailMergeConfigItem::SetFilter()");
921  }
922  }
923  }
924 }
925 
926 sal_Int32 SwMailMergeConfigItem::MoveResultSet(sal_Int32 nTarget)
927 {
928  if(!m_pImpl->m_xResultSet.is())
929  GetResultSet();
930  if(m_pImpl->m_xResultSet.is())
931  {
932  try
933  {
934  //no action if the resultset is already at the right position
935  if(m_pImpl->m_xResultSet->getRow() != nTarget)
936  {
937  if(nTarget > 0)
938  {
939  bool bMoved = m_pImpl->m_xResultSet->absolute(nTarget);
940  if(!bMoved)
941  {
942  if(nTarget > 1)
943  m_pImpl->m_xResultSet->last();
944  else if(nTarget == 1)
945  m_pImpl->m_xResultSet->first();
946  }
947  }
948  else if(nTarget == -1)
949  m_pImpl->m_xResultSet->last();
950  m_pImpl->m_nResultSetCursorPos = m_pImpl->m_xResultSet->getRow();
951  }
952  }
953  catch (const Exception&)
954  {
955  }
956  }
957  return m_pImpl->m_nResultSetCursorPos;
958 }
959 
960 bool SwMailMergeConfigItem::IsResultSetFirstLast(bool& bIsFirst, bool& bIsLast)
961 {
962  bool bRet = false;
963  if(!m_pImpl->m_xResultSet.is())
964  GetResultSet();
965  if(m_pImpl->m_xResultSet.is())
966  {
967  try
968  {
969  bIsFirst = m_pImpl->m_xResultSet->isFirst();
970  bIsLast = m_pImpl->m_xResultSet->isLast();
971  bRet = true;
972  }
973  catch (const Exception&)
974  {
975  }
976  }
977  return bRet;
978 }
979 
981 {
982  return m_pImpl->m_nResultSetCursorPos;
983 }
984 
985 bool SwMailMergeConfigItem::IsRecordExcluded(sal_Int32 nRecord) const
986  { return m_aExcludedRecords.find(nRecord) != m_aExcludedRecords.end(); }
987 
988 void SwMailMergeConfigItem::ExcludeRecord(sal_Int32 nRecord, bool bExclude)
989 {
990  if(bExclude)
991  m_aExcludedRecords.insert(nRecord);
992  else
993  m_aExcludedRecords.erase(nRecord);
994 }
995 
996 uno::Sequence<uno::Any> SwMailMergeConfigItem::GetSelection() const
997 {
998  if(!m_pImpl->m_xResultSet.is())
999  GetResultSet();
1000  if(!m_pImpl->m_xResultSet.is())
1001  return {};
1002  m_pImpl->m_xResultSet->last();
1003  sal_Int32 nResultSetSize = m_pImpl->m_xResultSet->getRow()+1;
1004  std::vector<uno::Any> vResult;
1005  vResult.reserve(nResultSetSize);
1006  for(sal_Int32 nIdx=1; nIdx<nResultSetSize;++nIdx)
1007  if(!IsRecordExcluded(nIdx))
1008  vResult.push_back(uno::makeAny<sal_Int32>(nIdx));
1009  return comphelper::containerToSequence(vResult);
1010 }
1011 
1012 
1013 const uno::Sequence< OUString>&
1015 {
1016  return m_pImpl->m_aSavedDocuments;
1017 }
1018 
1020 {
1021  return m_pImpl->m_bIsOutputToLetter || !IsMailAvailable();
1022 }
1023 
1025 {
1026  if(m_pImpl->m_bIsOutputToLetter != bSet)
1027  {
1028  m_pImpl->m_bIsOutputToLetter = bSet;
1029  m_pImpl->SetModified();
1030  }
1031 }
1032 
1034 {
1035  return bInEMail ?
1036  m_pImpl->m_bIsIndividualGreetingLineInMail :
1037  m_pImpl->m_bIsIndividualGreetingLine;
1038 }
1039 
1041  bool bSet, bool bInEMail)
1042 {
1043  if(bInEMail)
1044  {
1045  if(m_pImpl->m_bIsIndividualGreetingLineInMail != bSet)
1046  {
1047  m_pImpl->m_bIsIndividualGreetingLineInMail = bSet;
1048  m_pImpl->SetModified();
1049  }
1050  }
1051  else
1052  {
1053  if(m_pImpl->m_bIsIndividualGreetingLine != bSet)
1054  {
1055  m_pImpl->m_bIsIndividualGreetingLine = bSet;
1056  m_pImpl->SetModified();
1057  }
1058  }
1059 }
1060 
1061 bool SwMailMergeConfigItem::IsGreetingLine(bool bInEMail) const
1062 {
1063  return bInEMail ? m_pImpl->m_bIsGreetingLineInMail : m_pImpl->m_bIsGreetingLine;
1064 }
1065 
1066 void SwMailMergeConfigItem::SetGreetingLine(bool bSet, bool bInEMail)
1067 {
1068  m_pImpl->m_bUserSettingWereOverwritten = false;
1069  if(bInEMail)
1070  {
1071  if(m_pImpl->m_bIsGreetingLineInMail != bSet)
1072  {
1073  m_pImpl->m_bIsGreetingLineInMail = bSet;
1074  m_pImpl->SetModified();
1075  }
1076  }
1077  else
1078  {
1079  if(m_pImpl->m_bIsGreetingLine != bSet)
1080  {
1081  m_pImpl->m_bIsGreetingLine = bSet;
1082  m_pImpl->SetModified();
1083  }
1084  }
1085 }
1086 
1088  Gender eType ) const
1089 {
1090  return m_pImpl->GetGreetings(eType);
1091 }
1092 
1094  Gender eType, const Sequence< OUString>& rSetGreetings)
1095 {
1096  m_pImpl->SetGreetings( eType, rSetGreetings);
1097 }
1098 
1100  SwMailMergeConfigItem::Gender eType) const
1101 {
1102  return m_pImpl->GetCurrentGreeting(eType);
1103 }
1104 
1106 {
1107  m_pImpl->SetCurrentGreeting(eType, nIndex);
1108 }
1109 
1111 {
1112  return m_pImpl->m_sFemaleGenderValue;
1113 }
1114 
1116 {
1117  if( m_pImpl->m_sFemaleGenderValue != rValue )
1118  {
1119  m_pImpl->m_sFemaleGenderValue = rValue;
1120  m_pImpl->SetModified();
1121  }
1122 }
1123 
1125  const SwDBData& rDBData ) const
1126 {
1127  Sequence< OUString> aRet;
1128  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1129  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1130  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1131  {
1132  aRet = aAssignIter->aDBColumnAssignments;
1133  }
1134  return aRet;
1135 }
1136 
1137 // returns the name that is assigned as e-mail column of the current data base
1138 OUString SwMailMergeConfigItem::GetAssignedColumn(sal_uInt32 nColumn) const
1139 {
1140  OUString sRet;
1141  Sequence< OUString> aAssignment = GetColumnAssignment( m_pImpl->m_aDBData );
1142  if(aAssignment.getLength() > sal::static_int_cast< sal_Int32, sal_uInt32>(nColumn) && !aAssignment[nColumn].isEmpty())
1143  sRet = aAssignment[nColumn];
1144  else if(nColumn < m_pImpl->m_AddressHeaderSA.size())
1145  sRet = m_pImpl->m_AddressHeaderSA[nColumn].first;
1146  return sRet;
1147 }
1148 
1150  const Sequence< OUString>& rList)
1151 {
1152  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1153  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1154  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1155  {
1156  if(aAssignIter->aDBColumnAssignments != rList)
1157  {
1158  aAssignIter->aDBColumnAssignments = rList;
1159  aAssignIter->bColumnAssignmentsChanged = true;
1160  }
1161  }
1162  else
1163  {
1164  DBAddressDataAssignment aAssignment;
1165  aAssignment.aDBData = rDBData;
1166  aAssignment.aDBColumnAssignments = rList;
1167  aAssignment.bColumnAssignmentsChanged = true;
1168  m_pImpl->m_aAddressDataAssignments.push_back(aAssignment);
1169  }
1170  m_pImpl->SetModified();
1171 }
1172 
1174 {
1175  bool bResult = true;
1176  Reference< XResultSet> xResultSet = GetResultSet();
1177  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1178  if(!xColsSupp.is())
1179  return false;
1180  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1181 
1182  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1183  Sequence< OUString> aAssignment =
1185  const OUString* pAssignment = aAssignment.getConstArray();
1186  const Sequence< OUString> aBlocks = GetAddressBlocks();
1187 
1188  if(aBlocks.getLength() <= m_pImpl->GetCurrentAddressBlockIndex())
1189  return false;
1190  SwAddressIterator aIter(aBlocks[m_pImpl->GetCurrentAddressBlockIndex()]);
1191  while(aIter.HasMore())
1192  {
1193  SwMergeAddressItem aItem = aIter.Next();
1194  if(aItem.bIsColumn)
1195  {
1196  OUString sConvertedColumn = aItem.sText;
1197  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1198  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1199  {
1200  if (rHeaders[nColumn].first == aItem.sText &&
1201  !pAssignment[nColumn].isEmpty())
1202  {
1203  sConvertedColumn = pAssignment[nColumn];
1204  break;
1205  }
1206  }
1207  //find out if the column exists in the data base
1208  if(!xCols->hasByName(sConvertedColumn))
1209  {
1210  bResult = false;
1211  break;
1212  }
1213  }
1214  }
1215  return bResult;
1216 }
1217 
1219 {
1220  bool bResult = true;
1221 
1222  if(!IsIndividualGreeting(false))
1223  return true;
1224 
1225  Reference< XResultSet> xResultSet = GetResultSet();
1226  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1227  if(!xColsSupp.is())
1228  return false;
1229  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1230  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1231 
1232  Sequence< OUString> aAssignment =
1234  const OUString* pAssignment = aAssignment.getConstArray();
1235 
1237  sal_Int32 nCurrentFemale = GetCurrentGreeting(SwMailMergeConfigItem::FEMALE);
1239  sal_Int32 nCurrentMale = GetCurrentGreeting(SwMailMergeConfigItem::MALE);
1240  OUString sMale, sFemale;
1241  if(rFemaleEntries.getLength() > nCurrentFemale)
1242  sFemale = rFemaleEntries[nCurrentFemale];
1243  if(rMaleEntries.getLength() > nCurrentMale)
1244  sMale = rMaleEntries[nCurrentMale];
1245 
1246  OUString sAddress( sFemale );
1247  sAddress += sMale;
1248  SwAddressIterator aIter(sAddress);
1249  while(aIter.HasMore())
1250  {
1251  SwMergeAddressItem aItem = aIter.Next();
1252  if(aItem.bIsColumn)
1253  {
1254  OUString sConvertedColumn = aItem.sText;
1255  auto nSize = std::min(sal_uInt32(rHeaders.size()), sal_uInt32(aAssignment.getLength()));
1256  for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
1257  {
1258  if (rHeaders[nColumn].first == aItem.sText &&
1259  !pAssignment[nColumn].isEmpty())
1260  {
1261  sConvertedColumn = pAssignment[nColumn];
1262  break;
1263  }
1264  }
1265  //find out if the column exists in the data base
1266  if(!xCols->hasByName(sConvertedColumn))
1267  {
1268  bResult = false;
1269  break;
1270  }
1271  }
1272  }
1273  return bResult;
1274 }
1275 
1277 {
1278  return m_pImpl->m_sMailDisplayName;
1279 }
1280 
1282 {
1283  if(m_pImpl->m_sMailDisplayName != rName)
1284  {
1285  m_pImpl->m_sMailDisplayName = rName;
1286  m_pImpl->SetModified();
1287  }
1288 }
1289 
1291 {
1292  return m_pImpl->m_sMailAddress;
1293 }
1294 
1295 void SwMailMergeConfigItem::SetMailAddress(const OUString& rAddress)
1296 {
1297  if(m_pImpl->m_sMailAddress != rAddress )
1298  {
1299  m_pImpl->m_sMailAddress = rAddress;
1300  m_pImpl->SetModified();
1301  }
1302 }
1303 
1305 {
1306  return m_pImpl->m_bIsMailReplyTo;
1307 }
1308 
1310 {
1311  if(m_pImpl->m_bIsMailReplyTo != bSet)
1312  {
1313  m_pImpl->m_bIsMailReplyTo = bSet;
1314  m_pImpl->SetModified();
1315  }
1316 }
1317 
1319 {
1320  return m_pImpl->m_sMailReplyTo;
1321 }
1322 
1323 void SwMailMergeConfigItem::SetMailReplyTo(const OUString& rReplyTo)
1324 {
1325  if(m_pImpl->m_sMailReplyTo != rReplyTo)
1326  {
1327  m_pImpl->m_sMailReplyTo = rReplyTo;
1328  m_pImpl->SetModified();
1329  }
1330 }
1331 
1333 {
1334  return m_pImpl->m_sMailServer;
1335 }
1336 
1337 void SwMailMergeConfigItem::SetMailServer(const OUString& rAddress)
1338 {
1339  if(m_pImpl->m_sMailServer != rAddress)
1340  {
1341  m_pImpl->m_sMailServer = rAddress;
1342  m_pImpl->SetModified();
1343  }
1344 }
1345 
1347 {
1348  // provide appropriate TCP port, based on SSL/STARTTLS status, if current port is one of the defaults
1349  switch (m_pImpl->m_nMailPort)
1350  {
1351  case SECURE_PORT:
1352  case DEFAULT_PORT:
1353  return m_pImpl->m_bIsSecureConnection ? SECURE_PORT : DEFAULT_PORT;
1354  break;
1355  default:
1356  return m_pImpl->m_nMailPort;
1357  }
1358 }
1359 
1361 {
1362  if(m_pImpl->m_nMailPort != nSet)
1363  {
1364  m_pImpl->m_nMailPort = nSet;
1365  m_pImpl->SetModified();
1366  }
1367 }
1368 
1370 {
1371  return m_pImpl->m_bIsSecureConnection;
1372 }
1373 
1375 {
1376  if(m_pImpl->m_bIsSecureConnection != bSet)
1377  {
1378  m_pImpl->m_bIsSecureConnection = bSet;
1379  m_pImpl->SetModified();
1380  }
1381 }
1382 
1384 {
1385  return m_pImpl->m_bIsAuthentication;
1386 }
1387 
1389 {
1390  if(m_pImpl->m_bIsAuthentication != bSet)
1391  {
1392  m_pImpl->m_bIsAuthentication = bSet;
1393  m_pImpl->SetModified();
1394  }
1395 }
1396 
1398 {
1399  return m_pImpl->m_sMailUserName;
1400 }
1401 
1402 void SwMailMergeConfigItem::SetMailUserName(const OUString& rName)
1403 {
1404  if(m_pImpl->m_sMailUserName != rName)
1405  {
1406  m_pImpl->m_sMailUserName = rName;
1407  m_pImpl->SetModified();
1408  }
1409 }
1410 
1412 {
1413  return m_pImpl->m_sMailPassword;
1414 }
1415 
1416 void SwMailMergeConfigItem::SetMailPassword(const OUString& rPassword)
1417 {
1418  if(m_pImpl->m_sMailPassword != rPassword)
1419  {
1420  m_pImpl->m_sMailPassword = rPassword;
1421  m_pImpl->SetModified();
1422  }
1423 }
1424 
1426 {
1427  return m_pImpl->m_bIsSMPTAfterPOP;
1428 }
1429 
1431 {
1432  if( m_pImpl->m_bIsSMPTAfterPOP != bSet)
1433  {
1434  m_pImpl->m_bIsSMPTAfterPOP = bSet;
1435  m_pImpl->SetModified();
1436  }
1437 }
1438 
1440 {
1441  return m_pImpl->m_sInServerName;
1442 }
1443 
1444 void SwMailMergeConfigItem::SetInServerName(const OUString& rServer)
1445 {
1446  if(m_pImpl->m_sInServerName != rServer)
1447  {
1448  m_pImpl->m_sInServerName = rServer;
1449  m_pImpl->SetModified();
1450  }
1451 }
1452 
1454 {
1455  // provide appropriate TCP port as user toggles between POP/IMAP if current port is one of the defaults
1456  switch (m_pImpl->m_nInServerPort)
1457  {
1458  case POP_SECURE_PORT:
1459  case POP_PORT:
1460  case IMAP_SECURE_PORT:
1461  case IMAP_PORT:
1462  if ( m_pImpl->m_bInServerPOP )
1463  return m_pImpl->m_bIsSecureConnection ? POP_SECURE_PORT : POP_PORT;
1464  else
1465  return m_pImpl->m_bIsSecureConnection ? IMAP_SECURE_PORT : IMAP_PORT;
1466  break;
1467  default:
1468  return m_pImpl->m_nInServerPort;
1469  }
1470 }
1471 
1473 {
1474  if( m_pImpl->m_nInServerPort != nSet)
1475  {
1476  m_pImpl->m_nInServerPort = nSet;
1477  m_pImpl->SetModified();
1478  }
1479 }
1480 
1482 {
1483  return m_pImpl->m_bInServerPOP;
1484 }
1485 
1487 {
1488  if( m_pImpl->m_bInServerPOP != bSet)
1489  {
1490  m_pImpl->m_bInServerPOP = bSet;
1491  m_pImpl->SetModified();
1492  }
1493 }
1494 
1496 {
1497  return m_pImpl->m_sInServerUserName;
1498 }
1499 
1501 {
1502  if( m_pImpl->m_sInServerUserName != rName)
1503  {
1504  m_pImpl->m_sInServerUserName = rName;
1505  m_pImpl->SetModified();
1506  }
1507 }
1508 
1510 {
1511  return m_pImpl->m_sInServerPassword;
1512 }
1513 
1514 void SwMailMergeConfigItem::SetInServerPassword(const OUString& rPassword)
1515 {
1516  if(m_pImpl->m_sInServerPassword != rPassword)
1517  {
1518  m_pImpl->m_sInServerPassword = rPassword;
1519  m_pImpl->SetModified();
1520  }
1521 }
1522 
1524 {
1525  m_bGreetingInserted = false;
1526  m_bAddressInserted = false;
1527 }
1528 
1530 {
1531  return m_pImpl->m_bIsEMailSupported;
1532 }
1533 
1535 {
1536  m_pImpl->m_aMergeInfos.push_back(rInfo);
1537 }
1538 
1540 {
1541  assert(nDocument < m_pImpl->m_aMergeInfos.size());
1542  return m_pImpl->m_aMergeInfos[nDocument];
1543 }
1544 
1545 
1547 {
1548  if(m_pTargetView)
1549  return m_pImpl->m_aMergeInfos.size();
1550  else
1551  {
1552  sal_Int32 nRestore = GetResultSetPosition();
1553  MoveResultSet(-1);
1554  sal_Int32 nRet = GetResultSetPosition();
1555  MoveResultSet( nRestore );
1556  nRet -= m_aExcludedRecords.size();
1557  return nRet >= 0 ? nRet : 0;
1558  }
1559 }
1560 
1562 {
1563  SfxViewShell* pViewShell = SfxViewShell::GetFirst( false, checkSfxViewShell<SwView> );
1564  while(pViewShell)
1565  {
1566  if(pViewShell == pView)
1567  return pView;
1568 
1569  pViewShell = SfxViewShell::GetNext( *pViewShell, false, checkSfxViewShell<SwView> );
1570  }
1571  return nullptr;
1572 }
1573 
1575 {
1576  //make sure that the pointer is really valid - the document may have been closed manually
1577  if(m_pTargetView)
1578  {
1580  }
1581  return m_pTargetView;
1582 }
1583 
1585 {
1586  m_pTargetView = pView;
1587  //reset the document merge counter
1588  if(!m_pTargetView)
1589  {
1590  m_pImpl->m_aMergeInfos.clear();
1591  }
1592 }
1593 
1595 {
1597  return m_pSourceView;
1598 }
1599 
1600 //This implements XSelectionChangeListener and XDispatch because the
1601 //broadcaster uses this combo to determine if to send the database-changed
1602 //update. Its probably that listening to statusChanged at some other level is
1603 //equivalent to this. See the other call to SwXDispatch::GetDBChangeURL for
1604 //the broadcaster of the event.
1605 class DBChangeListener : public cppu::WeakImplHelper<css::view::XSelectionChangeListener, css::frame::XDispatch>
1606 {
1608 public:
1610  : m_rParent(rParent)
1611  {
1612  }
1613 
1614  virtual void SAL_CALL selectionChanged(const EventObject& /*rEvent*/) override
1615  {
1616  }
1617 
1618  virtual void SAL_CALL disposing(const EventObject&) override
1619  {
1620  m_rParent.stopDBChangeListening();
1621  }
1622 
1623  virtual void SAL_CALL dispatch(const css::util::URL& rURL, const css::uno::Sequence< css::beans::PropertyValue >& /*rArgs*/) override
1624  {
1625  if (rURL.Complete.equalsAscii(SwXDispatch::GetDBChangeURL()))
1626  m_rParent.updateCurrentDBDataFromDocument();
1627  }
1628 
1629  virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1630  {
1631  }
1632 
1633  virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1634  {
1635  }
1636 };
1637 
1639 {
1640  if (m_xDBChangedListener.is())
1641  {
1642  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1643  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
1644  m_xDBChangedListener.clear();
1645  }
1646 
1647  m_pSourceView = pView;
1648 
1649  if (!m_pSourceView)
1650  return;
1651 
1652  std::vector<OUString> aDBNameList;
1653  std::vector<OUString> aAllDBNames;
1654  m_pSourceView->GetWrtShell().GetAllUsedDB( aDBNameList, &aAllDBNames );
1655  if(!aDBNameList.empty())
1656  {
1657  // if fields are available there is usually no need of an addressblock and greeting
1658  if(!m_pImpl->m_bUserSettingWereOverwritten)
1659  {
1660  if( m_pImpl->m_bIsAddressBlock
1661  || m_pImpl->m_bIsGreetingLineInMail
1662  || m_pImpl->m_bIsGreetingLine )
1663  {
1664  //store user settings
1665  m_pImpl->m_bUserSettingWereOverwritten = true;
1666  m_pImpl->m_bIsAddressBlock_LastUserSetting = m_pImpl->m_bIsAddressBlock;
1667  m_pImpl->m_bIsGreetingLineInMail_LastUserSetting = m_pImpl->m_bIsGreetingLineInMail;
1668  m_pImpl->m_bIsGreetingLine_LastUserSetting = m_pImpl->m_bIsGreetingLine;
1669 
1670  //set all to false
1671  m_pImpl->m_bIsAddressBlock = false;
1672  m_pImpl->m_bIsGreetingLineInMail = false;
1673  m_pImpl->m_bIsGreetingLine = false;
1674 
1675  m_pImpl->SetModified();
1676  }
1677  }
1678  }
1679  else if( m_pImpl->m_bUserSettingWereOverwritten )
1680  {
1681  //restore last user settings:
1682  m_pImpl->m_bIsAddressBlock = m_pImpl->m_bIsAddressBlock_LastUserSetting;
1683  m_pImpl->m_bIsGreetingLineInMail = m_pImpl->m_bIsGreetingLineInMail_LastUserSetting;
1684  m_pImpl->m_bIsGreetingLine = m_pImpl->m_bIsGreetingLine_LastUserSetting;
1685 
1686  m_pImpl->m_bUserSettingWereOverwritten = false;
1687  }
1688 
1689  if (!m_xDBChangedListener.is())
1690  {
1691  m_xDBChangedListener.set(new DBChangeListener(*this));
1692  }
1693 
1694  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1695  xSupplier->addSelectionChangeListener(m_xDBChangedListener);
1696 }
1697 
1699 {
1700  m_pImpl->SetCurrentAddressBlockIndex( nSet );
1701 }
1702 
1704 {
1705  return m_pImpl->GetCurrentAddressBlockIndex();
1706 }
1707 
1708 /* 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:2987
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< 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
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)
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)
SwMailMergeConfigItem & m_rParent
bool IsRecordExcluded(sal_Int32 nRecord) 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)
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 TOOLS_WARN_EXCEPTION(area, stream)
#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)
OUString const & GetMailReplyTo() const
sal_Int32 GetResultSetPosition() const
void SetFilter(OUString const &)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
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
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
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
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
Sequence< OUString > GetAddressBlocks(bool bConvertToConfig=false) const
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)