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