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 = aTempDocuments.getArray();
334  sal_Int32 nIndex = 0;
335  for(sal_Int32 i = 0; i < m_aSavedDocuments.getLength(); ++i)
336  {
338  {
339  pTempDocuments[nIndex++] = m_aSavedDocuments[i];
340  }
341  }
342  if(nIndex < m_aSavedDocuments.getLength())
343  {
344  m_aSavedDocuments = aTempDocuments;
345  m_aSavedDocuments.realloc(nIndex);
346  }
347  }
348 }
349 
351 {
352  if(m_aAddressBlocks.size() >= sal::static_int_cast<sal_uInt32, sal_Int32>(nSet))
353  {
354  m_nCurrentAddressBlock = nSet;
355  SetModified();
356  }
357 }
358 
359 static OUString lcl_CreateNodeName(Sequence<OUString>& rAssignments )
360 {
361  const OUString* pNames = rAssignments.getConstArray();
362  sal_Int32 nStart = rAssignments.getLength();
363  OUString sNewName;
364  bool bFound;
365  do
366  {
367  bFound = false;
368  sNewName = "_" + OUString::number(nStart);
369  //search if the name exists
370  for(sal_Int32 nAssign = 0; nAssign < rAssignments.getLength(); ++nAssign)
371  {
372  if(pNames[nAssign] == sNewName)
373  {
374  bFound = true;
375  ++nStart;
376  break;
377  }
378  }
379  }
380  while(bFound);
381  // add the new name to the array of existing names
382  rAssignments.realloc(rAssignments.getLength() + 1);
383  rAssignments.getArray()[rAssignments.getLength() - 1] = sNewName;
384  return sNewName;
385 }
386 
387 static void lcl_ConvertToNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders )
388 {
389  //convert the strings used for UI to numbers used for the configuration
390  OUString sBlock(rBlock.replaceAll("\n", "\\n"));
391  for (size_t i = 0; i < rHeaders.size(); ++i)
392  {
393  OUString sHeader = "<" + rHeaders[i].first + ">";
394  OUString sReplace = "<" + OUStringLiteral1('0' + i) + ">";
395  sBlock = sBlock.replaceAll(sHeader, sReplace);
396  }
397  rBlock = sBlock;
398 }
399 
400 static void lcl_ConvertFromNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders)
401 {
402  //convert the numbers used for the configuration to strings used for UI to numbers
403  //doesn't use ReplaceAll to prevent expansion of numbers inside of the headers
404  SwAddressIterator aGreetingIter(rBlock.replaceAll("\\n", "\n"));
405  OUStringBuffer sBlock;
406  while(aGreetingIter.HasMore())
407  {
408  SwMergeAddressItem aNext = aGreetingIter.Next();
409  if(aNext.bIsColumn)
410  {
411  //the text should be 1 characters long
412  sal_Unicode cChar = aNext.sText[0];
413  if(cChar >= '0' && cChar <= 'c')
414  {
415  sBlock.append("<");
416  sal_uInt16 nHeader = cChar - '0';
417  if(nHeader < rHeaders.size())
418  sBlock.append(rHeaders[nHeader].first);
419  sBlock.append(">");
420  }
421  else
422  {
423  SAL_WARN("sw.ui", "parse error in address block or greeting line");
424  }
425  }
426  else
427  sBlock.append(aNext.sText);
428  }
429  rBlock = sBlock.makeStringAndClear();
430 }
431 
433 {
434  static Sequence<OUString> aNames {
435  "OutputToLetter", // 0
436  "IncludeCountry", // 1
437  "ExcludeCountry", // 2
438  "AddressBlockSettings", // 3
439  "IsAddressBlock", // 4
440  "IsGreetingLine", // 5
441  "IsIndividualGreetingLine", // 6
442  "FemaleGreetingLines", // 7
443  "MaleGreetingLines", // 8
444  "NeutralGreetingLines", // 9
445  "CurrentFemaleGreeting", // 10
446  "CurrentMaleGreeting", // 11
447  "CurrentNeutralGreeting", // 12
448  "FemaleGenderValue", // 13
449  "MailDisplayName", // 14
450  "MailAddress", // 15
451  "IsMailReplyTo", // 16
452  "MailReplyTo", // 17
453  "MailServer", // 18
454  "MailPort", // 19
455  "IsSecureConnection", // 20
456  "IsAuthentication", // 21
457  "MailUserName", // 22
458  "MailPassword", // 23
459  "DataSource/DataSourceName", // 24
460  "DataSource/DataTableName", // 25
461  "DataSource/DataCommandType",// 26
462  "Filter", // 27
463  "SavedDocuments", // 28
464  "EMailSupported", // 29
465  "IsEMailGreetingLine", //30
466  "IsEMailIndividualGreetingLine", //31
467  "IsSMPTAfterPOP", //32
468  "InServerName", //33
469  "InServerPort", //34
470  "InServerIsPOP", //35
471  "InServerUserName", //36
472  "InServerPassword", //37
473  "IsHideEmptyParagraphs", //38
474  "CurrentAddressBlock" //39
475  };
476  return aNames;
477 }
478 
479 void SwMailMergeConfigItem_Impl::Notify( const css::uno::Sequence< OUString >& ) {}
480 
482 {
484  Sequence<Any> aValues(aNames.getLength());
485  Any* pValues = aValues.getArray();
486 
487  for(int nProp = 0; nProp < aNames.getLength(); nProp++)
488  {
489  switch(nProp)
490  {
491  case 0: pValues[nProp] <<= m_bIsOutputToLetter; break;
492  case 1: pValues[nProp] <<= m_bIncludeCountry; break;
493  case 2: pValues[nProp] <<= m_sExcludeCountry; break;
494  case 3: pValues[nProp] <<= GetAddressBlocks(true); break;
495  case 4:
496  {
498  pValues[nProp] <<= m_bIsAddressBlock_LastUserSetting;
499  else
500  pValues[nProp] <<= m_bIsAddressBlock;
501  break;
502  }
503  case 5:
504  {
506  pValues[nProp] <<= m_bIsGreetingLine_LastUserSetting;
507  else
508  pValues[nProp] <<= m_bIsGreetingLine;
509  break;
510  }
511  case 6: pValues[nProp] <<= m_bIsIndividualGreetingLine; break;
512  case 7:
513  case 8:
514  case 9:
515  pValues[nProp] <<= GetGreetings(
517  SwMailMergeConfigItem::FEMALE + nProp - 7), true);
518  break;
519  case 10: pValues[nProp] <<= m_nCurrentFemaleGreeting; break;
520  case 11: pValues[nProp] <<= m_nCurrentMaleGreeting; break;
521  case 12: pValues[nProp] <<= m_nCurrentNeutralGreeting; break;
522  case 13: pValues[nProp] <<= m_sFemaleGenderValue; break;
523  case 14: pValues[nProp] <<= m_sMailDisplayName; break;
524  case 15: pValues[nProp] <<= m_sMailAddress; break;
525  case 16: pValues[nProp] <<= m_bIsMailReplyTo; break;
526  case 17: pValues[nProp] <<= m_sMailReplyTo; break;
527  case 18: pValues[nProp] <<= m_sMailServer; break;
528  case 19: pValues[nProp] <<= m_nMailPort; break;
529  case 20: pValues[nProp] <<= m_bIsSecureConnection; break;
530  case 21: pValues[nProp] <<= m_bIsAuthentication; break;
531  case 22: pValues[nProp] <<= m_sMailUserName; break;
532  case 23: pValues[nProp] <<= m_sMailPassword; break;
533  case 24 :pValues[nProp] <<= m_aDBData.sDataSource; break;
534  case 25 :pValues[nProp] <<= m_aDBData.sCommand; break;
535  case 26 :pValues[nProp] <<= static_cast<short>(m_aDBData.nCommandType); break;
536  case 27 :pValues[nProp] <<= m_sFilter; break;
537  case 28 :pValues[nProp] <<= m_aSavedDocuments; break;
538  case 29: pValues[nProp] <<= m_bIsEMailSupported; break;
539  case 30:
540  {
542  pValues[nProp] <<= m_bIsGreetingLineInMail_LastUserSetting;
543  else
544  pValues[nProp] <<= m_bIsGreetingLineInMail;
545  break;
546  }
547  case 31: pValues[nProp] <<= m_bIsIndividualGreetingLineInMail; break;
548  case 32: pValues[nProp] <<= m_bIsSMPTAfterPOP; break;
549  case 33: pValues[nProp] <<= m_sInServerName; break;
550  case 34: pValues[nProp] <<= m_nInServerPort; break;
551  case 35: pValues[nProp] <<= m_bInServerPOP; break;
552  case 36: pValues[nProp] <<= m_sInServerUserName; break;
553  case 37: pValues[nProp] <<= m_sInServerPassword; break;
554  case 38: pValues[nProp] <<= m_bIsHideEmptyParagraphs; break;
555  case 39: pValues[nProp] <<= m_nCurrentAddressBlock; break;
556  }
557  }
558  PutProperties(aNames, aValues);
559  //store the changed / new assignments
560 
561  //load the existing node names to find new names
563 
564  for(const auto& rAssignment : m_aAddressDataAssignments)
565  {
566  if(rAssignment.bColumnAssignmentsChanged)
567  {
568  //create a new node name
569  OUString sNewNode = !rAssignment.sConfigNodeName.isEmpty() ?
570  rAssignment.sConfigNodeName :
571  lcl_CreateNodeName(aAssignments);
572  OUString sSlash = "/";
573  OUString sNodePath = cAddressDataAssignments;
574  sNodePath += sSlash;
575  sNodePath += sNewNode;
576  sNodePath += sSlash;
577  //only one new entry is written
578  Sequence< PropertyValue > aNewValues(4);
579  PropertyValue* pNewValues = aNewValues.getArray();
580  pNewValues[0].Name = sNodePath;
581  pNewValues[0].Name += cDataSourceName;
582  pNewValues[0].Value <<= rAssignment.aDBData.sDataSource;
583  pNewValues[1].Name = sNodePath;
584  pNewValues[1].Name += cDataTableName;
585  pNewValues[1].Value <<= rAssignment.aDBData.sCommand;
586  pNewValues[2].Name = sNodePath;
587  pNewValues[2].Name += cDataCommandType;
588  pNewValues[2].Value <<= rAssignment.aDBData.nCommandType;
589  pNewValues[3].Name = sNodePath;
590  pNewValues[3].Name += cDBColumnAssignments;
591  pNewValues[3].Value <<= rAssignment.aDBColumnAssignments;
592 
594  }
595  }
596 
598 }
599 
601  bool bConvertToConfig) const
602 {
604  OUString* pRet = aRet.getArray();
605  for(size_t nBlock = 0; nBlock < m_aAddressBlocks.size(); nBlock++)
606  {
607  pRet[nBlock] = m_aAddressBlocks[nBlock];
608  if(bConvertToConfig)
610  }
611  return aRet;
612 }
613 
615  const Sequence< OUString>& rBlocks,
616  bool bConvertFromConfig)
617 {
618  m_aAddressBlocks.clear();
619  for(sal_Int32 nBlock = 0; nBlock < rBlocks.getLength(); nBlock++)
620  {
621  OUString sBlock = rBlocks[nBlock];
622  if(bConvertFromConfig)
624  m_aAddressBlocks.push_back(sBlock);
625  }
627  SetModified();
628 }
629 
631  SwMailMergeConfigItem::Gender eType, bool bConvertToConfig) const
632 {
633  const std::vector< OUString>& rGreetings =
637  Sequence< OUString> aRet(rGreetings.size());
638  OUString* pRet = aRet.getArray();
639  for(size_t nGreeting = 0; nGreeting < rGreetings.size(); nGreeting++)
640  {
641  pRet[nGreeting] = rGreetings[nGreeting];
642  if(bConvertToConfig)
643  lcl_ConvertToNumbers(pRet[nGreeting], m_AddressHeaderSA);
644  }
645  return aRet;
646 }
647 
650  const Sequence< OUString>& rSetGreetings,
651  bool bConvertFromConfig)
652 {
653  std::vector< OUString>& rGreetings =
657 
658  rGreetings.clear();
659  for(sal_Int32 nGreeting = 0; nGreeting < rSetGreetings.getLength(); nGreeting++)
660  {
661  OUString sGreeting = rSetGreetings[nGreeting];
662  if(bConvertFromConfig)
664  rGreetings.push_back(sGreeting);
665  }
666  SetModified();
667 }
668 
670  SwMailMergeConfigItem::Gender eType) const
671 {
672  sal_Int32 nRet;
673  switch(eType)
674  {
677  default: nRet = m_nCurrentNeutralGreeting; break;
678  }
679  return nRet;
680 }
681 
683  SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
684 {
685  bool bChanged = false;
686  switch(eType)
687  {
689  bChanged = m_nCurrentFemaleGreeting != nIndex;
690  m_nCurrentFemaleGreeting = nIndex;
691  break;
693  bChanged = m_nCurrentMaleGreeting != nIndex;
694  m_nCurrentMaleGreeting = nIndex;
695  break;
696  default:
697  bChanged = m_nCurrentNeutralGreeting != nIndex;
698  m_nCurrentNeutralGreeting = nIndex;
699  }
700  if(bChanged)
701  SetModified();
702 }
703 
706  m_bAddressInserted(false),
707  m_bGreetingInserted(false),
708  m_nGreetingMoves(0),
709  m_pSourceView(nullptr),
710  m_pTargetView(nullptr)
711 {
712 }
713 
715 {
716  if (m_xDBChangedListener.is())
717  {
718  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
719  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
720  m_xDBChangedListener.clear();
721  }
722 }
723 
725 {
726  const SwDBData& rDBData = m_pSourceView->GetWrtShell().GetDBDesc();
727  SetCurrentDBData(rDBData);
728 }
729 
731 {
733 }
734 
736 {
737  if(m_pImpl->IsModified())
738  m_pImpl->Commit();
739 }
740 
741 const std::vector<std::pair<OUString, int>>& SwMailMergeConfigItem::GetDefaultAddressHeaders() const
742 {
743  return m_pImpl->m_AddressHeaderSA;
744 }
745 
747  const Sequence< OUString>& rBlocks)
748 {
749  m_pImpl->SetAddressBlocks(rBlocks);
750 }
751 
753 {
754  return m_pImpl->GetAddressBlocks();
755 }
756 
758 {
759  return m_pImpl->m_bIsAddressBlock && IsOutputToLetter();
760 }
761 
763 {
764  m_pImpl->m_bUserSettingWereOverwritten = false;
765  if(m_pImpl->m_bIsAddressBlock != bSet)
766  {
767  m_pImpl->m_bIsAddressBlock = bSet;
768  m_pImpl->SetModified();
769  }
770 }
771 
773 {
774  return m_pImpl->m_bIsHideEmptyParagraphs;
775 }
776 
778 {
779  if(m_pImpl->m_bIsHideEmptyParagraphs != bSet)
780  {
781  m_pImpl->m_bIsHideEmptyParagraphs = bSet;
782  m_pImpl->SetModified();
783  }
784 }
785 
787 {
788  return m_pImpl->m_bIncludeCountry;
789 }
790 
792 {
793  return m_pImpl->m_sExcludeCountry;
794 }
795 
796 void SwMailMergeConfigItem::SetCountrySettings(bool bSet, const OUString& rCountry)
797 {
798  if(m_pImpl->m_sExcludeCountry != rCountry ||
799  m_pImpl->m_bIncludeCountry != bSet)
800  {
801  m_pImpl->m_bIncludeCountry = bSet;
802  m_pImpl->m_sExcludeCountry = bSet ? rCountry : OUString();
803  m_pImpl->SetModified();
804  }
805 }
806 
808  Reference< XDataSource> const & xSource,
809  const SharedConnection& rConnection,
810  Reference< XColumnsSupplier> const & xColumnsSupplier,
811  const SwDBData& rDBData)
812 {
813  m_pImpl->m_xSource = xSource ;
814  m_pImpl->m_xConnection = rConnection ;
815  m_pImpl->m_xColumnsSupplier = xColumnsSupplier;
816  m_pImpl->m_aDBData = rDBData;
817  m_pImpl->m_xResultSet = nullptr;
818  m_pImpl->m_nResultSetCursorPos = 0;
819  m_pImpl->SetModified();
820 }
821 
823 {
824  return m_pImpl->m_xSource;
825 }
826 
828 {
829  return m_pImpl->m_xConnection;
830 }
831 
832 Reference< XColumnsSupplier> const & SwMailMergeConfigItem::GetColumnsSupplier()
833 {
834  if(!m_pImpl->m_xColumnsSupplier.is() && m_pImpl->m_xConnection.is())
835  {
836  m_pImpl->m_xColumnsSupplier = SwDBManager::GetColumnSupplier(m_pImpl->m_xConnection,
837  m_pImpl->m_aDBData.sCommand,
838  m_pImpl->m_aDBData.nCommandType == CommandType::TABLE ?
840  }
841  return m_pImpl->m_xColumnsSupplier;
842 }
843 
845 {
846  return m_pImpl->m_aDBData;
847 }
848 
850 {
851  if(m_pImpl->m_aDBData != rDBData)
852  {
853  m_pImpl->m_aDBData = rDBData;
854  m_pImpl->m_xConnection.clear();
855  m_pImpl->m_xSource = nullptr;
856  m_pImpl->m_xResultSet = nullptr;
857  m_pImpl->m_xColumnsSupplier = nullptr;
858  m_pImpl->SetModified();
859  }
860 }
861 
862 Reference< XResultSet> const & SwMailMergeConfigItem::GetResultSet() const
863 {
864  if(!m_pImpl->m_xConnection.is() && !m_pImpl->m_aDBData.sDataSource.isEmpty())
865  {
866  m_pImpl->m_xConnection.reset(
867  SwDBManager::GetConnection(m_pImpl->m_aDBData.sDataSource, m_pImpl->m_xSource, m_pSourceView),
869  );
870  }
871  if(!m_pImpl->m_xResultSet.is() && m_pImpl->m_xConnection.is())
872  {
873  try
874  {
876 
877  Reference<XRowSet> xRowSet( xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY );
878  Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
879  xRowProperties->setPropertyValue("DataSourceName", makeAny(m_pImpl->m_aDBData.sDataSource));
880  xRowProperties->setPropertyValue("Command", makeAny(m_pImpl->m_aDBData.sCommand));
881  xRowProperties->setPropertyValue("CommandType", makeAny(m_pImpl->m_aDBData.nCommandType));
882  xRowProperties->setPropertyValue("FetchSize", makeAny(sal_Int32(10)));
883  xRowProperties->setPropertyValue("ActiveConnection", makeAny(m_pImpl->m_xConnection.getTyped()));
884  try
885  {
886  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
887  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
888  }
889  catch (const Exception&)
890  {
891  css::uno::Any ex( cppu::getCaughtException() );
892  SAL_WARN("sw.ui", "exception caught: " << exceptionToString(ex));
893  }
894  xRowSet->execute();
895  m_pImpl->m_xResultSet = xRowSet.get();
896  m_pImpl->m_xResultSet->first();
897  m_pImpl->m_nResultSetCursorPos = 1;
898  }
899  catch (const Exception&)
900  {
901  css::uno::Any ex( cppu::getCaughtException() );
902  SAL_WARN("sw.ui", "exception caught in: SwMailMergeConfigItem::GetResultSet() " << exceptionToString(ex));
903  }
904  }
905  return m_pImpl->m_xResultSet;
906 }
907 
909 {
910  m_pImpl->m_xConnection.clear();
911  if(m_pImpl->m_xResultSet.is())
912  {
913  ::comphelper::disposeComponent( m_pImpl->m_xResultSet );
914  }
915 }
916 
918 {
919  return m_pImpl->m_sFilter;
920 }
921 
922 void SwMailMergeConfigItem::SetFilter(OUString const & rFilter)
923 {
924  if(m_pImpl->m_sFilter != rFilter)
925  {
926  m_pImpl->m_sFilter = rFilter;
927  m_pImpl->SetModified();
928  Reference<XPropertySet> xRowProperties(m_pImpl->m_xResultSet, UNO_QUERY);
929  if(xRowProperties.is())
930  {
931  try
932  {
933  xRowProperties->setPropertyValue("ApplyFilter", makeAny(!m_pImpl->m_sFilter.isEmpty()));
934  xRowProperties->setPropertyValue("Filter", makeAny(m_pImpl->m_sFilter));
935  uno::Reference<XRowSet> xRowSet( m_pImpl->m_xResultSet, UNO_QUERY_THROW );
936  xRowSet->execute();
937  }
938  catch (const Exception&)
939  {
940  css::uno::Any ex( cppu::getCaughtException() );
941  SAL_WARN("sw.ui", "exception caught in SwMailMergeConfigItem::SetFilter(): " << exceptionToString(ex));
942  }
943  }
944  }
945 }
946 
947 sal_Int32 SwMailMergeConfigItem::MoveResultSet(sal_Int32 nTarget)
948 {
949  if(!m_pImpl->m_xResultSet.is())
950  GetResultSet();
951  if(m_pImpl->m_xResultSet.is())
952  {
953  try
954  {
955  //no action if the resultset is already at the right position
956  if(m_pImpl->m_xResultSet->getRow() != nTarget)
957  {
958  if(nTarget > 0)
959  {
960  bool bMoved = m_pImpl->m_xResultSet->absolute(nTarget);
961  if(!bMoved)
962  {
963  if(nTarget > 1)
964  m_pImpl->m_xResultSet->last();
965  else if(nTarget == 1)
966  m_pImpl->m_xResultSet->first();
967  }
968  }
969  else if(nTarget == -1)
970  m_pImpl->m_xResultSet->last();
971  m_pImpl->m_nResultSetCursorPos = m_pImpl->m_xResultSet->getRow();
972  }
973  }
974  catch (const Exception&)
975  {
976  }
977  }
978  return m_pImpl->m_nResultSetCursorPos;
979 }
980 
981 bool SwMailMergeConfigItem::IsResultSetFirstLast(bool& bIsFirst, bool& bIsLast)
982 {
983  bool bRet = false;
984  if(!m_pImpl->m_xResultSet.is())
985  GetResultSet();
986  if(m_pImpl->m_xResultSet.is())
987  {
988  try
989  {
990  bIsFirst = m_pImpl->m_xResultSet->isFirst();
991  bIsLast = m_pImpl->m_xResultSet->isLast();
992  bRet = true;
993  }
994  catch (const Exception&)
995  {
996  }
997  }
998  return bRet;
999 }
1000 
1002 {
1003  return m_pImpl->m_nResultSetCursorPos;
1004 }
1005 
1006 bool SwMailMergeConfigItem::IsRecordExcluded(sal_Int32 nRecord) const
1007  { return m_aExcludedRecords.find(nRecord) != m_aExcludedRecords.end(); }
1008 
1009 void SwMailMergeConfigItem::ExcludeRecord(sal_Int32 nRecord, bool bExclude)
1010 {
1011  if(bExclude)
1012  m_aExcludedRecords.insert(nRecord);
1013  else
1014  m_aExcludedRecords.erase(nRecord);
1015 }
1016 
1017 uno::Sequence<uno::Any> SwMailMergeConfigItem::GetSelection() const
1018 {
1019  if(!m_pImpl->m_xResultSet.is())
1020  GetResultSet();
1021  if(!m_pImpl->m_xResultSet.is())
1022  return {};
1023  m_pImpl->m_xResultSet->last();
1024  sal_Int32 nResultSetSize = m_pImpl->m_xResultSet->getRow()+1;
1025  std::vector<uno::Any> vResult;
1026  vResult.reserve(nResultSetSize);
1027  for(sal_Int32 nIdx=1; nIdx<nResultSetSize;++nIdx)
1028  if(!IsRecordExcluded(nIdx))
1029  vResult.push_back(uno::makeAny<sal_Int32>(nIdx));
1030  return comphelper::containerToSequence(vResult);
1031 }
1032 
1033 
1034 const uno::Sequence< OUString>&
1036 {
1037  return m_pImpl->m_aSavedDocuments;
1038 }
1039 
1041 {
1042  return m_pImpl->m_bIsOutputToLetter || !IsMailAvailable();
1043 }
1044 
1046 {
1047  if(m_pImpl->m_bIsOutputToLetter != bSet)
1048  {
1049  m_pImpl->m_bIsOutputToLetter = bSet;
1050  m_pImpl->SetModified();
1051  }
1052 }
1053 
1055 {
1056  return bInEMail ?
1057  m_pImpl->m_bIsIndividualGreetingLineInMail :
1058  m_pImpl->m_bIsIndividualGreetingLine;
1059 }
1060 
1062  bool bSet, bool bInEMail)
1063 {
1064  if(bInEMail)
1065  {
1066  if(m_pImpl->m_bIsIndividualGreetingLineInMail != bSet)
1067  {
1068  m_pImpl->m_bIsIndividualGreetingLineInMail = bSet;
1069  m_pImpl->SetModified();
1070  }
1071  }
1072  else
1073  {
1074  if(m_pImpl->m_bIsIndividualGreetingLine != bSet)
1075  {
1076  m_pImpl->m_bIsIndividualGreetingLine = bSet;
1077  m_pImpl->SetModified();
1078  }
1079  }
1080 }
1081 
1082 bool SwMailMergeConfigItem::IsGreetingLine(bool bInEMail) const
1083 {
1084  return bInEMail ? m_pImpl->m_bIsGreetingLineInMail : m_pImpl->m_bIsGreetingLine;
1085 }
1086 
1087 void SwMailMergeConfigItem::SetGreetingLine(bool bSet, bool bInEMail)
1088 {
1089  m_pImpl->m_bUserSettingWereOverwritten = false;
1090  if(bInEMail)
1091  {
1092  if(m_pImpl->m_bIsGreetingLineInMail != bSet)
1093  {
1094  m_pImpl->m_bIsGreetingLineInMail = bSet;
1095  m_pImpl->SetModified();
1096  }
1097  }
1098  else
1099  {
1100  if(m_pImpl->m_bIsGreetingLine != bSet)
1101  {
1102  m_pImpl->m_bIsGreetingLine = bSet;
1103  m_pImpl->SetModified();
1104  }
1105  }
1106 }
1107 
1109  Gender eType ) const
1110 {
1111  return m_pImpl->GetGreetings(eType);
1112 }
1113 
1115  Gender eType, const Sequence< OUString>& rSetGreetings)
1116 {
1117  m_pImpl->SetGreetings( eType, rSetGreetings);
1118 }
1119 
1121  SwMailMergeConfigItem::Gender eType) const
1122 {
1123  return m_pImpl->GetCurrentGreeting(eType);
1124 }
1125 
1127 {
1128  m_pImpl->SetCurrentGreeting(eType, nIndex);
1129 }
1130 
1132 {
1133  return m_pImpl->m_sFemaleGenderValue;
1134 }
1135 
1137 {
1138  if( m_pImpl->m_sFemaleGenderValue != rValue )
1139  {
1140  m_pImpl->m_sFemaleGenderValue = rValue;
1141  m_pImpl->SetModified();
1142  }
1143 }
1144 
1146  const SwDBData& rDBData ) const
1147 {
1148  Sequence< OUString> aRet;
1149  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1150  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1151  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1152  {
1153  aRet = aAssignIter->aDBColumnAssignments;
1154  }
1155  return aRet;
1156 }
1157 
1158 // returns the name that is assigned as e-mail column of the current data base
1159 OUString SwMailMergeConfigItem::GetAssignedColumn(sal_uInt32 nColumn) const
1160 {
1161  OUString sRet;
1162  Sequence< OUString> aAssignment = GetColumnAssignment( m_pImpl->m_aDBData );
1163  if(aAssignment.getLength() > sal::static_int_cast< sal_Int32, sal_uInt32>(nColumn) && !aAssignment[nColumn].isEmpty())
1164  sRet = aAssignment[nColumn];
1165  else if(nColumn < m_pImpl->m_AddressHeaderSA.size())
1166  sRet = m_pImpl->m_AddressHeaderSA[nColumn].first;
1167  return sRet;
1168 }
1169 
1171  const Sequence< OUString>& rList)
1172 {
1173  auto aAssignIter = std::find_if(m_pImpl->m_aAddressDataAssignments.begin(), m_pImpl->m_aAddressDataAssignments.end(),
1174  [&rDBData](const DBAddressDataAssignment& rAssignment) { return rAssignment.aDBData == rDBData; });
1175  if (aAssignIter != m_pImpl->m_aAddressDataAssignments.end())
1176  {
1177  if(aAssignIter->aDBColumnAssignments != rList)
1178  {
1179  aAssignIter->aDBColumnAssignments = rList;
1180  aAssignIter->bColumnAssignmentsChanged = true;
1181  }
1182  }
1183  else
1184  {
1185  DBAddressDataAssignment aAssignment;
1186  aAssignment.aDBData = rDBData;
1187  aAssignment.aDBColumnAssignments = rList;
1188  aAssignment.bColumnAssignmentsChanged = true;
1189  m_pImpl->m_aAddressDataAssignments.push_back(aAssignment);
1190  }
1191  m_pImpl->SetModified();
1192 }
1193 
1195 {
1196  bool bResult = true;
1197  Reference< XResultSet> xResultSet = GetResultSet();
1198  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1199  if(!xColsSupp.is())
1200  return false;
1201  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1202 
1203  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1204  Sequence< OUString> aAssignment =
1206  const OUString* pAssignment = aAssignment.getConstArray();
1207  const Sequence< OUString> aBlocks = GetAddressBlocks();
1208 
1209  if(aBlocks.getLength() <= m_pImpl->GetCurrentAddressBlockIndex())
1210  return false;
1211  SwAddressIterator aIter(aBlocks[m_pImpl->GetCurrentAddressBlockIndex()]);
1212  while(aIter.HasMore())
1213  {
1214  SwMergeAddressItem aItem = aIter.Next();
1215  if(aItem.bIsColumn)
1216  {
1217  OUString sConvertedColumn = aItem.sText;
1218  for(sal_uInt32 nColumn = 0;
1219  nColumn < rHeaders.size() && nColumn < sal_uInt32(aAssignment.getLength());
1220  ++nColumn)
1221  {
1222  if (rHeaders[nColumn].first == aItem.sText &&
1223  !pAssignment[nColumn].isEmpty())
1224  {
1225  sConvertedColumn = pAssignment[nColumn];
1226  break;
1227  }
1228  }
1229  //find out if the column exists in the data base
1230  if(!xCols->hasByName(sConvertedColumn))
1231  {
1232  bResult = false;
1233  break;
1234  }
1235  }
1236  }
1237  return bResult;
1238 }
1239 
1241 {
1242  bool bResult = true;
1243 
1244  if(!IsIndividualGreeting(false))
1245  return true;
1246 
1247  Reference< XResultSet> xResultSet = GetResultSet();
1248  uno::Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
1249  if(!xColsSupp.is())
1250  return false;
1251  const std::vector<std::pair<OUString, int>>& rHeaders = GetDefaultAddressHeaders();
1252  uno::Reference<container::XNameAccess> xCols = xColsSupp->getColumns();
1253 
1254  Sequence< OUString> aAssignment =
1256  const OUString* pAssignment = aAssignment.getConstArray();
1257 
1259  sal_Int32 nCurrentFemale = GetCurrentGreeting(SwMailMergeConfigItem::FEMALE);
1261  sal_Int32 nCurrentMale = GetCurrentGreeting(SwMailMergeConfigItem::MALE);
1262  OUString sMale, sFemale;
1263  if(rFemaleEntries.getLength() > nCurrentFemale)
1264  sFemale = rFemaleEntries[nCurrentFemale];
1265  if(rMaleEntries.getLength() > nCurrentMale)
1266  sMale = rMaleEntries[nCurrentMale];
1267 
1268  OUString sAddress( sFemale );
1269  sAddress += sMale;
1270  SwAddressIterator aIter(sAddress);
1271  while(aIter.HasMore())
1272  {
1273  SwMergeAddressItem aItem = aIter.Next();
1274  if(aItem.bIsColumn)
1275  {
1276  OUString sConvertedColumn = aItem.sText;
1277  for(sal_uInt32 nColumn = 0;
1278  nColumn < rHeaders.size() && nColumn < sal_uInt32(aAssignment.getLength());
1279  ++nColumn)
1280  {
1281  if (rHeaders[nColumn].first == aItem.sText &&
1282  !pAssignment[nColumn].isEmpty())
1283  {
1284  sConvertedColumn = pAssignment[nColumn];
1285  break;
1286  }
1287  }
1288  //find out if the column exists in the data base
1289  if(!xCols->hasByName(sConvertedColumn))
1290  {
1291  bResult = false;
1292  break;
1293  }
1294  }
1295  }
1296  return bResult;
1297 }
1298 
1300 {
1301  return m_pImpl->m_sMailDisplayName;
1302 }
1303 
1305 {
1306  if(m_pImpl->m_sMailDisplayName != rName)
1307  {
1308  m_pImpl->m_sMailDisplayName = rName;
1309  m_pImpl->SetModified();
1310  }
1311 }
1312 
1314 {
1315  return m_pImpl->m_sMailAddress;
1316 }
1317 
1318 void SwMailMergeConfigItem::SetMailAddress(const OUString& rAddress)
1319 {
1320  if(m_pImpl->m_sMailAddress != rAddress )
1321  {
1322  m_pImpl->m_sMailAddress = rAddress;
1323  m_pImpl->SetModified();
1324  }
1325 }
1326 
1328 {
1329  return m_pImpl->m_bIsMailReplyTo;
1330 }
1331 
1333 {
1334  if(m_pImpl->m_bIsMailReplyTo != bSet)
1335  {
1336  m_pImpl->m_bIsMailReplyTo = bSet;
1337  m_pImpl->SetModified();
1338  }
1339 }
1340 
1342 {
1343  return m_pImpl->m_sMailReplyTo;
1344 }
1345 
1346 void SwMailMergeConfigItem::SetMailReplyTo(const OUString& rReplyTo)
1347 {
1348  if(m_pImpl->m_sMailReplyTo != rReplyTo)
1349  {
1350  m_pImpl->m_sMailReplyTo = rReplyTo;
1351  m_pImpl->SetModified();
1352  }
1353 }
1354 
1356 {
1357  return m_pImpl->m_sMailServer;
1358 }
1359 
1360 void SwMailMergeConfigItem::SetMailServer(const OUString& rAddress)
1361 {
1362  if(m_pImpl->m_sMailServer != rAddress)
1363  {
1364  m_pImpl->m_sMailServer = rAddress;
1365  m_pImpl->SetModified();
1366  }
1367 }
1368 
1370 {
1371  // provide appropriate TCP port, based on SSL/STARTTLS status, if current port is one of the defaults
1372  switch (m_pImpl->m_nMailPort)
1373  {
1374  case SECURE_PORT:
1375  case DEFAULT_PORT:
1376  return m_pImpl->m_bIsSecureConnection ? SECURE_PORT : DEFAULT_PORT;
1377  break;
1378  default:
1379  return m_pImpl->m_nMailPort;
1380  }
1381 }
1382 
1384 {
1385  if(m_pImpl->m_nMailPort != nSet)
1386  {
1387  m_pImpl->m_nMailPort = nSet;
1388  m_pImpl->SetModified();
1389  }
1390 }
1391 
1393 {
1394  return m_pImpl->m_bIsSecureConnection;
1395 }
1396 
1398 {
1399  if(m_pImpl->m_bIsSecureConnection != bSet)
1400  {
1401  m_pImpl->m_bIsSecureConnection = bSet;
1402  m_pImpl->SetModified();
1403  }
1404 }
1405 
1407 {
1408  return m_pImpl->m_bIsAuthentication;
1409 }
1410 
1412 {
1413  if(m_pImpl->m_bIsAuthentication != bSet)
1414  {
1415  m_pImpl->m_bIsAuthentication = bSet;
1416  m_pImpl->SetModified();
1417  }
1418 }
1419 
1421 {
1422  return m_pImpl->m_sMailUserName;
1423 }
1424 
1425 void SwMailMergeConfigItem::SetMailUserName(const OUString& rName)
1426 {
1427  if(m_pImpl->m_sMailUserName != rName)
1428  {
1429  m_pImpl->m_sMailUserName = rName;
1430  m_pImpl->SetModified();
1431  }
1432 }
1433 
1435 {
1436  return m_pImpl->m_sMailPassword;
1437 }
1438 
1439 void SwMailMergeConfigItem::SetMailPassword(const OUString& rPassword)
1440 {
1441  if(m_pImpl->m_sMailPassword != rPassword)
1442  {
1443  m_pImpl->m_sMailPassword = rPassword;
1444  m_pImpl->SetModified();
1445  }
1446 }
1447 
1449 {
1450  return m_pImpl->m_bIsSMPTAfterPOP;
1451 }
1452 
1454 {
1455  if( m_pImpl->m_bIsSMPTAfterPOP != bSet)
1456  {
1457  m_pImpl->m_bIsSMPTAfterPOP = bSet;
1458  m_pImpl->SetModified();
1459  }
1460 }
1461 
1463 {
1464  return m_pImpl->m_sInServerName;
1465 }
1466 
1467 void SwMailMergeConfigItem::SetInServerName(const OUString& rServer)
1468 {
1469  if(m_pImpl->m_sInServerName != rServer)
1470  {
1471  m_pImpl->m_sInServerName = rServer;
1472  m_pImpl->SetModified();
1473  }
1474 }
1475 
1477 {
1478  // provide appropriate TCP port as user toggles between POP/IMAP if current port is one of the defaults
1479  switch (m_pImpl->m_nInServerPort)
1480  {
1481  case POP_SECURE_PORT:
1482  case POP_PORT:
1483  case IMAP_SECURE_PORT:
1484  case IMAP_PORT:
1485  if ( m_pImpl->m_bInServerPOP )
1486  return m_pImpl->m_bIsSecureConnection ? POP_SECURE_PORT : POP_PORT;
1487  else
1488  return m_pImpl->m_bIsSecureConnection ? IMAP_SECURE_PORT : IMAP_PORT;
1489  break;
1490  default:
1491  return m_pImpl->m_nInServerPort;
1492  }
1493 }
1494 
1496 {
1497  if( m_pImpl->m_nInServerPort != nSet)
1498  {
1499  m_pImpl->m_nInServerPort = nSet;
1500  m_pImpl->SetModified();
1501  }
1502 }
1503 
1505 {
1506  return m_pImpl->m_bInServerPOP;
1507 }
1508 
1510 {
1511  if( m_pImpl->m_bInServerPOP != bSet)
1512  {
1513  m_pImpl->m_bInServerPOP = bSet;
1514  m_pImpl->SetModified();
1515  }
1516 }
1517 
1519 {
1520  return m_pImpl->m_sInServerUserName;
1521 }
1522 
1524 {
1525  if( m_pImpl->m_sInServerUserName != rName)
1526  {
1527  m_pImpl->m_sInServerUserName = rName;
1528  m_pImpl->SetModified();
1529  }
1530 }
1531 
1533 {
1534  return m_pImpl->m_sInServerPassword;
1535 }
1536 
1537 void SwMailMergeConfigItem::SetInServerPassword(const OUString& rPassword)
1538 {
1539  if(m_pImpl->m_sInServerPassword != rPassword)
1540  {
1541  m_pImpl->m_sInServerPassword = rPassword;
1542  m_pImpl->SetModified();
1543  }
1544 }
1545 
1547 {
1548  m_bGreetingInserted = false;
1549  m_bAddressInserted = false;
1550 }
1551 
1553 {
1554  return m_pImpl->m_bIsEMailSupported;
1555 }
1556 
1558 {
1559  m_pImpl->m_aMergeInfos.push_back(rInfo);
1560 }
1561 
1563 {
1564  assert(nDocument < m_pImpl->m_aMergeInfos.size());
1565  return m_pImpl->m_aMergeInfos[nDocument];
1566 }
1567 
1568 
1570 {
1571  if(m_pTargetView)
1572  return m_pImpl->m_aMergeInfos.size();
1573  else
1574  {
1575  sal_Int32 nRestore = GetResultSetPosition();
1576  MoveResultSet(-1);
1577  sal_Int32 nRet = GetResultSetPosition();
1578  MoveResultSet( nRestore );
1579  nRet -= m_aExcludedRecords.size();
1580  return nRet >= 0 ? nRet : 0;
1581  }
1582 }
1583 
1585 {
1586  SfxViewShell* pViewShell = SfxViewShell::GetFirst( false, checkSfxViewShell<SwView> );
1587  while(pViewShell)
1588  {
1589  if(pViewShell == pView)
1590  return pView;
1591 
1592  pViewShell = SfxViewShell::GetNext( *pViewShell, false, checkSfxViewShell<SwView> );
1593  }
1594  return nullptr;
1595 }
1596 
1598 {
1599  //make sure that the pointer is really valid - the document may have been closed manually
1600  if(m_pTargetView)
1601  {
1603  }
1604  return m_pTargetView;
1605 }
1606 
1608 {
1609  m_pTargetView = pView;
1610  //reset the document merge counter
1611  if(!m_pTargetView)
1612  {
1613  m_pImpl->m_aMergeInfos.clear();
1614  }
1615 }
1616 
1618 {
1620  return m_pSourceView;
1621 }
1622 
1623 //This implements XSelectionChangeListener and XDispatch because the
1624 //broadcaster uses this combo to determine if to send the database-changed
1625 //update. Its probably that listening to statusChanged at some other level is
1626 //equivalent to this. See the other call to SwXDispatch::GetDBChangeURL for
1627 //the broadcaster of the event.
1628 class DBChangeListener : public cppu::WeakImplHelper<css::view::XSelectionChangeListener, css::frame::XDispatch>
1629 {
1631 public:
1633  : m_rParent(rParent)
1634  {
1635  }
1636 
1637  virtual void SAL_CALL selectionChanged(const EventObject& /*rEvent*/) override
1638  {
1639  }
1640 
1641  virtual void SAL_CALL disposing(const EventObject&) override
1642  {
1643  m_rParent.stopDBChangeListening();
1644  }
1645 
1646  virtual void SAL_CALL dispatch(const css::util::URL& rURL, const css::uno::Sequence< css::beans::PropertyValue >& /*rArgs*/) override
1647  {
1648  if (rURL.Complete.equalsAscii(SwXDispatch::GetDBChangeURL()))
1649  m_rParent.updateCurrentDBDataFromDocument();
1650  }
1651 
1652  virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1653  {
1654  }
1655 
1656  virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1657  {
1658  }
1659 };
1660 
1662 {
1663  if (m_xDBChangedListener.is())
1664  {
1665  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1666  xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
1667  m_xDBChangedListener.clear();
1668  }
1669 
1670  m_pSourceView = pView;
1671 
1672  if (!m_pSourceView)
1673  return;
1674 
1675  std::vector<OUString> aDBNameList;
1676  std::vector<OUString> aAllDBNames;
1677  m_pSourceView->GetWrtShell().GetAllUsedDB( aDBNameList, &aAllDBNames );
1678  if(!aDBNameList.empty())
1679  {
1680  // if fields are available there is usually no need of an addressblock and greeting
1681  if(!m_pImpl->m_bUserSettingWereOverwritten)
1682  {
1683  if( m_pImpl->m_bIsAddressBlock
1684  || m_pImpl->m_bIsGreetingLineInMail
1685  || m_pImpl->m_bIsGreetingLine )
1686  {
1687  //store user settings
1688  m_pImpl->m_bUserSettingWereOverwritten = true;
1689  m_pImpl->m_bIsAddressBlock_LastUserSetting = m_pImpl->m_bIsAddressBlock;
1690  m_pImpl->m_bIsGreetingLineInMail_LastUserSetting = m_pImpl->m_bIsGreetingLineInMail;
1691  m_pImpl->m_bIsGreetingLine_LastUserSetting = m_pImpl->m_bIsGreetingLine;
1692 
1693  //set all to false
1694  m_pImpl->m_bIsAddressBlock = false;
1695  m_pImpl->m_bIsGreetingLineInMail = false;
1696  m_pImpl->m_bIsGreetingLine = false;
1697 
1698  m_pImpl->SetModified();
1699  }
1700  }
1701  }
1702  else if( m_pImpl->m_bUserSettingWereOverwritten )
1703  {
1704  //restore last user settings:
1705  m_pImpl->m_bIsAddressBlock = m_pImpl->m_bIsAddressBlock_LastUserSetting;
1706  m_pImpl->m_bIsGreetingLineInMail = m_pImpl->m_bIsGreetingLineInMail_LastUserSetting;
1707  m_pImpl->m_bIsGreetingLine = m_pImpl->m_bIsGreetingLine_LastUserSetting;
1708 
1709  m_pImpl->m_bUserSettingWereOverwritten = false;
1710  }
1711 
1712  if (!m_xDBChangedListener.is())
1713  {
1714  m_xDBChangedListener.set(new DBChangeListener(*this));
1715  }
1716 
1717  uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1718  xSupplier->addSelectionChangeListener(m_xDBChangedListener);
1719 }
1720 
1722 {
1723  m_pImpl->SetCurrentAddressBlockIndex( nSet );
1724 }
1725 
1727 {
1728  return m_pImpl->GetCurrentAddressBlockIndex();
1729 }
1730 
1731 /* 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:2921
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:1973
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)
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:1950
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)