Revert "tdf#158280 Replace usage of InputDialog with SvxNameDialog"
[LibreOffice.git] / sw / source / core / fields / authfld.cxx
blob0a3de0e91bb5a0c2336f2d2c0584085226ee0c20
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <memory>
24 #include <libxml/xmlwriter.h>
26 #include <comphelper/processfactory.hxx>
27 #include <comphelper/string.hxx>
28 #include <i18nlangtag/languagetag.hxx>
29 #include <o3tl/any.hxx>
30 #include <o3tl/string_view.hxx>
31 #include <officecfg/Office/Common.hxx>
32 #include <osl/diagnose.h>
33 #include <tools/urlobj.hxx>
34 #include <swtypes.hxx>
35 #include <strings.hrc>
36 #include <authfld.hxx>
37 #include <expfld.hxx>
38 #include <pam.hxx>
39 #include <cntfrm.hxx>
40 #include <rootfrm.hxx>
41 #include <tox.hxx>
42 #include <txmsrt.hxx>
43 #include <fmtfld.hxx>
44 #include <txtfld.hxx>
45 #include <ndtxt.hxx>
46 #include <doc.hxx>
47 #include <IDocumentFieldsAccess.hxx>
48 #include <IDocumentLayoutAccess.hxx>
49 #include <unofldmid.h>
50 #include <unoprnms.hxx>
51 #include <docsh.hxx>
53 #include <com/sun/star/beans/PropertyValues.hpp>
54 #include <com/sun/star/uri/UriReferenceFactory.hpp>
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::lang;
60 SwAuthEntry::SwAuthEntry(const SwAuthEntry& rCopy)
61 : SimpleReferenceObject()
63 for(int i = 0; i < AUTH_FIELD_END; ++i)
64 m_aAuthFields[i] = rCopy.m_aAuthFields[i];
67 bool SwAuthEntry::operator==(const SwAuthEntry& rComp) const
69 for(int i = 0; i < AUTH_FIELD_END; ++i)
70 if(m_aAuthFields[i] != rComp.m_aAuthFields[i])
71 return false;
72 return true;
75 SwAuthorityFieldType::SwAuthorityFieldType(SwDoc* pDoc)
76 : SwFieldType( SwFieldIds::TableOfAuthorities ),
77 m_pDoc(pDoc),
78 m_cPrefix('['),
79 m_cSuffix(']'),
80 m_bIsSequence(false),
81 m_bSortByDocument(true),
82 m_eLanguage(::GetAppLanguage())
86 SwAuthorityFieldType::~SwAuthorityFieldType()
90 std::unique_ptr<SwFieldType> SwAuthorityFieldType::Copy() const
92 return std::make_unique<SwAuthorityFieldType>(m_pDoc);
95 void SwAuthorityFieldType::RemoveField(const SwAuthEntry* pEntry)
97 for(SwAuthDataArr::size_type j = 0; j < m_DataArr.size(); ++j)
99 if(m_DataArr[j].get() == pEntry)
101 if (m_DataArr[j]->m_nCount <= 1)
103 m_DataArr.erase(m_DataArr.begin() + j);
104 //re-generate positions of the fields
105 DelSequenceArray();
107 return;
110 assert(false && "SwAuthorityFieldType::RemoveField: pEntry was not added previously");
113 SwAuthEntry* SwAuthorityFieldType::AddField(std::u16string_view rFieldContents)
115 rtl::Reference<SwAuthEntry> pEntry(new SwAuthEntry);
116 sal_Int32 nIdx{ 0 };
117 for( sal_Int32 i = 0; i < AUTH_FIELD_END; ++i )
118 pEntry->SetAuthorField( static_cast<ToxAuthorityField>(i),
119 OUString(o3tl::getToken(rFieldContents, 0, TOX_STYLE_DELIMITER, nIdx )));
121 for (const auto &rpTemp : m_DataArr)
123 if (*rpTemp == *pEntry)
125 return rpTemp.get();
129 //if it is a new Entry - insert
130 m_DataArr.push_back(std::move(pEntry));
131 //re-generate positions of the fields
132 DelSequenceArray();
133 return m_DataArr.back().get();
136 void SwAuthorityFieldType::GetAllEntryIdentifiers(
137 std::vector<OUString>& rToFill )const
139 for (const auto & rpTemp : m_DataArr)
141 rToFill.push_back(rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER));
145 SwAuthEntry* SwAuthorityFieldType::GetEntryByIdentifier(
146 std::u16string_view rIdentifier)const
148 for (const auto &rpTemp : m_DataArr)
150 if (rIdentifier == rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER))
152 return rpTemp.get();
155 return nullptr;
158 bool SwAuthorityFieldType::ChangeEntryContent(const SwAuthEntry* pNewEntry)
160 for (auto &rpTemp : m_DataArr)
162 if (rpTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER) ==
163 pNewEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER))
165 for(int i = 0; i < AUTH_FIELD_END; ++i)
167 rpTemp->SetAuthorField(static_cast<ToxAuthorityField>(i),
168 pNewEntry->GetAuthorField(static_cast<ToxAuthorityField>(i)));
170 return true;
173 return false;
176 /// appends a new entry (if new) and returns the copied entry
177 SwAuthEntry* SwAuthorityFieldType::AppendField( const SwAuthEntry& rInsert )
179 for( SwAuthDataArr::size_type nRet = 0; nRet < m_DataArr.size(); ++nRet )
181 if( *m_DataArr[ nRet ] == rInsert )
182 return m_DataArr[ nRet ].get();
185 //if it is a new Entry - insert
186 m_DataArr.push_back(new SwAuthEntry(rInsert));
187 return m_DataArr.back().get();
190 std::unique_ptr<SwTOXInternational> SwAuthorityFieldType::CreateTOXInternational() const
192 return std::make_unique<SwTOXInternational>(m_eLanguage, SwTOIOptions::NONE, m_sSortAlgorithm);
195 sal_uInt16 SwAuthorityFieldType::GetSequencePos(const SwAuthEntry* pAuthEntry,
196 SwRootFrame const*const pLayout)
198 //find the field in a sorted array of handles,
199 if(!m_SequArr.empty() && m_SequArr.size() != m_DataArr.size())
200 DelSequenceArray();
201 if(m_SequArr.empty())
203 IDocumentRedlineAccess const& rIDRA(m_pDoc->getIDocumentRedlineAccess());
204 std::unique_ptr<SwTOXInternational> pIntl = CreateTOXInternational();
205 // sw_redlinehide: need 2 arrays because the sorting may be different,
206 // if multiple fields refer to the same entry and first one is deleted
207 std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArr;
208 std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArrRLHidden;
209 std::vector<SwFormatField*> vFields;
210 GatherFields(vFields);
211 for(SwFormatField* pFormatField : vFields)
213 const SwTextField* pTextField = pFormatField->GetTextField();
214 if(!pTextField || !pTextField->GetpTextNode())
216 continue;
218 const SwTextNode& rFieldTextNode = pTextField->GetTextNode();
219 SwPosition aFieldPos(rFieldTextNode);
220 SwDoc& rDoc = const_cast<SwDoc&>(rFieldTextNode.GetDoc());
221 SwContentFrame *pFrame = rFieldTextNode.getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
222 const SwTextNode* pTextNode = nullptr;
223 if(pFrame && !pFrame->IsInDocBody())
224 pTextNode = GetBodyTextNode( rDoc, aFieldPos, *pFrame );
225 //if no text node could be found or the field is in the document
226 //body the directly available text node will be used
227 if(!pTextNode)
228 pTextNode = &rFieldTextNode;
229 if (pTextNode->GetText().isEmpty()
230 || !pTextNode->getLayoutFrame(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
231 || !pTextNode->GetNodes().IsDocNodes())
233 continue;
235 auto const InsertImpl = [&pIntl, pTextNode, pFormatField]
236 (std::vector<std::unique_ptr<SwTOXSortTabBase>> & rSortArr)
238 std::unique_ptr<SwTOXAuthority> pNew(
239 new SwTOXAuthority(*pTextNode, *pFormatField, *pIntl));
241 for (size_t i = 0; i < rSortArr.size(); ++i)
243 SwTOXSortTabBase* pOld = rSortArr[i].get();
244 if (pOld->equivalent(*pNew))
246 //only the first occurrence in the document
247 //has to be in the array
248 if (pOld->sort_lt(*pNew))
249 pNew.reset();
250 else // remove the old content
251 rSortArr.erase(rSortArr.begin() + i);
252 break;
255 //if it still exists - insert at the correct position
256 if (pNew)
258 size_t j {0};
260 while (j < rSortArr.size())
262 SwTOXSortTabBase* pOld = rSortArr[j].get();
263 if (pNew->sort_lt(*pOld))
264 break;
265 ++j;
267 rSortArr.insert(rSortArr.begin() + j, std::move(pNew));
270 InsertImpl(aSortArr);
271 if (!sw::IsFieldDeletedInModel(rIDRA, *pTextField))
273 InsertImpl(aSortArrRLHidden);
277 for(auto & pBase : aSortArr)
279 SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
280 SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
281 m_SequArr.push_back(pAField->GetAuthEntry());
283 for (auto & pBase : aSortArrRLHidden)
285 SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
286 SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
287 m_SequArrRLHidden.push_back(pAField->GetAuthEntry());
290 //find nHandle
291 auto const& rSequArr(pLayout && pLayout->IsHideRedlines() ? m_SequArrRLHidden : m_SequArr);
292 for (std::vector<sal_IntPtr>::size_type i = 0; i < rSequArr.size(); ++i)
294 if (rSequArr[i] == pAuthEntry)
296 return i + 1;
299 return 0;
302 void SwAuthorityFieldType::QueryValue( Any& rVal, sal_uInt16 nWhichId ) const
304 switch( nWhichId )
306 case FIELD_PROP_PAR1:
307 case FIELD_PROP_PAR2:
309 OUString sVal;
310 sal_Unicode uRet = FIELD_PROP_PAR1 == nWhichId ? m_cPrefix : m_cSuffix;
311 if(uRet)
312 sVal = OUString(uRet);
313 rVal <<= sVal;
315 break;
316 case FIELD_PROP_PAR3:
317 rVal <<= GetSortAlgorithm();
318 break;
320 case FIELD_PROP_BOOL1:
321 rVal <<= m_bIsSequence;
322 break;
324 case FIELD_PROP_BOOL2:
325 rVal <<= m_bSortByDocument;
326 break;
328 case FIELD_PROP_LOCALE:
329 rVal <<= LanguageTag(GetLanguage()).getLocale();
330 break;
332 case FIELD_PROP_PROP_SEQ:
334 Sequence<PropertyValues> aRet(m_SortKeyArr.size());
335 PropertyValues* pValues = aRet.getArray();
336 for(SortKeyArr::size_type i = 0; i < m_SortKeyArr.size(); ++i)
338 const SwTOXSortKey* pKey = &m_SortKeyArr[i];
339 pValues[i].realloc(2);
340 PropertyValue* pValue = pValues[i].getArray();
341 pValue[0].Name = UNO_NAME_SORT_KEY;
342 pValue[0].Value <<= sal_Int16(pKey->eField);
343 pValue[1].Name = UNO_NAME_IS_SORT_ASCENDING;
344 pValue[1].Value <<= pKey->bSortAscending;
346 rVal <<= aRet;
348 break;
349 default:
350 assert(false);
354 void SwAuthorityFieldType::PutValue( const Any& rAny, sal_uInt16 nWhichId )
356 switch( nWhichId )
358 case FIELD_PROP_PAR1:
359 case FIELD_PROP_PAR2:
361 OUString sTmp;
362 rAny >>= sTmp;
363 const sal_Unicode uSet = !sTmp.isEmpty() ? sTmp[0] : 0;
364 if( FIELD_PROP_PAR1 == nWhichId )
365 m_cPrefix = uSet;
366 else
367 m_cSuffix = uSet;
369 break;
370 case FIELD_PROP_PAR3:
372 OUString sTmp;
373 rAny >>= sTmp;
374 SetSortAlgorithm(sTmp);
375 break;
377 case FIELD_PROP_BOOL1:
378 m_bIsSequence = *o3tl::doAccess<bool>(rAny);
379 break;
380 case FIELD_PROP_BOOL2:
381 m_bSortByDocument = *o3tl::doAccess<bool>(rAny);
382 break;
384 case FIELD_PROP_LOCALE:
386 css::lang::Locale aLocale;
387 if( rAny >>= aLocale )
388 SetLanguage( LanguageTag::convertToLanguageType( aLocale ));
390 break;
392 case FIELD_PROP_PROP_SEQ:
394 Sequence<PropertyValues> aSeq;
395 if( rAny >>= aSeq )
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++)
405 SwTOXSortKey aSortKey;
406 for(const PropertyValue& rValue : pValues[i])
408 if(rValue.Name == UNO_NAME_SORT_KEY)
410 sal_Int16 nVal = -1; rValue.Value >>= nVal;
411 if(nVal >= 0 && nVal < AUTH_FIELD_END)
412 aSortKey.eField = static_cast<ToxAuthorityField>(nVal);
414 else if(rValue.Name == UNO_NAME_IS_SORT_ASCENDING)
416 aSortKey.bSortAscending = *o3tl::doAccess<bool>(rValue.Value);
419 m_SortKeyArr.push_back(aSortKey);
423 break;
424 default:
425 assert(false);
429 void SwAuthorityFieldType::SwClientNotify(const SwModify&, const SfxHint& rHint)
431 //re-generate positions of the fields
432 DelSequenceArray();
433 CallSwClientNotify(rHint);
436 sal_uInt16 SwAuthorityFieldType::GetSortKeyCount() const
438 return m_SortKeyArr.size();
441 const SwTOXSortKey* SwAuthorityFieldType::GetSortKey(sal_uInt16 nIdx) const
443 if(m_SortKeyArr.size() > nIdx)
444 return &m_SortKeyArr[nIdx];
445 OSL_FAIL("Sort key not found");
446 return nullptr;
449 void SwAuthorityFieldType::SetSortKeys(sal_uInt16 nKeyCount, SwTOXSortKey const aKeys[])
451 m_SortKeyArr.clear();
452 for(sal_uInt16 i = 0; i < nKeyCount; i++)
453 if(aKeys[i].eField < AUTH_FIELD_END)
454 m_SortKeyArr.push_back(aKeys[i]);
457 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
458 std::u16string_view rFieldContents )
459 : SwField(pInitType)
460 , m_nTempSequencePos( -1 )
461 , m_nTempSequencePosRLHidden( -1 )
463 m_xAuthEntry = pInitType->AddField( rFieldContents );
466 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
467 SwAuthEntry* pAuthEntry )
468 : SwField( pInitType )
469 , m_xAuthEntry( pAuthEntry )
470 , m_nTempSequencePos( -1 )
471 , m_nTempSequencePosRLHidden( -1 )
475 SwAuthorityField::~SwAuthorityField()
477 static_cast<SwAuthorityFieldType* >(GetTyp())->RemoveField(m_xAuthEntry.get());
480 OUString SwAuthorityField::ExpandImpl(SwRootFrame const*const pLayout) const
482 return ConditionalExpandAuthIdentifier(pLayout);
485 OUString SwAuthorityField::ConditionalExpandAuthIdentifier(
486 SwRootFrame const*const pLayout) const
488 SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
489 OUString sRet;
490 if(pAuthType->GetPrefix())
491 sRet = OUString(pAuthType->GetPrefix());
493 if( pAuthType->IsSequence() )
495 sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
496 ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
497 if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
498 rnTempSequencePos = pAuthType->GetSequencePos(m_xAuthEntry.get(), pLayout);
499 if (0 <= rnTempSequencePos)
500 sRet += OUString::number(rnTempSequencePos);
502 else
504 //TODO: Expand to: identifier, number sequence, ...
505 if(m_xAuthEntry)
507 OUString sIdentifier(m_xAuthEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER));
508 // tdf#107784 Use title if it's a ooxml citation
509 if (o3tl::starts_with(o3tl::trim(sIdentifier), u"CITATION"))
510 return m_xAuthEntry->GetAuthorField(AUTH_FIELD_TITLE);
511 else
512 sRet += sIdentifier;
515 if(pAuthType->GetSuffix())
516 sRet += OUStringChar(pAuthType->GetSuffix());
517 return sRet;
520 OUString SwAuthorityField::ExpandCitation(ToxAuthorityField eField,
521 SwRootFrame const*const pLayout) const
523 SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
524 OUString sRet;
526 if( pAuthType->IsSequence() )
528 sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
529 ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
530 if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
531 rnTempSequencePos = pAuthType->GetSequencePos(m_xAuthEntry.get(), pLayout);
532 if (0 <= rnTempSequencePos)
533 sRet += OUString::number(rnTempSequencePos);
535 else
537 //TODO: Expand to: identifier, number sequence, ...
538 if(m_xAuthEntry)
539 sRet += m_xAuthEntry->GetAuthorField(eField);
541 return sRet;
544 std::unique_ptr<SwField> SwAuthorityField::Copy() const
546 SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
547 return std::make_unique<SwAuthorityField>(pAuthType, m_xAuthEntry.get());
550 const OUString & SwAuthorityField::GetFieldText(ToxAuthorityField eField) const
552 return m_xAuthEntry->GetAuthorField( eField );
555 void SwAuthorityField::SetPar1(const OUString& rStr)
557 SwAuthorityFieldType* pInitType = static_cast<SwAuthorityFieldType* >(GetTyp());
558 pInitType->RemoveField(m_xAuthEntry.get());
559 m_xAuthEntry = pInitType->AddField(rStr);
562 OUString SwAuthorityField::GetDescription() const
564 return SwResId(STR_AUTHORITY_ENTRY);
567 OUString SwAuthorityField::GetAuthority(const SwRootFrame* pLayout, const SwForm* pTOX) const
569 OUString aText;
571 std::unique_ptr<SwForm> pDefaultTOX;
572 if (!pTOX)
574 pDefaultTOX = std::make_unique<SwForm>(TOX_AUTHORITIES);
575 pTOX = pDefaultTOX.get();
578 SwAuthorityFieldType* pFieldType = static_cast<SwAuthorityFieldType*>(GetTyp());
579 std::unique_ptr<SwTOXInternational> pIntl(pFieldType->CreateTOXInternational());
581 // This is based on SwTOXAuthority::GetLevel()
582 OUString sText = GetFieldText(AUTH_FIELD_AUTHORITY_TYPE);
583 ToxAuthorityType nAuthorityKind = AUTH_TYPE_ARTICLE;
584 if (pIntl->IsNumeric(sText))
585 nAuthorityKind = static_cast<ToxAuthorityType>(sText.toUInt32());
586 if (nAuthorityKind > AUTH_TYPE_END)
587 nAuthorityKind = AUTH_TYPE_ARTICLE;
589 // Must be incremented by 1, since the pattern 0 is for the heading
590 const SwFormTokens& aPattern = pTOX->GetPattern(static_cast<int>(nAuthorityKind) + 1);
592 for (const auto& rToken : aPattern)
594 switch (rToken.eTokenType)
596 case TOKEN_TAB_STOP:
598 aText += "\t";
599 break;
601 case TOKEN_TEXT:
603 aText += rToken.sText;
604 break;
606 case TOKEN_AUTHORITY:
608 ToxAuthorityField eField = static_cast<ToxAuthorityField>(rToken.nAuthorityField);
610 if (AUTH_FIELD_IDENTIFIER == eField)
612 // Why isn't there a way to get the identifier without parentheses???
613 OUString sTmp = ExpandField(true, pLayout);
614 if (sal_Unicode cPref = pFieldType->GetPrefix(); cPref && cPref != ' ')
615 sTmp = sTmp.copy(1);
616 if (sal_Unicode cSuff = pFieldType->GetSuffix(); cSuff && cSuff != ' ')
617 sTmp = sTmp.copy(0, sTmp.getLength() - 1);
618 aText += sTmp;
620 else if (AUTH_FIELD_AUTHORITY_TYPE == eField)
622 aText += SwAuthorityFieldType::GetAuthTypeName(nAuthorityKind);
624 else if (AUTH_FIELD_URL == eField)
626 aText += GetRelativeURI();
628 else
630 aText += GetFieldText(eField);
632 break;
634 default:
635 break;
639 return aText;
642 SwAuthorityField::TargetType SwAuthorityField::GetTargetType() const
644 return SwAuthorityField::TargetType(GetAuthEntry()->GetAuthorField(AUTH_FIELD_TARGET_TYPE).toInt32());
647 OUString SwAuthorityField::GetAbsoluteURL() const
649 const OUString& rURL = GetAuthEntry()->GetAuthorField(
650 GetTargetType() == SwAuthorityField::TargetType::UseDisplayURL
651 ? AUTH_FIELD_URL : AUTH_FIELD_TARGET_URL);
652 SwDoc* pDoc = static_cast<SwAuthorityFieldType*>(GetTyp())->GetDoc();
653 SwDocShell* pDocShell = pDoc->GetDocShell();
654 if (!pDocShell)
655 return OUString();
656 OUString aBasePath = pDocShell->getDocumentBaseURL();
657 return INetURLObject::GetAbsURL(aBasePath, rURL, INetURLObject::EncodeMechanism::WasEncoded,
658 INetURLObject::DecodeMechanism::WithCharset);
661 OUString SwAuthorityField::GetRelativeURI() const
663 OUString sTmp = GetFieldText(AUTH_FIELD_URL);
665 SwDoc* pDoc = static_cast<SwAuthorityFieldType*>(GetTyp())->GetDoc();
666 SwDocShell* pDocShell = pDoc->GetDocShell();
667 if (!pDocShell)
668 return OUString();
669 const OUString aBaseURL = pDocShell->getDocumentBaseURL();
670 std::u16string_view aBaseURIScheme;
671 sal_Int32 nSep = aBaseURL.indexOf(':');
672 if (nSep != -1)
674 aBaseURIScheme = aBaseURL.subView(0, nSep);
677 uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
678 = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
679 uno::Reference<uri::XUriReference> xUriRef;
682 xUriRef = xUriReferenceFactory->parse(sTmp);
684 catch (const uno::Exception& rException)
686 SAL_WARN("sw.core",
687 "SwTOXAuthority::GetSourceURL: failed to parse url: " << rException.Message);
689 if (xUriRef.is() && xUriRef->getFragment().startsWith("page="))
691 xUriRef->clearFragment();
692 sTmp = xUriRef->getUriReference();
695 // convert to relative
696 bool bSaveRelFSys = officecfg::Office::Common::Save::URL::FileSystem::get();
697 if (xUriRef.is() && bSaveRelFSys && xUriRef->getScheme() == aBaseURIScheme)
699 sTmp = INetURLObject::GetRelURL(aBaseURL, sTmp);
701 return sTmp;
704 void SwAuthorityField::dumpAsXml(xmlTextWriterPtr pWriter) const
706 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthorityField"));
707 SwField::dumpAsXml(pWriter);
709 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_xAuthEntry"));
710 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", m_xAuthEntry.get());
711 if (m_xAuthEntry.is())
713 m_xAuthEntry->dumpAsXml(pWriter);
715 (void)xmlTextWriterEndElement(pWriter);
716 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_nTempSequencePos"));
717 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
718 BAD_CAST(OString::number(m_nTempSequencePos).getStr()));
719 (void)xmlTextWriterEndElement(pWriter);
720 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_nTempSequencePosRLHidden"));
721 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
722 BAD_CAST(OString::number(m_nTempSequencePosRLHidden).getStr()));
723 (void)xmlTextWriterEndElement(pWriter);
725 (void)xmlTextWriterEndElement(pWriter);
728 constexpr OUString aFieldNames[]
730 u"Identifier"_ustr,
731 u"BibiliographicType"_ustr,
732 u"Address"_ustr,
733 u"Annote"_ustr,
734 u"Author"_ustr,
735 u"Booktitle"_ustr,
736 u"Chapter"_ustr,
737 u"Edition"_ustr,
738 u"Editor"_ustr,
739 u"Howpublished"_ustr,
740 u"Institution"_ustr,
741 u"Journal"_ustr,
742 u"Month"_ustr,
743 u"Note"_ustr,
744 u"Number"_ustr,
745 u"Organizations"_ustr,
746 u"Pages"_ustr,
747 u"Publisher"_ustr,
748 u"School"_ustr,
749 u"Series"_ustr,
750 u"Title"_ustr,
751 u"Report_Type"_ustr,
752 u"Volume"_ustr,
753 u"Year"_ustr,
754 u"URL"_ustr,
755 u"Custom1"_ustr,
756 u"Custom2"_ustr,
757 u"Custom3"_ustr,
758 u"Custom4"_ustr,
759 u"Custom5"_ustr,
760 u"ISBN"_ustr,
761 u"LocalURL"_ustr,
762 u"TargetType"_ustr,
763 u"TargetURL"_ustr,
766 void SwAuthEntry::dumpAsXml(xmlTextWriterPtr pWriter) const
768 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthEntry"));
770 for (int i = 0; i < AUTH_FIELD_END; ++i)
772 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_aAuthField"));
773 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("key"), BAD_CAST(aFieldNames[i].toUtf8().getStr()));
774 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(m_aAuthFields[i].toUtf8().getStr()));
775 (void)xmlTextWriterEndElement(pWriter);
778 (void)xmlTextWriterEndElement(pWriter);
781 bool SwAuthorityField::QueryValue( Any& rAny, sal_uInt16 /*nWhichId*/ ) const
783 if(!GetTyp())
784 return false;
785 if(!m_xAuthEntry)
786 return false;
787 Sequence <PropertyValue> aRet(AUTH_FIELD_END);
788 PropertyValue* pValues = aRet.getArray();
789 for(int i = 0; i < AUTH_FIELD_END; ++i)
791 pValues[i].Name = aFieldNames[i];
792 const OUString& sField = m_xAuthEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
793 if(i == AUTH_FIELD_AUTHORITY_TYPE)
794 pValues[i].Value <<= sal_Int16(sField.toInt32());
795 else
796 pValues[i].Value <<= sField;
798 rAny <<= aRet;
799 /* FIXME: it is weird that we always return false here */
800 return false;
803 static sal_Int32 lcl_Find(std::u16string_view rFieldName)
805 for(sal_Int32 i = 0; i < AUTH_FIELD_END; ++i)
806 if(aFieldNames[i] == rFieldName)
807 return i;
808 return -1;
811 bool SwAuthorityField::PutValue( const Any& rAny, sal_uInt16 /*nWhichId*/ )
813 if(!GetTyp() || !m_xAuthEntry)
814 return false;
816 Sequence <PropertyValue> aParam;
817 if(!(rAny >>= aParam))
818 return false;
820 OUStringBuffer sBuf(+(AUTH_FIELD_END - 1));
821 comphelper::string::padToLength(sBuf, (AUTH_FIELD_END - 1), TOX_STYLE_DELIMITER);
822 OUString sToSet(sBuf.makeStringAndClear());
823 for (const PropertyValue& rParam : aParam)
825 const sal_Int32 nFound = lcl_Find(rParam.Name);
826 if(nFound >= 0)
828 OUString sContent;
829 if(AUTH_FIELD_AUTHORITY_TYPE == nFound)
831 sal_Int16 nVal = 0;
832 rParam.Value >>= nVal;
833 sContent = OUString::number(nVal);
835 else
836 rParam.Value >>= sContent;
837 sToSet = comphelper::string::setToken(sToSet, nFound, TOX_STYLE_DELIMITER, sContent);
841 static_cast<SwAuthorityFieldType*>(GetTyp())->RemoveField(m_xAuthEntry.get());
842 m_xAuthEntry = static_cast<SwAuthorityFieldType*>(GetTyp())->AddField(sToSet);
844 /* FIXME: it is weird that we always return false here */
845 return false;
848 SwFieldType* SwAuthorityField::ChgTyp( SwFieldType* pFieldTyp )
850 SwAuthorityFieldType* pSrcTyp = static_cast<SwAuthorityFieldType*>(GetTyp()),
851 * pDstTyp = static_cast<SwAuthorityFieldType*>(pFieldTyp);
852 if( pSrcTyp != pDstTyp )
854 const SwAuthEntry* pSrcEntry = m_xAuthEntry.get();
855 m_xAuthEntry = pDstTyp->AppendField( *pSrcEntry );
856 pSrcTyp->RemoveField( pSrcEntry );
857 SwField::ChgTyp( pFieldTyp );
859 return pSrcTyp;
862 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */