xref: /core/sw/source/core/fields/authfld.cxx (revision 3c6cb83b)
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 #include <memory>
21 #include <hintids.hxx>
22 #include <comphelper/string.hxx>
23 #include <editeng/unolingu.hxx>
24 #include <editeng/langitem.hxx>
25 #include <i18nlangtag/languagetag.hxx>
26 #include <o3tl/any.hxx>
27 #include <swtypes.hxx>
28 #include <strings.hrc>
29 #include <authfld.hxx>
30 #include <expfld.hxx>
31 #include <pam.hxx>
32 #include <cntfrm.hxx>
33 #include <rootfrm.hxx>
34 #include <tox.hxx>
35 #include <txmsrt.hxx>
36 #include <doctxm.hxx>
37 #include <fmtfld.hxx>
38 #include <txtfld.hxx>
39 #include <ndtxt.hxx>
40 #include <doc.hxx>
41 #include <IDocumentFieldsAccess.hxx>
42 #include <IDocumentLayoutAccess.hxx>
43 #include <unofldmid.h>
44 #include <unoprnms.hxx>
45 #include <calbck.hxx>
46 #include <unomid.h>
47 
48 #include <com/sun/star/beans/PropertyValues.hpp>
49 
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::lang;
53 
54 SwAuthEntry::SwAuthEntry(const SwAuthEntry& rCopy)
55     : SimpleReferenceObject()
56 {
57     for(int i = 0; i < AUTH_FIELD_END; ++i)
58         aAuthFields[i] = rCopy.aAuthFields[i];
59 }
60 
61 bool    SwAuthEntry::operator==(const SwAuthEntry& rComp)
62 {
63     for(int i = 0; i < AUTH_FIELD_END; ++i)
64         if(aAuthFields[i] != rComp.aAuthFields[i])
65             return false;
66     return true;
67 }
68 
69 SwAuthorityFieldType::SwAuthorityFieldType(SwDoc* pDoc)
70     : SwFieldType( SwFieldIds::TableOfAuthorities ),
71     m_pDoc(pDoc),
72     m_cPrefix('['),
73     m_cSuffix(']'),
74     m_bIsSequence(false),
75     m_bSortByDocument(true),
76     m_eLanguage(::GetAppLanguage())
77 {
78 }
79 
80 SwAuthorityFieldType::~SwAuthorityFieldType()
81 {
82 }
83 
84 std::unique_ptr<SwFieldType> SwAuthorityFieldType::Copy()  const
85 {
86     return std::make_unique<SwAuthorityFieldType>(m_pDoc);
87 }
88 
89 void SwAuthorityFieldType::RemoveField(const SwAuthEntry* nHandle)
90 {
91     for(SwAuthDataArr::size_type j = 0; j < m_DataArr.size(); ++j)
92     {
93         if(m_DataArr[j].get() == nHandle)
94         {
95             m_DataArr.erase(m_DataArr.begin() + j);
96             //re-generate positions of the fields
97             DelSequenceArray();
98             return;
99         }
100     }
101     OSL_FAIL("Field unknown" );
102 }
103 
104 SwAuthEntry* SwAuthorityFieldType::AddField(const OUString& rFieldContents)
105 {
106     rtl::Reference<SwAuthEntry> pEntry(new SwAuthEntry);
107     sal_Int32 nIdx{ 0 };
108     for( sal_Int32 i = 0; i < AUTH_FIELD_END; ++i )
109         pEntry->SetAuthorField( static_cast<ToxAuthorityField>(i),
110                         rFieldContents.getToken( 0, TOX_STYLE_DELIMITER, nIdx ));
111 
112     for (auto &rpTemp : m_DataArr)
113     {
114         if (*rpTemp == *pEntry)
115         {
116             return rpTemp.get();
117         }
118     }
119 
120     //if it is a new Entry - insert
121     m_DataArr.push_back(std::move(pEntry));
122     //re-generate positions of the fields
123     DelSequenceArray();
124     return m_DataArr.back().get();
125 }
126 
127 void SwAuthorityFieldType::GetAllEntryIdentifiers(
128     std::vector<OUString>& rToFill )const
129 {
130     for (const auto & rpTemp : m_DataArr)
131     {
132         rToFill.push_back(rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER));
133     }
134 }
135 
136 SwAuthEntry* SwAuthorityFieldType::GetEntryByIdentifier(
137                                 const OUString& rIdentifier)const
138 {
139     for (const auto &rpTemp : m_DataArr)
140     {
141         if (rIdentifier == rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER))
142         {
143             return rpTemp.get();
144         }
145     }
146     return nullptr;
147 }
148 
149 bool SwAuthorityFieldType::ChangeEntryContent(const SwAuthEntry* pNewEntry)
150 {
151     for (auto &rpTemp : m_DataArr)
152     {
153         if (rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER) ==
154                     pNewEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER))
155         {
156             for(int i = 0; i < AUTH_FIELD_END; ++i)
157             {
158                 rpTemp->SetAuthorField(static_cast<ToxAuthorityField>(i),
159                     pNewEntry->GetAuthorField(static_cast<ToxAuthorityField>(i)));
160             }
161             return true;
162         }
163     }
164     return false;
165 }
166 
167 /// appends a new entry (if new) and returns the array position
168 sal_uInt16  SwAuthorityFieldType::AppendField( const SwAuthEntry& rInsert )
169 {
170     for( SwAuthDataArr::size_type nRet = 0; nRet < m_DataArr.size(); ++nRet )
171     {
172         if( *m_DataArr[ nRet ] == rInsert )
173             return nRet;
174     }
175 
176     //if it is a new Entry - insert
177     m_DataArr.push_back(new SwAuthEntry(rInsert));
178     return m_DataArr.size()-1;
179 }
180 
181 sal_uInt16 SwAuthorityFieldType::GetSequencePos(const SwAuthEntry* pAuthEntry,
182         SwRootFrame const*const pLayout)
183 {
184     //find the field in a sorted array of handles,
185 #if OSL_DEBUG_LEVEL > 0
186     bool bCurrentFieldWithoutTextNode = false;
187 #endif
188     if(!m_SequArr.empty() && m_SequArr.size() != m_DataArr.size())
189         DelSequenceArray();
190     if(m_SequArr.empty())
191     {
192         IDocumentRedlineAccess const& rIDRA(m_pDoc->getIDocumentRedlineAccess());
193         // sw_redlinehide: need 2 arrays because the sorting may be different,
194         // if multiple fields refer to the same entry and first one is deleted
195         std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArr;
196         std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArrRLHidden;
197         SwIterator<SwFormatField,SwFieldType> aIter( *this );
198 
199         SwTOXInternational aIntl(m_eLanguage, SwTOIOptions::NONE, m_sSortAlgorithm);
200 
201         for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
202         {
203             const SwTextField* pTextField = pFormatField->GetTextField();
204             if(!pTextField || !pTextField->GetpTextNode())
205             {
206 #if OSL_DEBUG_LEVEL > 0
207                 if(pAuthEntry == static_cast<SwAuthorityField*>(pFormatField->GetField())->GetAuthEntry())
208                     bCurrentFieldWithoutTextNode = true;
209 #endif
210                 continue;
211             }
212             const SwTextNode& rFieldTextNode = pTextField->GetTextNode();
213             SwPosition aFieldPos(rFieldTextNode);
214             SwDoc& rDoc = *const_cast<SwDoc*>(rFieldTextNode.GetDoc());
215             SwContentFrame *pFrame = rFieldTextNode.getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
216             const SwTextNode* pTextNode = nullptr;
217             if(pFrame && !pFrame->IsInDocBody())
218                 pTextNode = GetBodyTextNode( rDoc, aFieldPos, *pFrame );
219             //if no text node could be found or the field is in the document
220             //body the directly available text node will be used
221             if(!pTextNode)
222                 pTextNode = &rFieldTextNode;
223             if (pTextNode->GetText().isEmpty()
224                 || !pTextNode->getLayoutFrame(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
225                 || !pTextNode->GetNodes().IsDocNodes())
226             {
227                 continue;
228             }
229             auto const InsertImpl = [&aIntl, pTextNode, pFormatField]
230                 (std::vector<std::unique_ptr<SwTOXSortTabBase>> & rSortArr)
231             {
232                 std::unique_ptr<SwTOXAuthority> pNew(
233                     new SwTOXAuthority(*pTextNode, *pFormatField, aIntl));
234 
235                 for (size_t i = 0; i < rSortArr.size(); ++i)
236                 {
237                     SwTOXSortTabBase* pOld = rSortArr[i].get();
238                     if (pOld->equivalent(*pNew))
239                     {
240                         //only the first occurrence in the document
241                         //has to be in the array
242                         if (pOld->sort_lt(*pNew))
243                             pNew.reset();
244                         else // remove the old content
245                             rSortArr.erase(rSortArr.begin() + i);
246                         break;
247                     }
248                 }
249                 //if it still exists - insert at the correct position
250                 if (pNew)
251                 {
252                     size_t j {0};
253 
254                     while (j < rSortArr.size())
255                     {
256                         SwTOXSortTabBase* pOld = rSortArr[j].get();
257                         if (pNew->sort_lt(*pOld))
258                             break;
259                         ++j;
260                     }
261                     rSortArr.insert(rSortArr.begin() + j, std::move(pNew));
262                 }
263             };
264             InsertImpl(aSortArr);
265             if (!sw::IsFieldDeletedInModel(rIDRA, *pTextField))
266             {
267                 InsertImpl(aSortArrRLHidden);
268             }
269         }
270 
271         for(auto & pBase : aSortArr)
272         {
273             SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
274             SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
275             m_SequArr.push_back(pAField->GetAuthEntry());
276         }
277         for (auto & pBase : aSortArrRLHidden)
278         {
279             SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
280             SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
281             m_SequArrRLHidden.push_back(pAField->GetAuthEntry());
282         }
283     }
284     //find nHandle
285     auto const& rSequArr(pLayout && pLayout->IsHideRedlines() ? m_SequArrRLHidden : m_SequArr);
286     for (std::vector<sal_IntPtr>::size_type i = 0; i < rSequArr.size(); ++i)
287     {
288         if (rSequArr[i] == pAuthEntry)
289         {
290             return i + 1;
291         }
292     }
293 #if OSL_DEBUG_LEVEL > 0
294     OSL_ENSURE(bCurrentFieldWithoutTextNode, "Handle not found");
295 #endif
296     return 0;
297 }
298 
299 void SwAuthorityFieldType::QueryValue( Any& rVal, sal_uInt16 nWhichId ) const
300 {
301     switch( nWhichId )
302     {
303     case FIELD_PROP_PAR1:
304     case FIELD_PROP_PAR2:
305         {
306             OUString sVal;
307             sal_Unicode uRet = FIELD_PROP_PAR1 == nWhichId ? m_cPrefix : m_cSuffix;
308             if(uRet)
309                 sVal = OUString(uRet);
310             rVal <<= sVal;
311         }
312         break;
313     case FIELD_PROP_PAR3:
314         rVal <<= GetSortAlgorithm();
315         break;
316 
317     case FIELD_PROP_BOOL1:
318         rVal <<= m_bIsSequence;
319         break;
320 
321     case FIELD_PROP_BOOL2:
322         rVal <<= m_bSortByDocument;
323         break;
324 
325     case FIELD_PROP_LOCALE:
326         rVal <<= LanguageTag(GetLanguage()).getLocale();
327         break;
328 
329     case FIELD_PROP_PROP_SEQ:
330         {
331             Sequence<PropertyValues> aRet(m_SortKeyArr.size());
332             PropertyValues* pValues = aRet.getArray();
333             for(SortKeyArr::size_type i = 0; i < m_SortKeyArr.size(); ++i)
334             {
335                 const SwTOXSortKey* pKey = &m_SortKeyArr[i];
336                 pValues[i].realloc(2);
337                 PropertyValue* pValue = pValues[i].getArray();
338                 pValue[0].Name = UNO_NAME_SORT_KEY;
339                 pValue[0].Value <<= sal_Int16(pKey->eField);
340                 pValue[1].Name = UNO_NAME_IS_SORT_ASCENDING;
341                 pValue[1].Value <<= pKey->bSortAscending;
342             }
343             rVal <<= aRet;
344         }
345         break;
346     default:
347         assert(false);
348     }
349 }
350 
351 void SwAuthorityFieldType::PutValue( const Any& rAny, sal_uInt16 nWhichId )
352 {
353     bool bRet = true;
354     switch( nWhichId )
355     {
356     case FIELD_PROP_PAR1:
357     case FIELD_PROP_PAR2:
358     {
359         OUString sTmp;
360         rAny >>= sTmp;
361         const sal_Unicode uSet = !sTmp.isEmpty() ? sTmp[0] : 0;
362         if( FIELD_PROP_PAR1 == nWhichId )
363             m_cPrefix = uSet;
364         else
365             m_cSuffix = uSet;
366     }
367     break;
368     case FIELD_PROP_PAR3:
369     {
370         OUString sTmp;
371         rAny >>= sTmp;
372         SetSortAlgorithm(sTmp);
373         break;
374     }
375     case FIELD_PROP_BOOL1:
376         m_bIsSequence = *o3tl::doAccess<bool>(rAny);
377         break;
378     case FIELD_PROP_BOOL2:
379         m_bSortByDocument = *o3tl::doAccess<bool>(rAny);
380         break;
381 
382     case FIELD_PROP_LOCALE:
383         {
384             css::lang::Locale aLocale;
385             bRet = rAny >>= aLocale;
386             if( bRet )
387                 SetLanguage( LanguageTag::convertToLanguageType( aLocale ));
388         }
389         break;
390 
391     case FIELD_PROP_PROP_SEQ:
392         {
393             Sequence<PropertyValues> aSeq;
394             bRet = rAny >>= aSeq;
395             if( bRet )
396             {
397                 m_SortKeyArr.clear();
398                 const PropertyValues* pValues = aSeq.getConstArray();
399                 //TODO: Limiting to the first SAL_MAX_UINT16 elements of aSeq so that size of
400                 // m_SortKeyArr remains in range of sal_uInt16, as GetSortKeyCount and GetSortKey
401                 // still expect m_SortKeyArr to be indexed by sal_uInt16:
402                 auto nSize = std::min<sal_Int32>(aSeq.getLength(), SAL_MAX_UINT16);
403                 for(sal_Int32 i = 0; i < nSize; i++)
404                 {
405                     SwTOXSortKey aSortKey;
406                     for(const PropertyValue& rValue : pValues[i])
407                     {
408                         if(rValue.Name == UNO_NAME_SORT_KEY)
409                         {
410                             sal_Int16 nVal = -1; rValue.Value >>= nVal;
411                             if(nVal >= 0 && nVal < AUTH_FIELD_END)
412                                 aSortKey.eField = static_cast<ToxAuthorityField>(nVal);
413                             else
414                                 bRet = false;
415                         }
416                         else if(rValue.Name == UNO_NAME_IS_SORT_ASCENDING)
417                         {
418                             aSortKey.bSortAscending = *o3tl::doAccess<bool>(rValue.Value);
419                         }
420                     }
421                     m_SortKeyArr.push_back(aSortKey);
422                 }
423             }
424         }
425         break;
426     default:
427         assert(false);
428     }
429 }
430 
431 void SwAuthorityFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
432 {
433     //re-generate positions of the fields
434     DelSequenceArray();
435     NotifyClients( pOld, pNew );
436 }
437 
438 sal_uInt16 SwAuthorityFieldType::GetSortKeyCount() const
439 {
440     return m_SortKeyArr.size();
441 }
442 
443 const SwTOXSortKey*  SwAuthorityFieldType::GetSortKey(sal_uInt16 nIdx) const
444 {
445     if(m_SortKeyArr.size() > nIdx)
446         return &m_SortKeyArr[nIdx];
447     OSL_FAIL("Sort key not found");
448     return nullptr;
449 }
450 
451 void SwAuthorityFieldType::SetSortKeys(sal_uInt16 nKeyCount, SwTOXSortKey  const aKeys[])
452 {
453     m_SortKeyArr.clear();
454     for(sal_uInt16 i = 0; i < nKeyCount; i++)
455         if(aKeys[i].eField < AUTH_FIELD_END)
456             m_SortKeyArr.push_back(aKeys[i]);
457 }
458 
459 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
460                                     const OUString& rFieldContents )
461     : SwField(pInitType)
462     , m_nTempSequencePos( -1 )
463     , m_nTempSequencePosRLHidden( -1 )
464 {
465     m_xAuthEntry = pInitType->AddField( rFieldContents );
466 }
467 
468 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
469                                     SwAuthEntry* pAuthEntry )
470     : SwField( pInitType )
471     , m_xAuthEntry( pAuthEntry )
472     , m_nTempSequencePos( -1 )
473     , m_nTempSequencePosRLHidden( -1 )
474 {
475 }
476 
477 SwAuthorityField::~SwAuthorityField()
478 {
479     static_cast<SwAuthorityFieldType* >(GetTyp())->RemoveField(m_xAuthEntry.get());
480 }
481 
482 OUString SwAuthorityField::ExpandImpl(SwRootFrame const*const pLayout) const
483 {
484     return ConditionalExpandAuthIdentifier(pLayout);
485 }
486 
487 OUString SwAuthorityField::ConditionalExpandAuthIdentifier(
488         SwRootFrame const*const pLayout) const
489 {
490     SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
491     OUString sRet;
492     if(pAuthType->GetPrefix())
493         sRet = OUString(pAuthType->GetPrefix());
494 
495     if( pAuthType->IsSequence() )
496     {
497         sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
498                 ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
499         if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
500             rnTempSequencePos = pAuthType->GetSequencePos(m_xAuthEntry.get(), pLayout);
501         if (0 <= rnTempSequencePos)
502             sRet += OUString::number(rnTempSequencePos);
503     }
504     else
505     {
506         //TODO: Expand to: identifier, number sequence, ...
507         if(m_xAuthEntry)
508             sRet += m_xAuthEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER);
509     }
510     if(pAuthType->GetSuffix())
511         sRet += OUStringLiteral1(pAuthType->GetSuffix());
512     return sRet;
513 }
514 
515 OUString SwAuthorityField::ExpandCitation(ToxAuthorityField eField,
516         SwRootFrame const*const pLayout) const
517 {
518     SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
519     OUString sRet;
520 
521     if( pAuthType->IsSequence() )
522     {
523         sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
524                 ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
525         if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
526             rnTempSequencePos = pAuthType->GetSequencePos(m_xAuthEntry.get(), pLayout);
527         if (0 <= rnTempSequencePos)
528             sRet += OUString::number(rnTempSequencePos);
529     }
530     else
531     {
532         //TODO: Expand to: identifier, number sequence, ...
533         if(m_xAuthEntry)
534             sRet += m_xAuthEntry->GetAuthorField(eField);
535     }
536     return sRet;
537 }
538 
539 std::unique_ptr<SwField> SwAuthorityField::Copy() const
540 {
541     SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
542     return std::make_unique<SwAuthorityField>(pAuthType, m_xAuthEntry.get());
543 }
544 
545 const OUString & SwAuthorityField::GetFieldText(ToxAuthorityField eField) const
546 {
547     return m_xAuthEntry->GetAuthorField( eField );
548 }
549 
550 void SwAuthorityField::SetPar1(const OUString& rStr)
551 {
552     SwAuthorityFieldType* pInitType = static_cast<SwAuthorityFieldType* >(GetTyp());
553     pInitType->RemoveField(m_xAuthEntry.get());
554     m_xAuthEntry = pInitType->AddField(rStr);
555 }
556 
557 OUString SwAuthorityField::GetDescription() const
558 {
559     return SwResId(STR_AUTHORITY_ENTRY);
560 }
561 
562 const char* const aFieldNames[] =
563 {
564     "Identifier",
565     "BibiliographicType",
566     "Address",
567     "Annote",
568     "Author",
569     "Booktitle",
570     "Chapter",
571     "Edition",
572     "Editor",
573     "Howpublished",
574     "Institution",
575     "Journal",
576     "Month",
577     "Note",
578     "Number",
579     "Organizations",
580     "Pages",
581     "Publisher",
582     "School",
583     "Series",
584     "Title",
585     "Report_Type",
586     "Volume",
587     "Year",
588     "URL",
589     "Custom1",
590     "Custom2",
591     "Custom3",
592     "Custom4",
593     "Custom5",
594     "ISBN"
595 };
596 
597 bool    SwAuthorityField::QueryValue( Any& rAny, sal_uInt16 /*nWhichId*/ ) const
598 {
599     if(!GetTyp())
600         return false;
601     if(!m_xAuthEntry)
602         return false;
603     Sequence <PropertyValue> aRet(AUTH_FIELD_END);
604     PropertyValue* pValues = aRet.getArray();
605     for(int i = 0; i < AUTH_FIELD_END; ++i)
606     {
607         pValues[i].Name = OUString::createFromAscii(aFieldNames[i]);
608         const OUString& sField = m_xAuthEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
609         if(i == AUTH_FIELD_AUTHORITY_TYPE)
610             pValues[i].Value <<= sal_Int16(sField.toInt32());
611         else
612             pValues[i].Value <<= sField;
613     }
614     rAny <<= aRet;
615     /* FIXME: it is weird that we always return false here */
616     return false;
617 }
618 
619 static sal_Int32 lcl_Find(const OUString& rFieldName)
620 {
621     for(sal_Int32 i = 0; i < AUTH_FIELD_END; ++i)
622         if(rFieldName.equalsAscii(aFieldNames[i]))
623             return i;
624     return -1;
625 }
626 
627 bool    SwAuthorityField::PutValue( const Any& rAny, sal_uInt16 /*nWhichId*/ )
628 {
629     if(!GetTyp() || !m_xAuthEntry)
630         return false;
631 
632     Sequence <PropertyValue> aParam;
633     if(!(rAny >>= aParam))
634         return false;
635 
636     OUStringBuffer sBuf;
637     comphelper::string::padToLength(sBuf, AUTH_FIELD_ISBN, TOX_STYLE_DELIMITER);
638     OUString sToSet(sBuf.makeStringAndClear());
639     for(const PropertyValue& rParam : std::as_const(aParam))
640     {
641         const sal_Int32 nFound = lcl_Find(rParam.Name);
642         if(nFound >= 0)
643         {
644             OUString sContent;
645             if(AUTH_FIELD_AUTHORITY_TYPE == nFound)
646             {
647                 sal_Int16 nVal = 0;
648                 rParam.Value >>= nVal;
649                 sContent = OUString::number(nVal);
650             }
651             else
652                 rParam.Value >>= sContent;
653             sToSet = comphelper::string::setToken(sToSet, nFound, TOX_STYLE_DELIMITER, sContent);
654         }
655     }
656 
657     static_cast<SwAuthorityFieldType*>(GetTyp())->RemoveField(m_xAuthEntry.get());
658     m_xAuthEntry = static_cast<SwAuthorityFieldType*>(GetTyp())->AddField(sToSet);
659 
660     /* FIXME: it is weird that we always return false here */
661     return false;
662 }
663 
664 SwFieldType* SwAuthorityField::ChgTyp( SwFieldType* pFieldTyp )
665 {
666     SwAuthorityFieldType* pSrcTyp = static_cast<SwAuthorityFieldType*>(GetTyp()),
667                         * pDstTyp = static_cast<SwAuthorityFieldType*>(pFieldTyp);
668     if( pSrcTyp != pDstTyp )
669     {
670         const SwAuthEntry* pSrcEntry = m_xAuthEntry.get();
671         pDstTyp->AppendField( *pSrcEntry );
672         pSrcTyp->RemoveField( pSrcEntry );
673         SwField::ChgTyp( pFieldTyp );
674     }
675     return pSrcTyp;
676 }
677 
678 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
679