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>
23#include <vector>
24#include <swtypes.hxx>
25#include <com/sun/star/uno/Any.hxx>
26#include <com/sun/star/beans/PropertyValue.hpp>
27#include <com/sun/star/frame/XDispatch.hpp>
28#include <com/sun/star/sdbc/XDataSource.hpp>
29#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
30#include <com/sun/star/lang/XMultiServiceFactory.hpp>
31#include <com/sun/star/beans/XPropertySet.hpp>
32#include <com/sun/star/sdbc/XRowSet.hpp>
33#include <com/sun/star/view/XSelectionSupplier.hpp>
35#include <comphelper/types.hxx>
36#include <com/sun/star/sdb/CommandType.hpp>
38#include <rtl/ustrbuf.hxx>
39#include <sal/log.hxx>
42#include <mailmergehelper.hxx>
43#include <swunohelper.hxx>
44#include <dbmgr.hxx>
45#include <view.hxx>
46#include <unodispatch.hxx>
47#include <wrtsh.hxx>
48#include <dbui.hrc>
49
50using namespace utl;
51using namespace ::com::sun::star;
52using namespace ::com::sun::star::uno;
53using namespace ::com::sun::star::lang;
54using namespace ::com::sun::star::beans;
55using namespace ::com::sun::star::sdb;
56using namespace ::com::sun::star::sdbc;
57using namespace ::com::sun::star::sdbcx;
58
59constexpr OUStringLiteral cAddressDataAssignments = u"AddressDataAssignments";
60const char cDBColumnAssignments[] = "DBColumnAssignments";
61const char cDataSourceName[] = "DataSource/DataSourceName";
62const char cDataTableName[] = "DataSource/DataTableName" ;
63const 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
72namespace {
73
74struct DBAddressDataAssignment
75{
76 SwDBData aDBData;
77 Sequence< OUString> aDBColumnAssignments;
78 //if loaded the name of the node has to be saved
79 OUString sConfigNodeName;
80 //all created or changed assignments need to be stored
81 bool bColumnAssignmentsChanged;
82
83 DBAddressDataAssignment() :
84 bColumnAssignmentsChanged(false)
85 {}
86};
87
88}
89
91{
93 Reference< XDataSource> m_xSource;
95 Reference< XColumnsSupplier> m_xColumnsSupplier;
96 Reference< XResultSet> m_xResultSet;
98 OUString m_sFilter;
100
101 std::vector<DBAddressDataAssignment> m_aAddressDataAssignments;
102 std::vector< OUString> m_aAddressBlocks;
106
110
113 std::vector< OUString> m_aFemaleGreetingLines;
115 std::vector< OUString> m_aMaleGreetingLines;
117 std::vector< OUString> m_aNeutralGreetingLines;
120 uno::Sequence< OUString> m_aSavedDocuments;
121
124
125 //mail settings
132
139
140 sal_Int16 m_nMailPort;
144
146
147 std::vector<std::pair<OUString, int>> m_AddressHeaderSA;
148
149 //these addresses are not stored in the configuration
150 std::vector< SwDocMergeInfo > m_aMergeInfos;
151
152 //we do overwrite the usersettings in a special case
153 //then we do remind the usersettings here
158
159 static const Sequence< OUString>& GetPropertyNames();
160
161 virtual void ImplCommit() override;
162
163public:
165
166 virtual void Notify( const css::uno::Sequence< OUString >& aPropertyNames ) override;
167 Sequence< OUString> GetAddressBlocks(bool bConvertToConfig = false) const;
168 void SetAddressBlocks(
169 const Sequence< OUString>& rBlocks,
170 bool bConvertFromConfig = false);
171 uno::Sequence< OUString>
173 bool bConvertToConfig = false) const;
175 const uno::Sequence< OUString>& rBlocks,
176 bool bConvertFromConfig = false);
177
178 void SetCurrentAddressBlockIndex( sal_Int32 nSet );
180 { return m_nCurrentAddressBlock; }
182 void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex);
183
184};
185
187 ConfigItem("Office.Writer/MailMergeWizard", ConfigItemMode::NONE),
188 m_nResultSetCursorPos(-1),
189 m_nCurrentAddressBlock(0),
190 m_bIsAddressBlock(true),
191 m_bIsHideEmptyParagraphs(false),
192 m_bIsOutputToLetter(true),
193 m_bIncludeCountry(false),
194 m_bIsGreetingLine(true),
195 m_bIsIndividualGreetingLine(false),
196 m_nCurrentFemaleGreeting(0),
197 m_nCurrentMaleGreeting(0),
198 m_nCurrentNeutralGreeting(0),
199 m_bIsGreetingLineInMail(false),
200 m_bIsIndividualGreetingLineInMail(false),
201 m_bIsSMPTAfterPOP(false),
202 m_nInServerPort( POP_SECURE_PORT ),
203 m_bInServerPOP( true ),
204 m_nMailPort(SECURE_PORT),
205 m_bIsMailReplyTo(false),
206 m_bIsSecureConnection(true),
207 m_bIsAuthentication(false),
208
209 m_bIsEMailSupported(false),
210 m_bUserSettingWereOverwritten(false),
211 m_bIsAddressBlock_LastUserSetting(false),
212 m_bIsGreetingLineInMail_LastUserSetting(false),
213 m_bIsGreetingLine_LastUserSetting(false)
214{
215 for (auto const& [aName, aID] : SA_ADDRESS_HEADER)
216 {
217 m_AddressHeaderSA.emplace_back(SwResId(aName), aID);
218 }
219
220 const Sequence<OUString>& rNames = GetPropertyNames();
221 Sequence<Any> aValues = GetProperties(rNames);
222 const Any* pValues = aValues.getConstArray();
223 assert(aValues.getLength() == rNames.getLength());
224 if(aValues.getLength() == rNames.getLength())
225 {
226 for(int nProp = 0; nProp < rNames.getLength(); nProp++)
227 {
228 switch(nProp)
229 {
230 case 0: pValues[nProp] >>= m_bIsOutputToLetter; break;
231 case 1: pValues[nProp] >>= m_bIncludeCountry; break;
232 case 2: pValues[nProp] >>= m_sExcludeCountry; break;
233 case 3:
234 {
235 Sequence< OUString> aBlocks;
236 pValues[nProp] >>= aBlocks;
237 SetAddressBlocks(aBlocks, true);
238 }
239 break;
240 case 4: pValues[nProp] >>= m_bIsAddressBlock; break;
241 case 5: pValues[nProp] >>= m_bIsGreetingLine; break;
242 case 6: pValues[nProp] >>= m_bIsIndividualGreetingLine; break;
243 case 7 :
244 case 8 :
245 case 9 :
246 {
247 Sequence< OUString> aGreetings;
248 pValues[nProp] >>= aGreetings;
250 SwMailMergeConfigItem::FEMALE + nProp - 7), aGreetings, true);
251 }
252 break;
253
254 case 10: pValues[nProp] >>= m_nCurrentFemaleGreeting; break;
255 case 11: pValues[nProp] >>= m_nCurrentMaleGreeting; break;
256 case 12: pValues[nProp] >>= m_nCurrentNeutralGreeting; break;
257 case 13: pValues[nProp] >>= m_sFemaleGenderValue; break;
258 case 14: pValues[nProp] >>= m_sMailDisplayName; break;
259 case 15: pValues[nProp] >>= m_sMailAddress; break;
260 case 16: pValues[nProp] >>= m_bIsMailReplyTo; break;
261 case 17: pValues[nProp] >>= m_sMailReplyTo; break;
262 case 18: pValues[nProp] >>= m_sMailServer; break;
263 case 19: pValues[nProp] >>= m_nMailPort; break;
264 case 20: pValues[nProp] >>= m_bIsSecureConnection; break;
265 case 21: pValues[nProp] >>= m_bIsAuthentication; break;
266 case 22: pValues[nProp] >>= m_sMailUserName; break;
267 case 23: pValues[nProp] >>= m_sMailPassword; break;
268 case 24 :pValues[nProp] >>= m_aDBData.sDataSource; break;
269 case 25 :pValues[nProp] >>= m_aDBData.sCommand; break;
270 case 26 :
271 {
272 short nTemp = 0;
273 if(pValues[nProp] >>= nTemp)
274 m_aDBData.nCommandType = nTemp;
275 }
276 break;
277 case 27: pValues[nProp] >>= m_sFilter; break;
278 case 28: pValues[nProp] >>= m_aSavedDocuments; break;
279 case 29:
280 pValues[nProp] >>= m_bIsEMailSupported;
281 break;
282 case 30: pValues[nProp] >>= m_bIsGreetingLineInMail; break;
283 case 31: pValues[nProp] >>= m_bIsIndividualGreetingLineInMail; break;
284 case 32: pValues[nProp] >>= m_bIsSMPTAfterPOP; break;
285 case 33: pValues[nProp] >>= m_sInServerName; break;
286 case 34: pValues[nProp] >>= m_nInServerPort; break;
287 case 35: pValues[nProp] >>= m_bInServerPOP; break;
288 case 36: pValues[nProp] >>= m_sInServerUserName; break;
289 case 37: pValues[nProp] >>= m_sInServerPassword; break;
290 case 38: pValues[nProp] >>= m_bIsHideEmptyParagraphs; break;
291 case 39: pValues[nProp] >>= m_nCurrentAddressBlock; break;
292 }
293 }
295 }
296 //read the list of data base assignments
297 Sequence<OUString> aAssignments = GetNodeNames(cAddressDataAssignments);
298 if(aAssignments.hasElements())
299 {
300 //create a list of property names to load the URLs of all data bases
301 const OUString* pAssignments = aAssignments.getConstArray();
302 Sequence< OUString > aAssignProperties(4 * aAssignments.getLength());
303 OUString* pAssignProperties = aAssignProperties.getArray();
304 sal_Int32 nAssign;
305 for(nAssign = 0; nAssign < aAssignProperties.getLength(); nAssign += 4)
306 {
307 OUString sAssignPath = OUString::Concat(cAddressDataAssignments) +
308 "/" +
309 pAssignments[nAssign / 4] +
310 "/";
311 pAssignProperties[nAssign] = sAssignPath;
312 pAssignProperties[nAssign] += cDataSourceName;
313 pAssignProperties[nAssign + 1] = sAssignPath;
314 pAssignProperties[nAssign + 1] += cDataTableName;
315 pAssignProperties[nAssign + 2] = sAssignPath;
316 pAssignProperties[nAssign + 2] += cDataCommandType;
317 pAssignProperties[nAssign + 3] = sAssignPath;
318 pAssignProperties[nAssign + 3] += cDBColumnAssignments;
319 }
320 Sequence<Any> aAssignValues = GetProperties(aAssignProperties);
321 const Any* pAssignValues = aAssignValues.getConstArray();
322 for(nAssign = 0; nAssign < aAssignValues.getLength(); nAssign += 4 )
323 {
324 DBAddressDataAssignment aAssignment;
325 pAssignValues[nAssign] >>= aAssignment.aDBData.sDataSource;
326 pAssignValues[nAssign + 1] >>= aAssignment.aDBData.sCommand;
327 pAssignValues[nAssign + 2] >>= aAssignment.aDBData.nCommandType;
328 pAssignValues[nAssign + 3] >>= aAssignment.aDBColumnAssignments;
329 aAssignment.sConfigNodeName = pAssignments[nAssign / 4];
330 m_aAddressDataAssignments.push_back(aAssignment);
331 }
332 }
333 //check if the saved documents still exist
334 if(!m_aSavedDocuments.hasElements())
335 return;
336
337 uno::Sequence< OUString > aTempDocuments(m_aSavedDocuments.getLength());
338 auto begin = aTempDocuments.getArray();
339 OUString* pTempDocuments = std::copy_if(std::cbegin(m_aSavedDocuments), std::cend(m_aSavedDocuments), begin,
340 [](const OUString& rDoc) { return SWUnoHelper::UCB_IsFile( rDoc ); });
341 sal_Int32 nIndex = static_cast<sal_Int32>(std::distance(begin, pTempDocuments));
342 if(nIndex < m_aSavedDocuments.getLength())
343 {
344 m_aSavedDocuments.swap(aTempDocuments);
345 m_aSavedDocuments.realloc(nIndex);
346 }
347}
348
350{
351 if(m_aAddressBlocks.size() >= sal::static_int_cast<sal_uInt32, sal_Int32>(nSet))
352 {
354 SetModified();
355 }
356}
357
358static OUString lcl_CreateNodeName(Sequence<OUString>& rAssignments )
359{
360 sal_Int32 nStart = rAssignments.getLength();
361 OUString sNewName;
362 //search if the name exists
363 while(true)
364 {
365 sNewName = "_" + OUString::number(nStart++);
366 if(comphelper::findValue(rAssignments, sNewName) == -1)
367 break;
368 }
369 // add the new name to the array of existing names
370 rAssignments.realloc(rAssignments.getLength() + 1);
371 rAssignments.getArray()[rAssignments.getLength() - 1] = sNewName;
372 return sNewName;
373}
374
375static void lcl_ConvertToNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders )
376{
377 //convert the strings used for UI to numbers used for the configuration
378 OUString sBlock(rBlock.replaceAll("\n", "\\n"));
379 for (size_t i = 0; i < rHeaders.size(); ++i)
380 {
381 OUString sHeader = "<" + rHeaders[i].first + ">";
382 OUString sReplace = "<" + OUStringChar(sal_Unicode('0' + i)) + ">";
383 sBlock = sBlock.replaceAll(sHeader, sReplace);
384 }
385 rBlock = sBlock;
386}
387
388static void lcl_ConvertFromNumbers(OUString& rBlock, const std::vector<std::pair<OUString, int>>& rHeaders)
389{
390 //convert the numbers used for the configuration to strings used for UI to numbers
391 //doesn't use ReplaceAll to prevent expansion of numbers inside of the headers
392 SwAddressIterator aGreetingIter(rBlock.replaceAll("\\n", "\n"));
393 OUStringBuffer sBlock;
394 while(aGreetingIter.HasMore())
395 {
396 SwMergeAddressItem aNext = aGreetingIter.Next();
397 if(aNext.bIsColumn)
398 {
399 //the text should be 1 characters long
400 sal_Unicode cChar = aNext.sText[0];
401 if(cChar >= '0' && cChar <= 'c')
402 {
403 sBlock.append("<");
404 sal_uInt16 nHeader = cChar - '0';
405 if(nHeader < rHeaders.size())
406 sBlock.append(rHeaders[nHeader].first);
407 sBlock.append(">");
408 }
409 else
410 {
411 SAL_WARN("sw.ui", "parse error in address block or greeting line");
412 }
413 }
414 else
415 sBlock.append(aNext.sText);
416 }
417 rBlock = sBlock.makeStringAndClear();
418}
419
421{
422 static Sequence<OUString> aNames {
423 "OutputToLetter", // 0
424 "IncludeCountry", // 1
425 "ExcludeCountry", // 2
426 "AddressBlockSettings", // 3
427 "IsAddressBlock", // 4
428 "IsGreetingLine", // 5
429 "IsIndividualGreetingLine", // 6
430 "FemaleGreetingLines", // 7
431 "MaleGreetingLines", // 8
432 "NeutralGreetingLines", // 9
433 "CurrentFemaleGreeting", // 10
434 "CurrentMaleGreeting", // 11
435 "CurrentNeutralGreeting", // 12
436 "FemaleGenderValue", // 13
437 "MailDisplayName", // 14
438 "MailAddress", // 15
439 "IsMailReplyTo", // 16
440 "MailReplyTo", // 17
441 "MailServer", // 18
442 "MailPort", // 19
443 "IsSecureConnection", // 20
444 "IsAuthentication", // 21
445 "MailUserName", // 22
446 "MailPassword", // 23
447 "DataSource/DataSourceName", // 24
448 "DataSource/DataTableName", // 25
449 "DataSource/DataCommandType",// 26
450 "Filter", // 27
451 "SavedDocuments", // 28
452 "EMailSupported", // 29
453 "IsEMailGreetingLine", //30
454 "IsEMailIndividualGreetingLine", //31
455 "IsSMPTAfterPOP", //32
456 "InServerName", //33
457 "InServerPort", //34
458 "InServerIsPOP", //35
459 "InServerUserName", //36
460 "InServerPassword", //37
461 "IsHideEmptyParagraphs", //38
462 "CurrentAddressBlock" //39
463 };
464 return aNames;
465}
466
467void SwMailMergeConfigItem_Impl::Notify( const css::uno::Sequence< OUString >& ) {}
468
470{
471 Sequence<OUString> aNames = GetPropertyNames();
472 Sequence<Any> aValues(aNames.getLength());
473 Any* pValues = aValues.getArray();
474
475 for(int nProp = 0; nProp < aNames.getLength(); nProp++)
476 {
477 switch(nProp)
478 {
479 case 0: pValues[nProp] <<= m_bIsOutputToLetter; break;
480 case 1: pValues[nProp] <<= m_bIncludeCountry; break;
481 case 2: pValues[nProp] <<= m_sExcludeCountry; break;
482 case 3: pValues[nProp] <<= GetAddressBlocks(true); break;
483 case 4:
484 {
487 else
488 pValues[nProp] <<= m_bIsAddressBlock;
489 break;
490 }
491 case 5:
492 {
495 else
496 pValues[nProp] <<= m_bIsGreetingLine;
497 break;
498 }
499 case 6: pValues[nProp] <<= m_bIsIndividualGreetingLine; break;
500 case 7:
501 case 8:
502 case 9:
503 pValues[nProp] <<= GetGreetings(
505 SwMailMergeConfigItem::FEMALE + nProp - 7), true);
506 break;
507 case 10: pValues[nProp] <<= m_nCurrentFemaleGreeting; break;
508 case 11: pValues[nProp] <<= m_nCurrentMaleGreeting; break;
509 case 12: pValues[nProp] <<= m_nCurrentNeutralGreeting; break;
510 case 13: pValues[nProp] <<= m_sFemaleGenderValue; break;
511 case 14: pValues[nProp] <<= m_sMailDisplayName; break;
512 case 15: pValues[nProp] <<= m_sMailAddress; break;
513 case 16: pValues[nProp] <<= m_bIsMailReplyTo; break;
514 case 17: pValues[nProp] <<= m_sMailReplyTo; break;
515 case 18: pValues[nProp] <<= m_sMailServer; break;
516 case 19: pValues[nProp] <<= m_nMailPort; break;
517 case 20: pValues[nProp] <<= m_bIsSecureConnection; break;
518 case 21: pValues[nProp] <<= m_bIsAuthentication; break;
519 case 22: pValues[nProp] <<= m_sMailUserName; break;
520 case 23: pValues[nProp] <<= m_sMailPassword; break;
521 case 24 :pValues[nProp] <<= m_aDBData.sDataSource; break;
522 case 25 :pValues[nProp] <<= m_aDBData.sCommand; break;
523 case 26 :pValues[nProp] <<= m_aDBData.nCommandType; break;
524 case 27 :pValues[nProp] <<= m_sFilter; break;
525 case 28 :pValues[nProp] <<= m_aSavedDocuments; break;
526 case 29: pValues[nProp] <<= m_bIsEMailSupported; break;
527 case 30:
528 {
531 else
533 break;
534 }
535 case 31: pValues[nProp] <<= m_bIsIndividualGreetingLineInMail; break;
536 case 32: pValues[nProp] <<= m_bIsSMPTAfterPOP; break;
537 case 33: pValues[nProp] <<= m_sInServerName; break;
538 case 34: pValues[nProp] <<= m_nInServerPort; break;
539 case 35: pValues[nProp] <<= m_bInServerPOP; break;
540 case 36: pValues[nProp] <<= m_sInServerUserName; break;
541 case 37: pValues[nProp] <<= m_sInServerPassword; break;
542 case 38: pValues[nProp] <<= m_bIsHideEmptyParagraphs; break;
543 case 39: pValues[nProp] <<= m_nCurrentAddressBlock; break;
544 }
545 }
546 PutProperties(aNames, aValues);
547 //store the changed / new assignments
548
549 //load the existing node names to find new names
550 Sequence<OUString> aAssignments = GetNodeNames(cAddressDataAssignments);
551
552 for(const auto& rAssignment : m_aAddressDataAssignments)
553 {
554 if(rAssignment.bColumnAssignmentsChanged)
555 {
556 //create a new node name
557 OUString sNewNode = !rAssignment.sConfigNodeName.isEmpty() ?
558 rAssignment.sConfigNodeName :
559 lcl_CreateNodeName(aAssignments);
560 OUString sSlash = "/";
561 OUString sNodePath = cAddressDataAssignments + sSlash + sNewNode + sSlash;
562 //only one new entry is written
563 Sequence< PropertyValue > aNewValues
564 {
565 comphelper::makePropertyValue(sNodePath + cDataSourceName, rAssignment.aDBData.sDataSource),
566 comphelper::makePropertyValue(sNodePath + cDataTableName, rAssignment.aDBData.sCommand),
567 comphelper::makePropertyValue(sNodePath + cDataCommandType, rAssignment.aDBData.nCommandType),
568 comphelper::makePropertyValue(sNodePath + cDBColumnAssignments, rAssignment.aDBColumnAssignments)
569 };
571 }
572 }
573
575}
576
578 bool bConvertToConfig) const
579{
580 Sequence< OUString> aRet(m_aAddressBlocks.size());
581 std::transform(m_aAddressBlocks.begin(), m_aAddressBlocks.end(), aRet.getArray(),
582 [this, bConvertToConfig](const OUString& rBlock) -> OUString {
583 OUString sBlock = rBlock;
584 if(bConvertToConfig)
585 lcl_ConvertToNumbers(sBlock, m_AddressHeaderSA);
586 return sBlock;
587 });
588 return aRet;
589}
590
592 const Sequence< OUString>& rBlocks,
593 bool bConvertFromConfig)
594{
595 m_aAddressBlocks.clear();
596 std::transform(rBlocks.begin(), rBlocks.end(), std::back_inserter(m_aAddressBlocks),
597 [this, bConvertFromConfig](const OUString& rBlock) -> OUString {
598 OUString sBlock = rBlock;
599 if(bConvertFromConfig)
600 lcl_ConvertFromNumbers(sBlock, m_AddressHeaderSA);
601 return sBlock;
602 });
604 SetModified();
605}
606
608 SwMailMergeConfigItem::Gender eType, bool bConvertToConfig) const
609{
610 const std::vector< OUString>& rGreetings =
614 Sequence< OUString> aRet(rGreetings.size());
615 std::transform(rGreetings.begin(), rGreetings.end(), aRet.getArray(),
616 [this, bConvertToConfig](const OUString& rGreeting) -> OUString {
617 OUString sGreeting = rGreeting;
618 if(bConvertToConfig)
619 lcl_ConvertToNumbers(sGreeting, m_AddressHeaderSA);
620 return sGreeting;
621 });
622 return aRet;
623}
624
627 const Sequence< OUString>& rSetGreetings,
628 bool bConvertFromConfig)
629{
630 std::vector< OUString>& rGreetings =
634
635 rGreetings.clear();
636 std::transform(rSetGreetings.begin(), rSetGreetings.end(), std::back_inserter(rGreetings),
637 [this, bConvertFromConfig](const OUString& rGreeting) -> OUString {
638 OUString sGreeting = rGreeting;
639 if(bConvertFromConfig)
640 lcl_ConvertFromNumbers(sGreeting, m_AddressHeaderSA);
641 return sGreeting;
642 });
643 SetModified();
644}
645
648{
649 sal_Int32 nRet;
650 switch(eType)
651 {
654 default: nRet = m_nCurrentNeutralGreeting; break;
655 }
656 return nRet;
657}
658
660 SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
661{
662 bool bChanged = false;
663 switch(eType)
664 {
666 bChanged = m_nCurrentFemaleGreeting != nIndex;
668 break;
670 bChanged = m_nCurrentMaleGreeting != nIndex;
672 break;
673 default:
674 bChanged = m_nCurrentNeutralGreeting != nIndex;
676 }
677 if(bChanged)
678 SetModified();
679}
680
683 m_bAddressInserted(false),
684 m_bGreetingInserted(false),
686 m_nBegin(0),
687 m_nEnd(0),
688 m_pSourceView(nullptr),
689 m_pTargetView(nullptr)
690{
691}
692
694{
695 if (m_xDBChangedListener.is())
696 {
697 uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
698 xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
699 m_xDBChangedListener.clear();
700 }
701}
702
704{
705 const SwDBData& rDBData = m_pSourceView->GetWrtShell().GetDBData();
706 SetCurrentDBData(rDBData);
707}
708
710{
712}
713
715{
716 if(m_pImpl->IsModified())
717 m_pImpl->Commit();
718}
719
720const std::vector<std::pair<OUString, int>>& SwMailMergeConfigItem::GetDefaultAddressHeaders() const
721{
722 return m_pImpl->m_AddressHeaderSA;
723}
724
726 const Sequence< OUString>& rBlocks)
727{
728 m_pImpl->SetAddressBlocks(rBlocks);
729}
730
732{
733 return m_pImpl->GetAddressBlocks();
734}
735
737{
738 return m_pImpl->m_bIsAddressBlock && IsOutputToLetter();
739}
740
742{
743 m_pImpl->m_bUserSettingWereOverwritten = false;
744 if(m_pImpl->m_bIsAddressBlock != bSet)
745 {
746 m_pImpl->m_bIsAddressBlock = bSet;
747 m_pImpl->SetModified();
748 }
749}
750
752{
753 return m_pImpl->m_bIsHideEmptyParagraphs;
754}
755
757{
758 if(m_pImpl->m_bIsHideEmptyParagraphs != bSet)
759 {
760 m_pImpl->m_bIsHideEmptyParagraphs = bSet;
761 m_pImpl->SetModified();
762 }
763}
764
766{
767 return m_pImpl->m_bIncludeCountry;
768}
769
771{
772 return m_pImpl->m_sExcludeCountry;
773}
774
775void SwMailMergeConfigItem::SetCountrySettings(bool bSet, const OUString& rCountry)
776{
777 if(m_pImpl->m_sExcludeCountry != rCountry ||
778 m_pImpl->m_bIncludeCountry != bSet)
779 {
780 m_pImpl->m_bIncludeCountry = bSet;
781 m_pImpl->m_sExcludeCountry = bSet ? rCountry : OUString();
782 m_pImpl->SetModified();
783 }
784}
785
787 Reference< XDataSource> const & xSource,
788 const SharedConnection& rConnection,
789 Reference< XColumnsSupplier> const & xColumnsSupplier,
790 const SwDBData& rDBData)
791{
792 m_pImpl->m_xSource = xSource ;
793 m_pImpl->m_xConnection = rConnection ;
794 m_pImpl->m_xColumnsSupplier = xColumnsSupplier;
795 m_pImpl->m_aDBData = rDBData;
796 m_pImpl->m_xResultSet = nullptr;
797 m_pImpl->m_nResultSetCursorPos = 0;
798 m_pImpl->SetModified();
799}
800
801Reference< XDataSource> const & SwMailMergeConfigItem::GetSource() const
802{
803 return m_pImpl->m_xSource;
804}
805
807{
808 return m_pImpl->m_xConnection;
809}
810
811Reference< XColumnsSupplier> const & SwMailMergeConfigItem::GetColumnsSupplier()
812{
813 if(!m_pImpl->m_xColumnsSupplier.is() && m_pImpl->m_xConnection.is())
814 {
815 m_pImpl->m_xColumnsSupplier = SwDBManager::GetColumnSupplier(m_pImpl->m_xConnection,
816 m_pImpl->m_aDBData.sCommand,
817 m_pImpl->m_aDBData.nCommandType == CommandType::TABLE ?
819 }
820 return m_pImpl->m_xColumnsSupplier;
821}
822
824{
825 return m_pImpl->m_aDBData;
826}
827
829{
830 if(m_pImpl->m_aDBData != rDBData)
831 {
832 m_pImpl->m_aDBData = rDBData;
833 m_pImpl->m_xConnection.clear();
834 m_pImpl->m_xSource = nullptr;
835 m_pImpl->m_xResultSet = nullptr;
836 m_pImpl->m_xColumnsSupplier = nullptr;
837 m_pImpl->SetModified();
838 }
839}
840
841Reference< XResultSet> const & SwMailMergeConfigItem::GetResultSet() const
842{
843 if(!m_pImpl->m_xConnection.is() && !m_pImpl->m_aDBData.sDataSource.isEmpty())
844 {
845 m_pImpl->m_xConnection.reset(
846 SwDBManager::GetConnection(m_pImpl->m_aDBData.sDataSource, m_pImpl->m_xSource, m_pSourceView),
848 );
849 }
850 if(!m_pImpl->m_xResultSet.is() && m_pImpl->m_xConnection.is())
851 {
852 try
853 {
854 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
855
856 Reference<XRowSet> xRowSet( xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY );
857 Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
858 xRowProperties->setPropertyValue("DataSourceName", Any(m_pImpl->m_aDBData.sDataSource));
859 xRowProperties->setPropertyValue("Command", Any(m_pImpl->m_aDBData.sCommand));
860 xRowProperties->setPropertyValue("CommandType", Any(m_pImpl->m_aDBData.nCommandType));
861 xRowProperties->setPropertyValue("FetchSize", Any(sal_Int32(10)));
862 xRowProperties->setPropertyValue("ActiveConnection", Any(m_pImpl->m_xConnection.getTyped()));
863 try
864 {
865 xRowProperties->setPropertyValue("ApplyFilter", Any(!m_pImpl->m_sFilter.isEmpty()));
866 xRowProperties->setPropertyValue("Filter", Any(m_pImpl->m_sFilter));
867 }
868 catch (const Exception&)
869 {
870 TOOLS_WARN_EXCEPTION("sw.ui", "");
871 }
872 xRowSet->execute();
873 m_pImpl->m_xResultSet = xRowSet.get();
874 m_pImpl->m_xResultSet->first();
875 m_pImpl->m_nResultSetCursorPos = 1;
876 }
877 catch (const Exception&)
878 {
879 TOOLS_WARN_EXCEPTION("sw.ui", "SwMailMergeConfigItem::GetResultSet()");
880 }
881 }
882 return m_pImpl->m_xResultSet;
883}
884
886{
887 m_pImpl->m_xConnection.clear();
888 if(m_pImpl->m_xResultSet.is())
889 {
890 ::comphelper::disposeComponent( m_pImpl->m_xResultSet );
891 }
892}
893
895{
896 return m_pImpl->m_sFilter;
897}
898
899void SwMailMergeConfigItem::SetFilter(OUString const & rFilter)
900{
901 if(m_pImpl->m_sFilter == rFilter)
902 return;
903
904 m_pImpl->m_sFilter = rFilter;
905 m_pImpl->SetModified();
906 Reference<XPropertySet> xRowProperties(m_pImpl->m_xResultSet, UNO_QUERY);
907 if(!xRowProperties.is())
908 return;
909
910 try
911 {
912 xRowProperties->setPropertyValue("ApplyFilter", Any(!m_pImpl->m_sFilter.isEmpty()));
913 xRowProperties->setPropertyValue("Filter", Any(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
923sal_Int32 SwMailMergeConfigItem::MoveResultSet(sal_Int32 nTarget)
924{
925 if(!m_pImpl->m_xResultSet.is())
926 GetResultSet();
927 if(m_pImpl->m_xResultSet.is())
928 {
929 try
930 {
931 //no action if the resultset is already at the right position
932 if(m_pImpl->m_xResultSet->getRow() != nTarget)
933 {
934 if(nTarget > 0)
935 {
936 bool bMoved = m_pImpl->m_xResultSet->absolute(nTarget);
937 if(!bMoved)
938 {
939 if(nTarget > 1)
940 m_pImpl->m_xResultSet->last();
941 else if(nTarget == 1)
942 m_pImpl->m_xResultSet->first();
943 }
944 }
945 else if(nTarget == -1)
946 m_pImpl->m_xResultSet->last();
947 m_pImpl->m_nResultSetCursorPos = m_pImpl->m_xResultSet->getRow();
948 }
949 }
950 catch (const Exception&)
951 {
952 }
953 }
954 return m_pImpl->m_nResultSetCursorPos;
955}
956
957bool SwMailMergeConfigItem::IsResultSetFirstLast(bool& bIsFirst, bool& bIsLast)
958{
959 bool bRet = false;
960 if(!m_pImpl->m_xResultSet.is())
961 GetResultSet();
962 if(m_pImpl->m_xResultSet.is())
963 {
964 try
965 {
966 bIsFirst = m_pImpl->m_xResultSet->isFirst();
967 bIsLast = m_pImpl->m_xResultSet->isLast();
968 bRet = true;
969 }
970 catch (const Exception&)
971 {
972 }
973 }
974 return bRet;
975}
976
978{
979 return m_pImpl->m_nResultSetCursorPos;
980}
981
982bool SwMailMergeConfigItem::IsRecordIncluded(sal_uInt32 nRecord) const
983 { return nRecord > m_nBegin && nRecord <= m_nEnd; }
984
985bool SwMailMergeConfigItem::IsRecordExcluded(sal_uInt32 nRecord) const
986 { return m_aExcludedRecords.find(nRecord) != m_aExcludedRecords.end(); }
987
988void SwMailMergeConfigItem::ExcludeRecord(sal_Int32 nRecord, bool bExclude)
989{
990 if(bExclude)
991 m_aExcludedRecords.insert(nRecord);
992 else
993 m_aExcludedRecords.erase(nRecord);
994}
995
996uno::Sequence<uno::Any> SwMailMergeConfigItem::GetSelection() const
997{
998 if(!m_pImpl->m_xResultSet.is())
999 GetResultSet();
1000 if(!m_pImpl->m_xResultSet.is())
1001 return {};
1002 m_pImpl->m_xResultSet->last();
1003 sal_uInt32 nResultSetSize = m_pImpl->m_xResultSet->getRow()+1;
1004 std::vector<uno::Any> vResult;
1005 for(sal_uInt32 nIdx=1; nIdx<nResultSetSize;++nIdx)
1006 if( !IsRecordExcluded(nIdx) && IsRecordIncluded(nIdx) )
1007 vResult.push_back(uno::Any(sal_uInt32(nIdx)));
1008 return comphelper::containerToSequence(vResult);
1009}
1010
1011
1012const 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
1061{
1062 return bInEMail ? m_pImpl->m_bIsGreetingLineInMail : m_pImpl->m_bIsGreetingLine;
1063}
1064
1065void 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
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
1137OUString 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
1235 const Sequence< OUString> rFemaleEntries = GetGreetings(SwMailMergeConfigItem::FEMALE);
1236 sal_Int32 nCurrentFemale = GetCurrentGreeting(SwMailMergeConfigItem::FEMALE);
1237 const Sequence< OUString> rMaleEntries = GetGreetings(SwMailMergeConfigItem::MALE);
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
1293void 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
1321void 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
1335void 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 default:
1353 return m_pImpl->m_nMailPort;
1354 }
1355}
1356
1358{
1359 if(m_pImpl->m_nMailPort != nSet)
1360 {
1361 m_pImpl->m_nMailPort = nSet;
1362 m_pImpl->SetModified();
1363 }
1364}
1365
1367{
1368 return m_pImpl->m_bIsSecureConnection;
1369}
1370
1372{
1373 if(m_pImpl->m_bIsSecureConnection != bSet)
1374 {
1375 m_pImpl->m_bIsSecureConnection = bSet;
1376 m_pImpl->SetModified();
1377 }
1378}
1379
1381{
1382 return m_pImpl->m_bIsAuthentication;
1383}
1384
1386{
1387 if(m_pImpl->m_bIsAuthentication != bSet)
1388 {
1389 m_pImpl->m_bIsAuthentication = bSet;
1390 m_pImpl->SetModified();
1391 }
1392}
1393
1395{
1396 return m_pImpl->m_sMailUserName;
1397}
1398
1400{
1401 if(m_pImpl->m_sMailUserName != rName)
1402 {
1403 m_pImpl->m_sMailUserName = rName;
1404 m_pImpl->SetModified();
1405 }
1406}
1407
1409{
1410 return m_pImpl->m_sMailPassword;
1411}
1412
1413void SwMailMergeConfigItem::SetMailPassword(const OUString& rPassword)
1414{
1415 if(m_pImpl->m_sMailPassword != rPassword)
1416 {
1417 m_pImpl->m_sMailPassword = rPassword;
1418 m_pImpl->SetModified();
1419 }
1420}
1421
1423{
1424 return m_pImpl->m_bIsSMPTAfterPOP;
1425}
1426
1428{
1429 if( m_pImpl->m_bIsSMPTAfterPOP != bSet)
1430 {
1431 m_pImpl->m_bIsSMPTAfterPOP = bSet;
1432 m_pImpl->SetModified();
1433 }
1434}
1435
1437{
1438 return m_pImpl->m_sInServerName;
1439}
1440
1441void SwMailMergeConfigItem::SetInServerName(const OUString& rServer)
1442{
1443 if(m_pImpl->m_sInServerName != rServer)
1444 {
1445 m_pImpl->m_sInServerName = rServer;
1446 m_pImpl->SetModified();
1447 }
1448}
1449
1451{
1452 // provide appropriate TCP port as user toggles between POP/IMAP if current port is one of the defaults
1453 switch (m_pImpl->m_nInServerPort)
1454 {
1455 case POP_SECURE_PORT:
1456 case POP_PORT:
1457 case IMAP_SECURE_PORT:
1458 case IMAP_PORT:
1459 if ( m_pImpl->m_bInServerPOP )
1460 return m_pImpl->m_bIsSecureConnection ? POP_SECURE_PORT : POP_PORT;
1461 else
1462 return m_pImpl->m_bIsSecureConnection ? IMAP_SECURE_PORT : IMAP_PORT;
1463 default:
1464 return m_pImpl->m_nInServerPort;
1465 }
1466}
1467
1469{
1470 if( m_pImpl->m_nInServerPort != nSet)
1471 {
1472 m_pImpl->m_nInServerPort = nSet;
1473 m_pImpl->SetModified();
1474 }
1475}
1476
1478{
1479 return m_pImpl->m_bInServerPOP;
1480}
1481
1483{
1484 if( m_pImpl->m_bInServerPOP != bSet)
1485 {
1486 m_pImpl->m_bInServerPOP = bSet;
1487 m_pImpl->SetModified();
1488 }
1489}
1490
1492{
1493 return m_pImpl->m_sInServerUserName;
1494}
1495
1497{
1498 if( m_pImpl->m_sInServerUserName != rName)
1499 {
1500 m_pImpl->m_sInServerUserName = rName;
1501 m_pImpl->SetModified();
1502 }
1503}
1504
1506{
1507 return m_pImpl->m_sInServerPassword;
1508}
1509
1510void SwMailMergeConfigItem::SetInServerPassword(const OUString& rPassword)
1511{
1512 if(m_pImpl->m_sInServerPassword != rPassword)
1513 {
1514 m_pImpl->m_sInServerPassword = rPassword;
1515 m_pImpl->SetModified();
1516 }
1517}
1518
1520{
1521 m_bGreetingInserted = false;
1522 m_bAddressInserted = false;
1523}
1524
1526{
1527 return m_pImpl->m_bIsEMailSupported;
1528}
1529
1531{
1532 m_pImpl->m_aMergeInfos.push_back(rInfo);
1533}
1534
1536{
1537 assert(nDocument < m_pImpl->m_aMergeInfos.size());
1538 return m_pImpl->m_aMergeInfos[nDocument];
1539}
1540
1541
1543{
1544 if(m_pTargetView)
1545 return m_pImpl->m_aMergeInfos.size();
1546 else
1547 {
1548 sal_Int32 nRestore = GetResultSetPosition();
1549 MoveResultSet(-1);
1550 sal_Int32 nRet = GetResultSetPosition();
1551 MoveResultSet( nRestore );
1552 nRet -= m_aExcludedRecords.size();
1553 return nRet >= 0 ? nRet : 0;
1554 }
1555}
1556
1558{
1559 SfxViewShell* pViewShell = SfxViewShell::GetFirst( false, checkSfxViewShell<SwView> );
1560 while(pViewShell)
1561 {
1562 if(pViewShell == pView)
1563 return pView;
1564
1565 pViewShell = SfxViewShell::GetNext( *pViewShell, false, checkSfxViewShell<SwView> );
1566 }
1567 return nullptr;
1568}
1569
1571{
1572 //make sure that the pointer is really valid - the document may have been closed manually
1573 if(m_pTargetView)
1574 {
1576 }
1577 return m_pTargetView;
1578}
1579
1581{
1582 m_pTargetView = pView;
1583 //reset the document merge counter
1584 if(!m_pTargetView)
1585 {
1586 m_pImpl->m_aMergeInfos.clear();
1587 }
1588}
1589
1591{
1593 return m_pSourceView;
1594}
1595
1596namespace {
1597
1598//This implements XSelectionChangeListener and XDispatch because the
1599//broadcaster uses this combo to determine if to send the database-changed
1600//update. Its probably that listening to statusChanged at some other level is
1601//equivalent to this. See the other call to SwXDispatch::GetDBChangeURL for
1602//the broadcaster of the event.
1603class DBChangeListener : public cppu::WeakImplHelper<css::view::XSelectionChangeListener, css::frame::XDispatch>
1604{
1606public:
1607 explicit DBChangeListener(SwMailMergeConfigItem& rParent)
1608 : m_rParent(rParent)
1609 {
1610 }
1611
1612 virtual void SAL_CALL selectionChanged(const EventObject& /*rEvent*/) override
1613 {
1614 }
1615
1616 virtual void SAL_CALL disposing(const EventObject&) override
1617 {
1618 m_rParent.stopDBChangeListening();
1619 }
1620
1621 virtual void SAL_CALL dispatch(const css::util::URL& rURL, const css::uno::Sequence< css::beans::PropertyValue >& /*rArgs*/) override
1622 {
1623 if (rURL.Complete.equalsAscii(SwXDispatch::GetDBChangeURL()))
1624 m_rParent.updateCurrentDBDataFromDocument();
1625 }
1626
1627 virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1628 {
1629 }
1630
1631 virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL&) override
1632 {
1633 }
1634};
1635
1636}
1637
1639{
1640 if (m_xDBChangedListener.is())
1641 {
1642 uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1643 xSupplier->removeSelectionChangeListener(m_xDBChangedListener);
1644 m_xDBChangedListener.clear();
1645 }
1646
1647 m_pSourceView = pView;
1648
1649 if (!m_pSourceView)
1650 return;
1651
1652 std::vector<OUString> aDBNameList;
1653 std::vector<OUString> aAllDBNames;
1654 m_pSourceView->GetWrtShell().GetAllUsedDB( aDBNameList, &aAllDBNames );
1655 if(!aDBNameList.empty())
1656 {
1657 // if fields are available there is usually no need of an addressblock and greeting
1658 if(!m_pImpl->m_bUserSettingWereOverwritten)
1659 {
1660 if( m_pImpl->m_bIsAddressBlock
1661 || m_pImpl->m_bIsGreetingLineInMail
1662 || m_pImpl->m_bIsGreetingLine )
1663 {
1664 //store user settings
1665 m_pImpl->m_bUserSettingWereOverwritten = true;
1666 m_pImpl->m_bIsAddressBlock_LastUserSetting = m_pImpl->m_bIsAddressBlock;
1667 m_pImpl->m_bIsGreetingLineInMail_LastUserSetting = m_pImpl->m_bIsGreetingLineInMail;
1668 m_pImpl->m_bIsGreetingLine_LastUserSetting = m_pImpl->m_bIsGreetingLine;
1669
1670 //set all to false
1671 m_pImpl->m_bIsAddressBlock = false;
1672 m_pImpl->m_bIsGreetingLineInMail = false;
1673 m_pImpl->m_bIsGreetingLine = false;
1674
1675 m_pImpl->SetModified();
1676 }
1677 }
1678 }
1679 else if( m_pImpl->m_bUserSettingWereOverwritten )
1680 {
1681 //restore last user settings:
1682 m_pImpl->m_bIsAddressBlock = m_pImpl->m_bIsAddressBlock_LastUserSetting;
1683 m_pImpl->m_bIsGreetingLineInMail = m_pImpl->m_bIsGreetingLineInMail_LastUserSetting;
1684 m_pImpl->m_bIsGreetingLine = m_pImpl->m_bIsGreetingLine_LastUserSetting;
1685
1686 m_pImpl->m_bUserSettingWereOverwritten = false;
1687 }
1688
1689 if (!m_xDBChangedListener.is())
1690 {
1691 m_xDBChangedListener.set(new DBChangeListener(*this));
1692 }
1693
1694 uno::Reference<view::XSelectionSupplier> xSupplier = m_pSourceView->GetUNOObject();
1695 xSupplier->addSelectionChangeListener(m_xDBChangedListener);
1696}
1697
1699{
1700 m_pImpl->SetCurrentAddressBlockIndex( nSet );
1701}
1702
1704{
1705 return m_pImpl->GetCurrentAddressBlockIndex();
1706}
1707
1708/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
XSLTFilter & m_rParent
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
SwMergeAddressItem Next()
static css::uno::Reference< css::sdbc::XConnection > GetConnection(const OUString &rDataSource, css::uno::Reference< css::sdbc::XDataSource > &rxSource, const SwView *pView)
Definition: dbmgr.cxx:1880
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:1903
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:292
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:302
Sequence< OUString > GetAddressBlocks(bool bConvertToConfig=false) const
void SetAddressBlocks(const Sequence< OUString > &rBlocks, bool bConvertFromConfig=false)
static const Sequence< OUString > & GetPropertyNames()
sal_Int32 GetCurrentGreeting(SwMailMergeConfigItem::Gender eType) const
std::vector< OUString > m_aAddressBlocks
uno::Sequence< OUString > GetGreetings(SwMailMergeConfigItem::Gender eType, bool bConvertToConfig=false) const
void SetCurrentGreeting(SwMailMergeConfigItem::Gender eType, sal_Int32 nIndex)
std::vector< OUString > m_aMaleGreetingLines
uno::Sequence< OUString > m_aSavedDocuments
sal_Int32 GetCurrentAddressBlockIndex() const
SharedConnection m_xConnection
std::vector< SwDocMergeInfo > m_aMergeInfos
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames) override
std::vector< OUString > m_aFemaleGreetingLines
void SetCurrentAddressBlockIndex(sal_Int32 nSet)
std::vector< OUString > m_aNeutralGreetingLines
std::vector< DBAddressDataAssignment > m_aAddressDataAssignments
std::vector< std::pair< OUString, int > > m_AddressHeaderSA
Reference< XColumnsSupplier > m_xColumnsSupplier
Reference< XDataSource > m_xSource
virtual void ImplCommit() override
Reference< XResultSet > m_xResultSet
void SetGreetings(SwMailMergeConfigItem::Gender eType, const uno::Sequence< OUString > &rBlocks, bool bConvertFromConfig=false)
void AddMergedDocument(SwDocMergeInfo const &rInfo)
void SetIndividualGreeting(bool bSet, bool bInEMail)
const SwDBData & GetCurrentDBData() const
sal_Int32 GetResultSetPosition() const
void updateCurrentDBDataFromDocument()
void SetMailReplyTo(bool bSet)
void SetAuthentication(bool bSet)
sal_Int32 MoveResultSet(sal_Int32 nTarget)
css::uno::Sequence< OUString > GetAddressBlocks() const
css::uno::Sequence< OUString > GetGreetings(Gender eType) const
void SetFilter(OUString const &)
void SetGreetingLine(bool bSet, bool bInEMail)
SwDocMergeInfo & GetDocumentMergeInfo(sal_uInt32 nDocument)
std::unique_ptr< SwMailMergeConfigItem_Impl > m_pImpl
OUString const & GetInServerUserName() const
bool IsHideEmptyParagraphs() const
bool IsAuthentication() const
SharedConnection const & GetConnection() const
OUString const & GetInServerName() const
OUString const & GetMailServer() const
void SetCountrySettings(bool bSet, const OUString &sCountry)
void SetCurrentConnection(css::uno::Reference< css::sdbc::XDataSource > const &xSource, const SharedConnection &rConnection, css::uno::Reference< css::sdbcx::XColumnsSupplier > const &xColumnsSupplier, const SwDBData &rDBData)
OUString const & GetMailUserName() const
OUString const & GetMailAddress() const
void SetMailUserName(const OUString &rName)
std::set< sal_Int32 > m_aExcludedRecords
bool IsIncludeCountry() const
OUString const & GetMailDisplayName() const
void SetCurrentAddressBlockIndex(sal_Int32 nSet)
OUString & GetFilter() const
sal_uInt32 GetMergedDocumentCount()
void SetSourceView(SwView *pView)
void SetOutputToLetter(bool bSet)
bool IsSecureConnection() const
sal_Int16 GetInServerPort() const
bool IsAddressFieldsAssigned() const
bool IsRecordIncluded(sal_uInt32 nRecord) const
css::uno::Sequence< css::uno::Any > GetSelection() const
void SetInServerName(const OUString &rServer)
sal_Int32 GetCurrentAddressBlockIndex() const
void SetTargetView(SwView *pView)
OUString & GetExcludeCountry() const
bool IsMailReplyTo() const
void SetMailServer(const OUString &rAddress)
sal_Int16 GetMailPort() const
void SetInServerUserName(const OUString &rName)
void SetGreetings(Gender eType, const css::uno::Sequence< OUString > &rBlocks)
void SetInServerPOP(bool bSet)
bool IsMailAvailable() const
bool IsSMTPAfterPOP() const
void ExcludeRecord(sal_Int32 nRecord, bool bExclude)
bool IsAddressBlock() const
void SetMailPort(sal_Int16 nSet)
const std::vector< std::pair< OUString, int > > & GetDefaultAddressHeaders() const
bool IsRecordExcluded(sal_uInt32 nRecord) const
void SetInServerPort(sal_Int16 nSet)
const css::uno::Sequence< OUString > & GetSavedDocuments() const
css::uno::Reference< css::sdbcx::XColumnsSupplier > const & GetColumnsSupplier()
void SetSecureConnection(bool bSet)
css::uno::Reference< css::view::XSelectionChangeListener > m_xDBChangedListener
OUString const & GetInServerPassword() const
void SetMailDisplayName(const OUString &rName)
void SetFemaleGenderValue(const OUString &rValue)
void SetMailPassword(const OUString &rPassword)
bool IsGreetingLine(bool bInEMail) const
void SetCurrentDBData(const SwDBData &rDBData)
bool IsGreetingFieldsAssigned() const
void SetAddressBlocks(const css::uno::Sequence< OUString > &rBlocks)
void SetSMTPAfterPOP(bool bSet)
bool IsInServerPOP() const
bool IsIndividualGreeting(bool bInEMail) const
bool IsResultSetFirstLast(bool &bIsFirst, bool &bIsLast)
OUString const & GetMailPassword() const
css::uno::Sequence< OUString > GetColumnAssignment(const SwDBData &rDBData) const
sal_Int32 GetCurrentGreeting(Gender eType) const
css::uno::Reference< css::sdbc::XResultSet > const & GetResultSet() const
OUString const & GetMailReplyTo() const
css::uno::Reference< css::sdbc::XDataSource > const & GetSource() const
bool IsOutputToLetter() const
void SetAddressBlock(bool bSet)
void SetColumnAssignment(const SwDBData &rDBData, const css::uno::Sequence< OUString > &)
void SetInServerPassword(const OUString &rPassword)
void SetHideEmptyParagraphs(bool bSet)
const OUString & GetFemaleGenderValue() const
void SetMailAddress(const OUString &rAddress)
void SetCurrentGreeting(Gender eType, sal_Int32 nIndex)
OUString GetAssignedColumn(sal_uInt32 nColumn) const
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
css::view::XSelectionSupplier * GetUNOObject()
Definition: view0.cxx:113
static const char * GetDBChangeURL()
static bool PutProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, const css::uno::Sequence< css::uno::Any > &rValues, bool bAllLocales)
static bool SetSetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
void ClearModified()
static css::uno::Sequence< css::uno::Any > GetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, bool bAllLocales)
static css::uno::Sequence< OUString > GetNodeNames(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, ConfigNameFormat eFormat)
ConfigItemMode
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
DocumentType eType
sal_Int32 nIndex
OUString aName
virtual DECL_LISTENERMULTIPLEXER_END void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
#define SAL_WARN(area, stream)
#define DEFAULT_PORT
#define IMAP_PORT
#define SECURE_PORT
const char cDataSourceName[]
#define IMAP_SECURE_PORT
static OUString lcl_CreateNodeName(Sequence< OUString > &rAssignments)
static void lcl_ConvertToNumbers(OUString &rBlock, const std::vector< std::pair< OUString, int > > &rHeaders)
const char cDBColumnAssignments[]
constexpr OUStringLiteral cAddressDataAssignments
static void lcl_ConvertFromNumbers(OUString &rBlock, const std::vector< std::pair< OUString, int > > &rHeaders)
static SwView * lcl_ExistsView(SwView *pView)
const char cDataTableName[]
const char cDataCommandType[]
#define POP_PORT
#define POP_SECURE_PORT
bool UCB_IsFile(const OUString &rURL)
@ Exception
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
constexpr OUStringLiteral first
enumrange< T >::Iterator begin(enumrange< T >)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
OUString sDataSource
Definition: swdbdata.hxx:30
OUString sCommand
Definition: swdbdata.hxx:31
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
sal_uInt16 sal_Unicode