1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <config_features.h>
21 #include <config_fuzzers.h>
23 #include <textapi.hxx>
25 #include <hintids.hxx>
26 #include <com/sun/star/frame/XModel.hpp>
27 #include <com/sun/star/text/XText.hpp>
28 #include <com/sun/star/script/Converter.hpp>
29 #include <com/sun/star/text/PlaceholderType.hpp>
30 #include <com/sun/star/text/TemplateDisplayFormat.hpp>
31 #include <com/sun/star/text/PageNumberType.hpp>
32 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
33 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
34 #include <com/sun/star/document/XDocumentProperties.hpp>
35 #include <com/sun/star/util/Date.hpp>
36 #include <com/sun/star/util/Duration.hpp>
37 #include <o3tl/any.hxx>
38 #include <o3tl/string_view.hxx>
39 #include <unotools/localedatawrapper.hxx>
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/string.hxx>
42 #include <tools/urlobj.hxx>
43 #include <svl/numformat.hxx>
44 #include <svl/urihelper.hxx>
45 #include <unotools/useroptions.hxx>
46 #include <unotools/syslocale.hxx>
47 #include <libxml/xmlstring.h>
48 #include <libxml/xmlwriter.h>
50 #include <tools/time.hxx>
51 #include <tools/datetime.hxx>
53 #include <com/sun/star/util/DateTime.hpp>
55 #include <swmodule.hxx>
56 #include <sfx2/docfile.hxx>
57 #include <sfx2/doctempl.hxx>
60 #include <charfmt.hxx>
61 #include <docstat.hxx>
62 #include <pagedesc.hxx>
63 #include <fmtpdsc.hxx>
65 #include <IDocumentFieldsAccess.hxx>
66 #include <IDocumentStatistics.hxx>
67 #include <IDocumentStylePoolAccess.hxx>
68 #include <IDocumentLayoutAccess.hxx>
69 #include <rootfrm.hxx>
70 #include <pagefrm.hxx>
76 #include <shellres.hxx>
77 #include <docufld.hxx>
82 #include <poolfmt.hxx>
84 #include <unofldmid.h>
85 #include <swunohelper.hxx>
86 #include <strings.hrc>
88 #include <editeng/outlobj.hxx>
92 #define URL_DECODE INetURLObject::DecodeMechanism::Unambiguous
94 using namespace ::com::sun::star
;
95 using namespace ::com::sun::star::uno
;
96 using namespace nsSwDocInfoSubType
;
98 SwPageNumberFieldType::SwPageNumberFieldType()
99 : SwFieldType( SwFieldIds::PageNumber
),
100 m_nNumberingType( SVX_NUM_ARABIC
),
105 OUString
SwPageNumberFieldType::Expand( SvxNumType nFormat
, short nOff
,
106 sal_uInt16
const nPageNumber
, sal_uInt16
const nMaxPage
,
107 const OUString
& rUserStr
, LanguageType nLang
) const
109 SvxNumType nTmpFormat
= (SVX_NUM_PAGEDESC
== nFormat
) ? m_nNumberingType
: nFormat
;
110 int const nTmp
= nPageNumber
+ nOff
;
112 if (0 > nTmp
|| SVX_NUM_NUMBER_NONE
== nTmpFormat
|| (!m_bVirtual
&& nTmp
> nMaxPage
))
115 if( SVX_NUM_CHAR_SPECIAL
== nTmpFormat
)
118 return FormatNumber( nTmp
, nTmpFormat
, nLang
);
121 std::unique_ptr
<SwFieldType
> SwPageNumberFieldType::Copy() const
123 std::unique_ptr
<SwPageNumberFieldType
> pTmp(new SwPageNumberFieldType());
125 pTmp
->m_nNumberingType
= m_nNumberingType
;
126 pTmp
->m_bVirtual
= m_bVirtual
;
131 void SwPageNumberFieldType::ChangeExpansion( SwDoc
* pDoc
,
133 const SvxNumType
* pNumFormat
)
136 m_nNumberingType
= *pNumFormat
;
139 if (!(bVirt
&& pDoc
))
142 // check the flag since the layout NEVER sets it back
143 for (SwRootFrame
* pRootFrame
: pDoc
->GetAllLayouts())
145 const SwPageFrame
* pPageFrameIter
= pRootFrame
->GetLastPage();
146 while (pPageFrameIter
)
148 const SwContentFrame
* pContentFrame
= pPageFrameIter
->FindFirstBodyContent();
151 const SwFormatPageDesc
& rFormatPageDesc
= pContentFrame
->GetPageDescItem();
152 if ( rFormatPageDesc
.GetNumOffset() && rFormatPageDesc
.GetDefinedIn() )
154 const SwContentNode
* pNd
= dynamic_cast<const SwContentNode
*>( rFormatPageDesc
.GetDefinedIn() );
157 if (SwIterator
<SwFrame
, SwContentNode
, sw::IteratorMode::UnwrapMulti
>(*pNd
).First())
158 // sw_redlinehide: not sure if this should happen only if
159 // it's the first node, because that's where RES_PAGEDESC
163 else if( dynamic_cast< const SwFormat
* >(rFormatPageDesc
.GetDefinedIn()) != nullptr)
166 sw::AutoFormatUsedHint
aHint(m_bVirtual
, pDoc
->GetNodes());
167 rFormatPageDesc
.GetDefinedIn()->CallSwClientNotify(aHint
);
172 pPageFrameIter
= static_cast<const SwPageFrame
*>(pPageFrameIter
->GetPrev());
177 SwPageNumberField::SwPageNumberField(SwPageNumberFieldType
* pTyp
,
178 sal_uInt16 nSub
, sal_uInt32 nFormat
, short nOff
,
179 sal_uInt16
const nPageNumber
, sal_uInt16
const nMaxPage
)
180 : SwField(pTyp
, nFormat
), m_nSubType(nSub
), m_nOffset(nOff
)
181 , m_nPageNumber(nPageNumber
)
182 , m_nMaxPage(nMaxPage
)
186 void SwPageNumberField::ChangeExpansion(sal_uInt16
const nPageNumber
,
187 sal_uInt16
const nMaxPage
)
189 m_nPageNumber
= nPageNumber
;
190 m_nMaxPage
= nMaxPage
;
193 OUString
SwPageNumberField::ExpandImpl(SwRootFrame
const*const) const
196 SwPageNumberFieldType
* pFieldType
= static_cast<SwPageNumberFieldType
*>(GetTyp());
198 if( PG_NEXT
== m_nSubType
&& 1 != m_nOffset
)
200 sRet
= pFieldType
->Expand(static_cast<SvxNumType
>(GetFormat()), 1, m_nPageNumber
, m_nMaxPage
, m_sUserStr
, GetLanguage());
203 sRet
= pFieldType
->Expand(static_cast<SvxNumType
>(GetFormat()), m_nOffset
, m_nPageNumber
, m_nMaxPage
, m_sUserStr
, GetLanguage());
206 else if( PG_PREV
== m_nSubType
&& -1 != m_nOffset
)
208 sRet
= pFieldType
->Expand(static_cast<SvxNumType
>(GetFormat()), -1, m_nPageNumber
, m_nMaxPage
, m_sUserStr
, GetLanguage());
211 sRet
= pFieldType
->Expand(static_cast<SvxNumType
>(GetFormat()), m_nOffset
, m_nPageNumber
, m_nMaxPage
, m_sUserStr
, GetLanguage());
215 sRet
= pFieldType
->Expand(static_cast<SvxNumType
>(GetFormat()), m_nOffset
, m_nPageNumber
, m_nMaxPage
, m_sUserStr
, GetLanguage());
219 std::unique_ptr
<SwField
> SwPageNumberField::Copy() const
221 std::unique_ptr
<SwPageNumberField
> pTmp(new SwPageNumberField(
222 static_cast<SwPageNumberFieldType
*>(GetTyp()), m_nSubType
,
223 GetFormat(), m_nOffset
, m_nPageNumber
, m_nMaxPage
));
224 pTmp
->SetLanguage( GetLanguage() );
225 pTmp
->SetUserString( m_sUserStr
);
226 return std::unique_ptr
<SwField
>(pTmp
.release());
229 OUString
SwPageNumberField::GetPar2() const
231 return OUString::number(m_nOffset
);
234 void SwPageNumberField::SetPar2(const OUString
& rStr
)
236 m_nOffset
= static_cast<short>(rStr
.toInt32());
239 sal_uInt16
SwPageNumberField::GetSubType() const
244 bool SwPageNumberField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
248 case FIELD_PROP_FORMAT
:
249 rAny
<<= static_cast<sal_Int16
>(GetFormat());
251 case FIELD_PROP_USHORT1
:
254 case FIELD_PROP_SUBTYPE
:
256 text::PageNumberType eType
;
257 eType
= text::PageNumberType_CURRENT
;
258 if(m_nSubType
== PG_PREV
)
259 eType
= text::PageNumberType_PREV
;
260 else if(m_nSubType
== PG_NEXT
)
261 eType
= text::PageNumberType_NEXT
;
265 case FIELD_PROP_PAR1
:
275 bool SwPageNumberField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
281 case FIELD_PROP_FORMAT
:
284 // TODO: where do the defines come from?
285 if(nSet
<= SVX_NUM_PAGEDESC
)
288 case FIELD_PROP_USHORT1
:
292 case FIELD_PROP_SUBTYPE
:
293 switch( static_cast<text::PageNumberType
>(SWUnoHelper::GetEnumAsInt32( rAny
)) )
295 case text::PageNumberType_CURRENT
:
296 m_nSubType
= PG_RANDOM
;
298 case text::PageNumberType_PREV
:
299 m_nSubType
= PG_PREV
;
301 case text::PageNumberType_NEXT
:
302 m_nSubType
= PG_NEXT
;
308 case FIELD_PROP_PAR1
:
318 SwAuthorFieldType::SwAuthorFieldType()
319 : SwFieldType( SwFieldIds::Author
)
323 OUString
SwAuthorFieldType::Expand(sal_uLong nFormat
)
325 SwModule
* mod
= SwModule::get();
326 SvtUserOptions
& rOpt
= mod
->GetUserOptions();
327 if((nFormat
& 0xff) == AF_NAME
)
329 // Prefer the view's redline author name.
330 // (set in SwXTextDocument::initializeForTiledRendering)
331 std::size_t nAuthor
= mod
->GetRedlineAuthor();
332 OUString sAuthor
= mod
->GetRedlineAuthor(nAuthor
);
333 if (sAuthor
.isEmpty())
334 return rOpt
.GetFullName();
342 std::unique_ptr
<SwFieldType
> SwAuthorFieldType::Copy() const
344 return std::make_unique
<SwAuthorFieldType
>();
347 SwAuthorField::SwAuthorField(SwAuthorFieldType
* pTyp
, sal_uInt32 nFormat
)
348 : SwField(pTyp
, nFormat
)
350 m_aContent
= SwAuthorFieldType::Expand(GetFormat());
353 OUString
SwAuthorField::ExpandImpl(SwRootFrame
const*const) const
356 const_cast<SwAuthorField
*>(this)->m_aContent
=
357 SwAuthorFieldType::Expand(GetFormat());
362 std::unique_ptr
<SwField
> SwAuthorField::Copy() const
364 std::unique_ptr
<SwAuthorField
> pTmp(new SwAuthorField( static_cast<SwAuthorFieldType
*>(GetTyp()),
366 pTmp
->SetExpansion(m_aContent
);
367 return std::unique_ptr
<SwField
>(pTmp
.release());
370 bool SwAuthorField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
374 case FIELD_PROP_BOOL1
:
375 rAny
<<= (GetFormat() & 0xff) == AF_NAME
;
378 case FIELD_PROP_BOOL2
:
382 case FIELD_PROP_PAR1
:
386 case FIELD_PROP_TITLE
:
395 bool SwAuthorField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
399 case FIELD_PROP_BOOL1
:
400 SetFormat( *o3tl::doAccess
<bool>(rAny
) ? AF_NAME
: AF_SHORTCUT
);
403 case FIELD_PROP_BOOL2
:
404 if( *o3tl::doAccess
<bool>(rAny
) )
405 SetFormat( GetFormat() | AF_FIXED
);
407 SetFormat( GetFormat() & ~AF_FIXED
);
410 case FIELD_PROP_PAR1
:
414 case FIELD_PROP_TITLE
:
423 SwFileNameFieldType::SwFileNameFieldType(SwDoc
& rDocument
)
424 : SwFieldType( SwFieldIds::Filename
)
429 OUString
SwFileNameFieldType::Expand(sal_uLong nFormat
) const
432 const SwDocShell
* pDShell
= m_rDoc
.GetDocShell();
433 if( pDShell
&& pDShell
->HasName() )
435 const INetURLObject
& rURLObj
= pDShell
->GetMedium()->GetURLObject();
436 switch( nFormat
& ~FF_FIXED
)
440 if( INetProtocol::File
== rURLObj
.GetProtocol() )
442 INetURLObject
aTemp(rURLObj
);
443 aTemp
.removeSegment();
444 // last slash should belong to the pathname
445 aRet
= aTemp
.PathToFileName();
449 aRet
= URIHelper::removePassword(
450 rURLObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
451 INetURLObject::EncodeMechanism::WasEncoded
, URL_DECODE
);
452 const sal_Int32 nPos
= aRet
.indexOf(rURLObj
.GetLastName( URL_DECODE
));
455 aRet
= aRet
.copy(0, nPos
);
462 aRet
= rURLObj
.GetLastName( INetURLObject::DecodeMechanism::WithCharset
);
466 aRet
= rURLObj
.GetBase();
470 if( INetProtocol::File
== rURLObj
.GetProtocol() )
471 aRet
= rURLObj
.GetFull();
473 aRet
= URIHelper::removePassword(
474 rURLObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
475 INetURLObject::EncodeMechanism::WasEncoded
, URL_DECODE
);
481 std::unique_ptr
<SwFieldType
> SwFileNameFieldType::Copy() const
483 return std::make_unique
<SwFileNameFieldType
>(m_rDoc
);
486 SwFileNameField::SwFileNameField(SwFileNameFieldType
* pTyp
, sal_uInt32 nFormat
)
487 : SwField(pTyp
, nFormat
)
489 m_aContent
= static_cast<SwFileNameFieldType
*>(GetTyp())->Expand(GetFormat());
492 OUString
SwFileNameField::ExpandImpl(SwRootFrame
const*const) const
495 const_cast<SwFileNameField
*>(this)->m_aContent
= static_cast<SwFileNameFieldType
*>(GetTyp())->Expand(GetFormat());
500 std::unique_ptr
<SwField
> SwFileNameField::Copy() const
502 std::unique_ptr
<SwFileNameField
> pTmp(
503 new SwFileNameField(static_cast<SwFileNameFieldType
*>(GetTyp()), GetFormat()));
504 pTmp
->SetExpansion(m_aContent
);
506 return std::unique_ptr
<SwField
>(pTmp
.release());
509 bool SwFileNameField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
513 case FIELD_PROP_FORMAT
:
516 switch( GetFormat() &(~FF_FIXED
) )
519 nRet
= text::FilenameDisplayFormat::PATH
;
522 nRet
= text::FilenameDisplayFormat::NAME
;
525 nRet
= text::FilenameDisplayFormat::NAME_AND_EXT
;
527 default: nRet
= text::FilenameDisplayFormat::FULL
;
533 case FIELD_PROP_BOOL2
:
537 case FIELD_PROP_PAR3
:
547 bool SwFileNameField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
551 case FIELD_PROP_FORMAT
:
553 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
554 // called with a int32 value! But normally we need
558 bool bFixed
= IsFixed();
561 case text::FilenameDisplayFormat::PATH
:
564 case text::FilenameDisplayFormat::NAME
:
565 nType
= FF_NAME_NOEXT
;
567 case text::FilenameDisplayFormat::NAME_AND_EXT
:
570 default: nType
= FF_PATHNAME
;
578 case FIELD_PROP_BOOL2
:
579 if( *o3tl::doAccess
<bool>(rAny
) )
580 SetFormat( GetFormat() | FF_FIXED
);
582 SetFormat( GetFormat() & ~FF_FIXED
);
585 case FIELD_PROP_PAR3
:
595 SwTemplNameFieldType::SwTemplNameFieldType(SwDoc
& rDocument
)
596 : SwFieldType( SwFieldIds::TemplateName
)
601 OUString
SwTemplNameFieldType::Expand(sal_uLong nFormat
) const
603 OSL_ENSURE( nFormat
< FF_END
, "Expand: no valid Format!" );
606 SwDocShell
*pDocShell(m_rDoc
.GetDocShell());
607 OSL_ENSURE(pDocShell
, "no SwDocShell");
609 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
610 pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
611 uno::Reference
<document::XDocumentProperties
> xDocProps(
612 xDPS
->getDocumentProperties());
613 OSL_ENSURE(xDocProps
.is(), "Doc has no DocumentProperties");
615 if( FF_UI_NAME
== nFormat
)
616 aRet
= xDocProps
->getTemplateName();
617 else if( !xDocProps
->getTemplateURL().isEmpty() )
619 if( FF_UI_RANGE
== nFormat
)
621 // for getting region names!
622 SfxDocumentTemplates aFac
;
625 aFac
.GetLogicNames( xDocProps
->getTemplateURL(), sRegion
, sTmp
);
630 INetURLObject
aPathName( xDocProps
->getTemplateURL() );
631 if( FF_NAME
== nFormat
)
632 aRet
= aPathName
.GetLastName(URL_DECODE
);
633 else if( FF_NAME_NOEXT
== nFormat
)
634 aRet
= aPathName
.GetBase();
637 if( FF_PATH
== nFormat
)
639 aPathName
.removeSegment();
640 aRet
= aPathName
.GetFull();
643 aRet
= aPathName
.GetFull();
651 std::unique_ptr
<SwFieldType
> SwTemplNameFieldType::Copy() const
653 return std::make_unique
<SwTemplNameFieldType
>(m_rDoc
);
656 SwTemplNameField::SwTemplNameField(SwTemplNameFieldType
* pTyp
, sal_uInt32 nFormat
)
657 : SwField(pTyp
, nFormat
)
660 OUString
SwTemplNameField::ExpandImpl(SwRootFrame
const*const) const
662 return static_cast<SwTemplNameFieldType
*>(GetTyp())->Expand(GetFormat());
665 std::unique_ptr
<SwField
> SwTemplNameField::Copy() const
667 return std::make_unique
<SwTemplNameField
>(static_cast<SwTemplNameFieldType
*>(GetTyp()), GetFormat());
670 bool SwTemplNameField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
674 case FIELD_PROP_FORMAT
:
677 switch( GetFormat() )
679 case FF_PATH
: nRet
= text::FilenameDisplayFormat::PATH
; break;
680 case FF_NAME_NOEXT
: nRet
= text::FilenameDisplayFormat::NAME
; break;
681 case FF_NAME
: nRet
= text::FilenameDisplayFormat::NAME_AND_EXT
; break;
682 case FF_UI_RANGE
: nRet
= text::TemplateDisplayFormat::AREA
; break;
683 case FF_UI_NAME
: nRet
= text::TemplateDisplayFormat::TITLE
; break;
684 default: nRet
= text::FilenameDisplayFormat::FULL
;
697 bool SwTemplNameField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
701 case FIELD_PROP_FORMAT
:
703 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
704 // called with a int32 value! But normally we need
710 case text::FilenameDisplayFormat::PATH
:
713 case text::FilenameDisplayFormat::NAME
:
714 SetFormat(FF_NAME_NOEXT
);
716 case text::FilenameDisplayFormat::NAME_AND_EXT
:
719 case text::TemplateDisplayFormat::AREA
:
720 SetFormat(FF_UI_RANGE
);
722 case text::TemplateDisplayFormat::TITLE
:
723 SetFormat(FF_UI_NAME
);
725 default: SetFormat(FF_PATHNAME
);
736 SwDocStatFieldType::SwDocStatFieldType(SwDoc
& rDocument
)
737 : SwFieldType(SwFieldIds::DocStat
)
739 , m_nNumberingType(SVX_NUM_ARABIC
)
743 OUString
SwDocStatFieldType::Expand(sal_uInt16 nSubType
, SvxNumType nFormat
) const
746 const SwDocStat
& rDStat
= m_rDoc
.getIDocumentStatistics().GetDocStat();
749 case DS_TBL
: nVal
= rDStat
.nTable
; break;
750 case DS_GRF
: nVal
= rDStat
.nGrf
; break;
751 case DS_OLE
: nVal
= rDStat
.nOLE
; break;
752 case DS_PARA
: nVal
= rDStat
.nPara
; break;
753 case DS_WORD
: nVal
= rDStat
.nWord
; break;
754 case DS_CHAR
: nVal
= rDStat
.nChar
; break;
756 if( m_rDoc
.getIDocumentLayoutAccess().GetCurrentLayout() )
757 const_cast<SwDocStat
&>(rDStat
).nPage
= m_rDoc
.getIDocumentLayoutAccess().GetCurrentLayout()->GetPageNum();
759 if( SVX_NUM_PAGEDESC
== nFormat
)
760 nFormat
= m_nNumberingType
;
763 OSL_FAIL( "SwDocStatFieldType::Expand: unknown SubType" );
766 if( nVal
<= SHRT_MAX
)
767 return FormatNumber( nVal
, nFormat
);
769 return OUString::number( nVal
);
772 std::unique_ptr
<SwFieldType
> SwDocStatFieldType::Copy() const
774 return std::make_unique
<SwDocStatFieldType
>(m_rDoc
);
779 * @param nSub SubType
782 SwDocStatField::SwDocStatField(SwDocStatFieldType
* pTyp
, sal_uInt16 nSub
, sal_uInt32 nFormat
)
783 : SwField(pTyp
, nFormat
),
787 OUString
SwDocStatField::ExpandImpl(SwRootFrame
const*const) const
789 return static_cast<SwDocStatFieldType
*>(GetTyp())->Expand(m_nSubType
, static_cast<SvxNumType
>(GetFormat()));
792 std::unique_ptr
<SwField
> SwDocStatField::Copy() const
794 return std::make_unique
<SwDocStatField
>(
795 static_cast<SwDocStatFieldType
*>(GetTyp()), m_nSubType
, GetFormat() );
798 sal_uInt16
SwDocStatField::GetSubType() const
803 void SwDocStatField::SetSubType(sal_uInt16 nSub
)
808 void SwDocStatField::ChangeExpansion( const SwFrame
* pFrame
)
810 if( DS_PAGE
== m_nSubType
&& SVX_NUM_PAGEDESC
== GetFormat() )
811 static_cast<SwDocStatFieldType
*>(GetTyp())->SetNumFormat(
812 pFrame
->FindPageFrame()->GetPageDesc()->GetNumType().GetNumberingType() );
815 bool SwDocStatField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
819 case FIELD_PROP_USHORT2
:
820 rAny
<<= static_cast<sal_Int16
>(GetFormat());
829 bool SwDocStatField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
834 case FIELD_PROP_USHORT2
:
838 if(nSet
<= SVX_NUM_CHARS_LOWER_LETTER_N
&&
839 nSet
!= SVX_NUM_CHAR_SPECIAL
&&
840 nSet
!= SVX_NUM_BITMAP
)
854 // Document info field type
856 SwDocInfoFieldType::SwDocInfoFieldType(SwDoc
* pDc
)
857 : SwValueFieldType( pDc
, SwFieldIds::DocInfo
)
861 std::unique_ptr
<SwFieldType
> SwDocInfoFieldType::Copy() const
863 return std::make_unique
<SwDocInfoFieldType
>(GetDoc());
866 static void lcl_GetLocalDataWrapper( LanguageType nLang
,
867 const LocaleDataWrapper
**ppAppLocalData
,
868 const LocaleDataWrapper
**ppLocalData
)
870 SvtSysLocale aLocale
;
871 *ppAppLocalData
= &aLocale
.GetLocaleData();
872 *ppLocalData
= *ppAppLocalData
;
873 if( nLang
!= (*ppLocalData
)->getLanguageTag().getLanguageType() )
874 *ppLocalData
= new LocaleDataWrapper(LanguageTag( nLang
));
877 OUString
SwDocInfoFieldType::Expand( sal_uInt16 nSub
, sal_uInt32 nFormat
,
878 LanguageType nLang
, const OUString
& rName
) const
880 const LocaleDataWrapper
*pAppLocalData
= nullptr, *pLocalData
= nullptr;
881 SwDocShell
*pDocShell(GetDoc()->GetDocShell());
882 OSL_ENSURE(pDocShell
, "no SwDocShell");
883 if (!pDocShell
) { return OUString(); }
885 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
886 pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
887 uno::Reference
<document::XDocumentProperties
> xDocProps(
888 xDPS
->getDocumentProperties());
889 OSL_ENSURE(xDocProps
.is(), "Doc has no DocumentProperties");
891 sal_uInt16 nExtSub
= nSub
& 0xff00;
892 nSub
&= 0xff; // do not consider extended SubTypes
897 case DI_TITLE
: aStr
= xDocProps
->getTitle(); break;
898 case DI_SUBJECT
:aStr
= xDocProps
->getSubject(); break;
899 case DI_KEYS
: aStr
= ::comphelper::string::convertCommaSeparated(
900 xDocProps
->getKeywords());
902 case DI_COMMENT
:aStr
= xDocProps
->getDescription(); break;
903 case DI_DOCNO
: aStr
= OUString::number(
904 xDocProps
->getEditingCycles() );
909 lcl_GetLocalDataWrapper( nLang
, &pAppLocalData
, &pLocalData
);
910 sal_Int32 dur
= xDocProps
->getEditingDuration();
911 // If Seconds > 0 then bSec should be TRUE otherwise Seconds
912 // information will be lost if file has EditTime in Seconds format.
913 aStr
= pLocalData
->getTime( tools::Time(dur
/3600, (dur
%3600)/60, dur
%60),
918 sal_Int32 dur
= xDocProps
->getEditingDuration();
919 double fVal
= tools::Time(dur
/3600, (dur
%3600)/60, dur
%60).GetTimeInDays();
920 aStr
= ExpandValue(fVal
, nFormat
, nLang
);
929 uno::Reference
< beans::XPropertySet
> xSet(
930 xDocProps
->getUserDefinedProperties(),
931 uno::UNO_QUERY_THROW
);
932 aAny
= xSet
->getPropertyValue( rName
);
934 uno::Reference
< script::XTypeConverter
> xConverter( script::Converter::create(comphelper::getProcessComponentContext()) );
935 uno::Any aNew
= xConverter
->convertToSimpleType( aAny
, uno::TypeClass_STRING
);
938 catch (uno::Exception
&) {}
944 OUString
aName( xDocProps
->getAuthor() );
945 util::DateTime
uDT( xDocProps
->getCreationDate() );
947 if( nSub
== DI_CREATE
)
949 else if( nSub
== DI_CHANGE
)
951 aName
= xDocProps
->getModifiedBy();
952 uDT
= xDocProps
->getModificationDate();
953 aDate
= DateTime(uDT
);
955 else if( nSub
== DI_PRINT
)
957 aName
= xDocProps
->getPrintedBy();
958 if ( !std::getenv("STABLE_FIELDS_HACK") )
960 uDT
= xDocProps
->getPrintDate();
961 aDate
= DateTime(uDT
);
967 if (aDate
.IsValidAndGregorian())
969 switch (nExtSub
& ~DI_SUB_FIXED
)
978 lcl_GetLocalDataWrapper( nLang
, &pAppLocalData
,
980 aStr
= pLocalData
->getTime( aDate
,
985 // start the number formatter
986 double fVal
= SwDateTimeField::GetDateTime( *GetDoc(),
988 aStr
= ExpandValue(fVal
, nFormat
, nLang
);
995 lcl_GetLocalDataWrapper( nLang
, &pAppLocalData
,
997 aStr
= pLocalData
->getDate( aDate
);
1001 // start the number formatter
1002 double fVal
= SwDateTimeField::GetDateTime( *GetDoc(),
1004 aStr
= ExpandValue(fVal
, nFormat
, nLang
);
1013 if( pAppLocalData
!= pLocalData
)
1019 // document info field
1021 SwDocInfoField::SwDocInfoField(SwDocInfoFieldType
* pTyp
, sal_uInt16 nSub
, const OUString
& rName
, sal_uInt32 nFormat
) :
1022 SwValueField(pTyp
, nFormat
), m_nSubType(nSub
)
1025 m_aContent
= static_cast<SwDocInfoFieldType
*>(GetTyp())->Expand(m_nSubType
, nFormat
, GetLanguage(), m_aName
);
1028 SwDocInfoField::SwDocInfoField(SwDocInfoFieldType
* pTyp
, sal_uInt16 nSub
, const OUString
& rName
, const OUString
& rValue
, sal_uInt32 nFormat
) :
1029 SwValueField(pTyp
, nFormat
), m_nSubType(nSub
)
1032 m_aContent
= rValue
;
1036 static double lcl_TimeToDouble( const T
& rTime
)
1038 const double fNanoSecondsPerDay
= 86400000000000.0;
1039 return ( (rTime
.Hours
* SAL_CONST_INT64(3600000000000))
1040 + (rTime
.Minutes
* SAL_CONST_INT64( 60000000000))
1041 + (rTime
.Seconds
* SAL_CONST_INT64( 1000000000))
1042 + (rTime
.NanoSeconds
))
1043 / fNanoSecondsPerDay
;
1047 static double lcl_DateToDouble( const D
& rDate
, const Date
& rNullDate
)
1049 tools::Long nDate
= Date::DateToDays( rDate
.Day
, rDate
.Month
, rDate
.Year
);
1050 tools::Long nNullDate
= Date::DateToDays( rNullDate
.GetDay(), rNullDate
.GetMonth(), rNullDate
.GetYear() );
1051 return double( nDate
- nNullDate
);
1054 OUString
SwDocInfoField::ExpandImpl(SwRootFrame
const*const) const
1056 if ( ( m_nSubType
& 0xFF ) == DI_CUSTOM
)
1058 // custom properties currently need special treatment
1059 // We don't have a secure way to detect "real" custom properties in Word import of text
1060 // fields, so we treat *every* unknown property as a custom property, even the "built-in"
1061 // section in Word's document summary information stream as these properties have not been
1062 // inserted when the document summary information was imported, we do it here.
1063 // This approach is still a lot better than the old one to import such fields as
1064 // "user fields" and simple text
1065 SwDocShell
* pDocShell
= GetDoc()->GetDocShell();
1070 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
1071 uno::Reference
<document::XDocumentProperties
> xDocProps( xDPS
->getDocumentProperties());
1072 uno::Reference
< beans::XPropertySet
> xSet( xDocProps
->getUserDefinedProperties(), uno::UNO_QUERY_THROW
);
1073 uno::Reference
< beans::XPropertySetInfo
> xSetInfo
= xSet
->getPropertySetInfo();
1076 if( xSetInfo
->hasPropertyByName( m_aName
) )
1077 aAny
= xSet
->getPropertyValue( m_aName
);
1078 if ( aAny
.getValueType() != cppu::UnoType
<void>::get() )
1080 // "void" type means that the property has not been inserted until now
1083 // if the field is "fixed" we don't update it from the property
1085 uno::Reference
< script::XTypeConverter
> xConverter( script::Converter::create(comphelper::getProcessComponentContext()) );
1087 util::DateTime aDateTime
;
1088 util::Duration aDuration
;
1091 SvNumberFormatter
* pFormatter
= pDocShell
->GetDoc()->GetNumberFormatter();
1092 const Date
& rNullDate
= pFormatter
->GetNullDate();
1093 sVal
= ExpandValue( lcl_DateToDouble
<util::Date
>( aDate
, rNullDate
), GetFormat(), GetLanguage());
1095 else if( aAny
>>= aDateTime
)
1097 double fDateTime
= lcl_TimeToDouble
<util::DateTime
>( aDateTime
);
1098 SvNumberFormatter
* pFormatter
= pDocShell
->GetDoc()->GetNumberFormatter();
1099 const Date
& rNullDate
= pFormatter
->GetNullDate();
1100 fDateTime
+= lcl_DateToDouble
<util::DateTime
>( aDateTime
, rNullDate
);
1101 sVal
= ExpandValue( fDateTime
, GetFormat(), GetLanguage());
1103 else if( aAny
>>= aDuration
)
1105 sVal
= OUStringChar(aDuration
.Negative
? '-' : '+')
1106 + SwViewShell::GetShellRes()->sDurationFormat
;
1107 sVal
= sVal
.replaceFirst("%1", OUString::number( aDuration
.Years
) );
1108 sVal
= sVal
.replaceFirst("%2", OUString::number( aDuration
.Months
) );
1109 sVal
= sVal
.replaceFirst("%3", OUString::number( aDuration
.Days
) );
1110 sVal
= sVal
.replaceFirst("%4", OUString::number( aDuration
.Hours
) );
1111 sVal
= sVal
.replaceFirst("%5", OUString::number( aDuration
.Minutes
) );
1112 sVal
= sVal
.replaceFirst("%6", OUString::number( aDuration
.Seconds
) );
1116 uno::Any aNew
= xConverter
->convertToSimpleType( aAny
, uno::TypeClass_STRING
);
1119 const_cast<SwDocInfoField
*>(this)->m_aContent
= sVal
;
1123 catch (uno::Exception
&) {}
1125 else if ( !IsFixed() )
1126 const_cast<SwDocInfoField
*>(this)->m_aContent
= static_cast<SwDocInfoFieldType
*>(GetTyp())->Expand(m_nSubType
, GetFormat(), GetLanguage(), m_aName
);
1131 OUString
SwDocInfoField::GetFieldName() const
1133 OUString
aStr(SwFieldType::GetTypeStr(GetTypeId()) + ":");
1135 sal_uInt16
const nSub
= m_nSubType
& 0xff;
1144 aStr
+= SwViewShell::GetShellRes()
1145 ->aDocInfoLst
[ nSub
- DI_SUBTYPE_BEGIN
];
1150 aStr
+= " " + SwViewShell::GetShellRes()->aFixedStr
;
1155 std::unique_ptr
<SwField
> SwDocInfoField::Copy() const
1157 std::unique_ptr
<SwDocInfoField
> pField(new SwDocInfoField(static_cast<SwDocInfoFieldType
*>(GetTyp()), m_nSubType
, m_aName
, GetFormat()));
1158 pField
->SetAutomaticLanguage(IsAutomaticLanguage());
1159 pField
->m_aContent
= m_aContent
;
1161 return std::unique_ptr
<SwField
>(pField
.release());
1164 sal_uInt16
SwDocInfoField::GetSubType() const
1169 void SwDocInfoField::SetSubType(sal_uInt16 nSub
)
1174 void SwDocInfoField::SetLanguage(LanguageType nLng
)
1177 SwField::SetLanguage(nLng
);
1179 SwValueField::SetLanguage(nLng
);
1182 bool SwDocInfoField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
1186 case FIELD_PROP_PAR1
:
1187 rAny
<<= m_aContent
;
1190 case FIELD_PROP_PAR4
:
1194 case FIELD_PROP_USHORT1
:
1195 rAny
<<= static_cast<sal_Int16
>(m_aContent
.toInt32());
1198 case FIELD_PROP_BOOL1
:
1199 rAny
<<= 0 != (m_nSubType
& DI_SUB_FIXED
);
1202 case FIELD_PROP_FORMAT
:
1203 rAny
<<= static_cast<sal_Int32
>(GetFormat());
1206 case FIELD_PROP_DOUBLE
:
1208 double fVal
= GetValue();
1212 case FIELD_PROP_PAR3
:
1213 rAny
<<= ExpandImpl(nullptr);
1215 case FIELD_PROP_BOOL2
:
1217 sal_uInt16 nExtSub
= (m_nSubType
& 0xff00) & ~DI_SUB_FIXED
;
1218 rAny
<<= nExtSub
== DI_SUB_DATE
;
1222 return SwField::QueryValue(rAny
, nWhichId
);
1227 bool SwDocInfoField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
1229 sal_Int32 nValue
= 0;
1232 case FIELD_PROP_PAR1
:
1233 if( m_nSubType
& DI_SUB_FIXED
)
1234 rAny
>>= m_aContent
;
1237 case FIELD_PROP_USHORT1
:
1238 if( m_nSubType
& DI_SUB_FIXED
)
1241 m_aContent
= OUString::number(nValue
);
1245 case FIELD_PROP_BOOL1
:
1246 if(*o3tl::doAccess
<bool>(rAny
))
1247 m_nSubType
|= DI_SUB_FIXED
;
1249 m_nSubType
&= ~DI_SUB_FIXED
;
1251 case FIELD_PROP_FORMAT
:
1259 case FIELD_PROP_PAR3
:
1260 rAny
>>= m_aContent
;
1262 case FIELD_PROP_BOOL2
:
1263 m_nSubType
&= 0xf0ff;
1264 if(*o3tl::doAccess
<bool>(rAny
))
1265 m_nSubType
|= DI_SUB_DATE
;
1267 m_nSubType
|= DI_SUB_TIME
;
1270 return SwField::PutValue(rAny
, nWhichId
);
1275 SwHiddenTextFieldType::SwHiddenTextFieldType( bool bSetHidden
)
1276 : SwFieldType( SwFieldIds::HiddenText
), m_bHidden( bSetHidden
)
1280 std::unique_ptr
<SwFieldType
> SwHiddenTextFieldType::Copy() const
1282 return std::make_unique
<SwHiddenTextFieldType
>( m_bHidden
);
1285 void SwHiddenTextFieldType::SetHiddenFlag( bool bSetHidden
)
1287 if( m_bHidden
!= bSetHidden
)
1289 m_bHidden
= bSetHidden
;
1290 UpdateFields(); // notify all HiddenTexts
1294 SwHiddenTextField::SwHiddenTextField( SwHiddenTextFieldType
* pFieldType
,
1297 const OUString
& rStr
,
1299 SwFieldTypesEnum nSub
) :
1300 SwField( pFieldType
), m_aCond(std::move(aCond
)), m_nSubType(nSub
),
1301 m_bCanToggle(bConditional
), m_bIsHidden(bHidden
), m_bValid(false)
1303 if(m_nSubType
== SwFieldTypesEnum::ConditionalText
)
1306 m_aTRUEText
= rStr
.getToken(0, '|', nPos
);
1310 m_aFALSEText
= rStr
.getToken(0, '|', nPos
);
1313 m_aContent
= rStr
.getToken(0, '|', nPos
);
1322 SwHiddenTextField::SwHiddenTextField( SwHiddenTextFieldType
* pFieldType
,
1326 SwFieldTypesEnum nSub
)
1327 : SwField( pFieldType
), m_aTRUEText(std::move(aTrue
)), m_aFALSEText(std::move(aFalse
)), m_aCond(std::move(aCond
)), m_nSubType(nSub
),
1328 m_bIsHidden(true), m_bValid(false)
1330 m_bCanToggle
= !m_aCond
.isEmpty();
1333 OUString
SwHiddenTextField::ExpandImpl(SwRootFrame
const*const) const
1335 // Type: !Hidden -> show always
1336 // Hide -> evaluate condition
1338 if( SwFieldTypesEnum::ConditionalText
== m_nSubType
)
1343 if( m_bCanToggle
&& !m_bIsHidden
)
1346 else if( !static_cast<SwHiddenTextFieldType
*>(GetTyp())->GetHiddenFlag() ||
1347 ( m_bCanToggle
&& m_bIsHidden
))
1350 return m_aFALSEText
;
1353 /// get current field value and cache it
1354 void SwHiddenTextField::Evaluate(SwDoc
& rDoc
)
1356 if( SwFieldTypesEnum::ConditionalText
!= m_nSubType
)
1359 #if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
1362 SwDBManager
* pMgr
= rDoc
.GetDBManager();
1365 OUString sTmpName
= (m_bCanToggle
&& !m_bIsHidden
) ? m_aTRUEText
: m_aFALSEText
;
1367 // Database expressions need to be different from normal text. Therefore, normal text is set
1368 // in quotes. If the latter exist they will be removed. If not, check if potential DB name.
1369 // Only if there are two or more dots and no quotes, we assume a database.
1370 if (sTmpName
.getLength()>1 &&
1371 sTmpName
.startsWith("\"") &&
1372 sTmpName
.endsWith("\""))
1374 m_aContent
= sTmpName
.copy(1, sTmpName
.getLength() - 2);
1377 else if(sTmpName
.indexOf('\"')<0 &&
1378 comphelper::string::getTokenCount(sTmpName
, '.') > 2)
1380 sTmpName
= ::ReplacePoint(sTmpName
);
1381 if(sTmpName
.startsWith("[") && sTmpName
.endsWith("]"))
1382 { // remove brackets
1383 sTmpName
= sTmpName
.copy(1, sTmpName
.getLength() - 2);
1385 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1388 sal_Int32 nIdx
{ 0 };
1389 OUString
sDBName( GetDBName( sTmpName
, rDoc
));
1390 OUString
sDataSource(sDBName
.getToken(0, DB_DELIM
, nIdx
));
1391 OUString
sDataTableOrQuery(sDBName
.getToken(0, DB_DELIM
, nIdx
));
1392 if( pMgr
->IsInMerge() && !sDBName
.isEmpty() &&
1393 pMgr
->IsDataSourceOpen( sDataSource
,
1394 sDataTableOrQuery
, false))
1397 pMgr
->GetMergeColumnCnt(GetColumnName( sTmpName
),
1398 GetLanguage(), m_aContent
, &fNumber
);
1406 OUString
SwHiddenTextField::GetFieldName() const
1408 OUString aStr
= SwFieldType::GetTypeStr(m_nSubType
) +
1409 " " + m_aCond
+ " " + m_aTRUEText
;
1411 if (m_nSubType
== SwFieldTypesEnum::ConditionalText
)
1413 aStr
+= " : " + m_aFALSEText
;
1418 std::unique_ptr
<SwField
> SwHiddenTextField::Copy() const
1420 std::unique_ptr
<SwHiddenTextField
> pField(
1421 new SwHiddenTextField(static_cast<SwHiddenTextFieldType
*>(GetTyp()), m_aCond
,
1422 m_aTRUEText
, m_aFALSEText
));
1423 pField
->m_bIsHidden
= m_bIsHidden
;
1424 pField
->m_bValid
= m_bValid
;
1425 pField
->m_aContent
= m_aContent
;
1426 pField
->SetFormat(GetFormat());
1427 pField
->m_nSubType
= m_nSubType
;
1428 return std::unique_ptr
<SwField
>(pField
.release());
1432 void SwHiddenTextField::SetPar1(const OUString
& rStr
)
1435 m_bCanToggle
= !m_aCond
.isEmpty();
1438 OUString
SwHiddenTextField::GetPar1() const
1443 /// set True/False text
1444 void SwHiddenTextField::SetPar2(const OUString
& rStr
)
1446 if (m_nSubType
== SwFieldTypesEnum::ConditionalText
)
1448 sal_Int32 nPos
= rStr
.indexOf('|');
1453 m_aTRUEText
= rStr
.copy(0, nPos
);
1454 m_aFALSEText
= rStr
.copy(nPos
+ 1);
1461 /// get True/False text
1462 OUString
SwHiddenTextField::GetPar2() const
1464 if(m_nSubType
!= SwFieldTypesEnum::ConditionalText
)
1468 return m_aTRUEText
+ "|" + m_aFALSEText
;
1471 sal_uInt16
SwHiddenTextField::GetSubType() const
1473 return static_cast<sal_uInt16
>(m_nSubType
);
1476 bool SwHiddenTextField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
1480 case FIELD_PROP_PAR1
:
1483 case FIELD_PROP_PAR2
:
1484 rAny
<<= m_aTRUEText
;
1486 case FIELD_PROP_PAR3
:
1487 rAny
<<= m_aFALSEText
;
1489 case FIELD_PROP_PAR4
:
1490 rAny
<<= m_aContent
;
1492 case FIELD_PROP_BOOL1
:
1493 rAny
<<= m_bIsHidden
;
1501 bool SwHiddenTextField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
1505 case FIELD_PROP_PAR1
:
1512 case FIELD_PROP_PAR2
:
1513 rAny
>>= m_aTRUEText
;
1515 case FIELD_PROP_PAR3
:
1516 rAny
>>= m_aFALSEText
;
1518 case FIELD_PROP_BOOL1
:
1519 m_bIsHidden
= *o3tl::doAccess
<bool>(rAny
);
1521 case FIELD_PROP_PAR4
:
1522 rAny
>>= m_aContent
;
1531 OUString
SwHiddenTextField::GetColumnName(const OUString
& rName
)
1533 sal_Int32 nPos
= rName
.indexOf(DB_DELIM
);
1536 nPos
= rName
.indexOf(DB_DELIM
, nPos
+ 1);
1539 return rName
.copy(nPos
+ 1);
1544 OUString
SwHiddenTextField::GetDBName(std::u16string_view rName
, SwDoc
& rDoc
)
1546 size_t nPos
= rName
.find(DB_DELIM
);
1547 if( nPos
!= std::u16string_view::npos
)
1549 nPos
= rName
.find(DB_DELIM
, nPos
+ 1);
1551 if( nPos
!= std::u16string_view::npos
)
1552 return OUString(rName
.substr(0, nPos
));
1555 SwDBData aData
= rDoc
.GetDBData();
1556 return aData
.sDataSource
+ OUStringChar(DB_DELIM
) + aData
.sCommand
;
1559 // [aFieldDefinition] value sample : " IF A == B \"TrueText\" \"FalseText\""
1560 void SwHiddenTextField::ParseIfFieldDefinition(std::u16string_view aFieldDefinition
,
1561 OUString
& rCondition
,
1565 // get all positions inside the input string where words are started
1567 // In: " IF A == B \"TrueText\" \"FalseText\""
1569 // 01234567890 123456789 01 2345678901 2
1572 // [1, 4, 6, 9, 11, 22]
1573 std::vector
<sal_Int32
> wordPosition
;
1575 bool quoted
= false;
1576 bool insideWord
= false;
1577 for (size_t i
= 0; i
< aFieldDefinition
.size(); i
++)
1581 if (aFieldDefinition
[i
] == '\"')
1589 if (aFieldDefinition
[i
] == ' ')
1598 quoted
= (aFieldDefinition
[i
] == '\"');
1603 wordPosition
.push_back(i
);
1604 quoted
= (aFieldDefinition
[i
] == '\"');
1611 // first word is always "IF"
1612 // last two words are: true-case and false-case,
1613 // everything before is treated as condition expression
1614 // => we need at least 4 words to be inside the input string
1615 if (wordPosition
.size() < 4)
1621 const sal_Int32 conditionBegin
= wordPosition
[1];
1622 const sal_Int32 trueBegin
= wordPosition
[wordPosition
.size() - 2];
1623 const sal_Int32 falseBegin
= wordPosition
[wordPosition
.size() - 1];
1625 const sal_Int32 conditionLength
= trueBegin
- conditionBegin
;
1626 const sal_Int32 trueLength
= falseBegin
- trueBegin
;
1629 // OUString::copy( sal_Int32 beginIndex, sal_Int32 count )
1630 rCondition
= o3tl::trim(aFieldDefinition
.substr(conditionBegin
, conditionLength
));
1631 rTrue
= o3tl::trim(aFieldDefinition
.substr(trueBegin
, trueLength
));
1632 rFalse
= o3tl::trim(aFieldDefinition
.substr(falseBegin
));
1635 if (rCondition
.getLength() >= 2)
1637 if (rCondition
[0] == '\"' && rCondition
[rCondition
.getLength() - 1] == '\"')
1638 rCondition
= rCondition
.copy(1, rCondition
.getLength() - 2);
1640 if (rTrue
.getLength() >= 2)
1642 if (rTrue
[0] == '\"' && rTrue
[rTrue
.getLength() - 1] == '\"')
1643 rTrue
= rTrue
.copy(1, rTrue
.getLength() - 2);
1645 if (rFalse
.getLength() >= 2)
1647 if (rFalse
[0] == '\"' && rFalse
[rFalse
.getLength() - 1] == '\"')
1648 rFalse
= rFalse
.copy(1, rFalse
.getLength() - 2);
1651 // Note: do not make trim once again, while this is a user defined data
1654 // field type for line height 0
1656 SwHiddenParaFieldType::SwHiddenParaFieldType()
1657 : SwFieldType( SwFieldIds::HiddenPara
)
1661 std::unique_ptr
<SwFieldType
> SwHiddenParaFieldType::Copy() const
1663 return std::make_unique
<SwHiddenParaFieldType
>();
1666 // field for line height 0
1668 SwHiddenParaField::SwHiddenParaField(SwHiddenParaFieldType
* pTyp
, OUString aStr
)
1669 : SwField(pTyp
), m_aCond(std::move(aStr
))
1671 m_bIsHidden
= false;
1674 OUString
SwHiddenParaField::ExpandImpl(SwRootFrame
const*const) const
1679 std::unique_ptr
<SwField
> SwHiddenParaField::Copy() const
1681 std::unique_ptr
<SwHiddenParaField
> pField(new SwHiddenParaField(static_cast<SwHiddenParaFieldType
*>(GetTyp()), m_aCond
));
1682 pField
->m_bIsHidden
= m_bIsHidden
;
1683 return std::unique_ptr
<SwField
>(pField
.release());
1686 bool SwHiddenParaField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
1690 case FIELD_PROP_PAR1
:
1693 case FIELD_PROP_BOOL1
:
1694 rAny
<<= m_bIsHidden
;
1703 bool SwHiddenParaField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
1707 case FIELD_PROP_PAR1
:
1710 case FIELD_PROP_BOOL1
:
1711 m_bIsHidden
= *o3tl::doAccess
<bool>(rAny
);
1721 void SwHiddenParaField::SetPar1(const OUString
& rStr
)
1726 OUString
SwHiddenParaField::GetPar1() const
1731 // PostIt field type
1733 SwPostItFieldType::SwPostItFieldType(SwDoc
& rDoc
)
1734 : SwFieldType( SwFieldIds::Postit
)
1738 std::unique_ptr
<SwFieldType
> SwPostItFieldType::Copy() const
1740 return std::make_unique
<SwPostItFieldType
>(mrDoc
);
1745 sal_uInt32
SwPostItField::s_nLastPostItId
= 1;
1747 SwPostItField::SwPostItField( SwPostItFieldType
* pT
,
1752 const DateTime
& rDateTime
,
1753 const bool bResolved
,
1754 const sal_uInt32 nPostItId
,
1755 const sal_uInt32 nParentId
,
1756 const sal_uInt32 nParaId
,
1757 const sal_uInt32 nParentPostItId
,
1758 OUString aParentName
1761 , m_sText( std::move(aText
) )
1762 , m_sAuthor( std::move(aAuthor
) )
1763 , m_sInitials( std::move(aInitials
) )
1764 , m_sName( std::move(aName
) )
1765 , m_aDateTime( rDateTime
)
1766 , m_bResolved( bResolved
)
1767 , m_nParentId( nParentId
)
1768 , m_nParaId( nParaId
)
1769 , m_nParentPostItId ( nParentPostItId
)
1770 , m_sParentName( std::move(aParentName
) )
1772 m_nPostItId
= nPostItId
== 0 ? s_nLastPostItId
++ : nPostItId
;
1775 SwPostItField::~SwPostItField()
1777 if ( m_xTextObject
.is() )
1779 m_xTextObject
->DisposeEditSource();
1785 OUString
SwPostItField::ExpandImpl(SwRootFrame
const*const) const
1790 OUString
SwPostItField::GetDescription() const
1792 return SwResId(STR_NOTE
);
1795 void SwPostItField::SetResolved(bool bNewState
)
1797 m_bResolved
= bNewState
;
1800 void SwPostItField::ToggleResolved()
1802 m_bResolved
= !m_bResolved
;
1805 bool SwPostItField::GetResolved() const
1810 std::unique_ptr
<SwField
> SwPostItField::Copy() const
1812 std::unique_ptr
<SwPostItField
> pRet(new SwPostItField( static_cast<SwPostItFieldType
*>(GetTyp()), m_sAuthor
, m_sText
, m_sInitials
, m_sName
,
1813 m_aDateTime
, m_bResolved
, m_nPostItId
, m_nParentId
, m_nParaId
, m_nParentPostItId
, m_sParentName
));
1815 pRet
->SetTextObject( *mpText
);
1817 // Note: member <m_xTextObject> not copied.
1819 return std::unique_ptr
<SwField
>(pRet
.release());
1823 void SwPostItField::SetPar1(const OUString
& rStr
)
1829 OUString
SwPostItField::GetPar1() const
1834 /// set the PostIt's text
1835 void SwPostItField::SetPar2(const OUString
& rStr
)
1840 /// get the PostIt's text
1841 OUString
SwPostItField::GetPar2() const
1847 void SwPostItField::SetName(const OUString
& rName
)
1852 void SwPostItField::SetParentName(const OUString
& rName
)
1854 m_sParentName
= rName
;
1857 void SwPostItField::SetTextObject( std::optional
<OutlinerParaObject
> pText
)
1859 mpText
= std::move(pText
);
1862 sal_Int32
SwPostItField::GetNumberOfParagraphs() const
1864 return mpText
? mpText
->Count() : 1;
1867 void SwPostItField::ChangeStyleSheetName(std::u16string_view rOldName
, const SfxStyleSheetBase
* pStyleSheet
)
1869 if (mpText
&& pStyleSheet
)
1870 mpText
->ChangeStyleSheetName(pStyleSheet
->GetFamily(), rOldName
, pStyleSheet
->GetName());
1873 void SwPostItField::SetPostItId(const sal_uInt32 nPostItId
)
1875 m_nPostItId
= nPostItId
== 0 ? s_nLastPostItId
++ : nPostItId
;
1878 void SwPostItField::SetParentPostItId(const sal_uInt32 nParentPostItId
)
1880 m_nParentPostItId
= nParentPostItId
;
1883 void SwPostItField::SetParentId(const sal_uInt32 nParentId
)
1885 m_nParentId
= nParentId
;
1888 void SwPostItField::SetParaId(const sal_uInt32 nParaId
)
1890 m_nParaId
= nParaId
;
1893 bool SwPostItField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
1897 case FIELD_PROP_PAR1
:
1900 case FIELD_PROP_PAR2
:
1905 case FIELD_PROP_PAR3
:
1906 rAny
<<= m_sInitials
;
1908 case FIELD_PROP_PAR4
:
1911 case FIELD_PROP_PAR7
: // PAR5 (Parent Para Id) and PAR6 (Para Id) are skipped - they are not written into xml. Used for file conversion.
1912 rAny
<<= m_sParentName
;
1914 case FIELD_PROP_BOOL1
:
1915 rAny
<<= m_bResolved
;
1917 case FIELD_PROP_TEXT
:
1919 if ( !m_xTextObject
.is() )
1921 SwPostItFieldType
* pGetType
= static_cast<SwPostItFieldType
*>(GetTyp());
1922 SwDoc
& rDoc
= pGetType
->GetDoc();
1923 auto pObj
= std::make_unique
<SwTextAPIEditSource
>( &rDoc
);
1924 const_cast <SwPostItField
*> (this)->m_xTextObject
= new SwTextAPIObject( std::move(pObj
) );
1928 m_xTextObject
->SetText( *mpText
);
1930 m_xTextObject
->SetString( m_sText
);
1932 uno::Reference
< text::XText
> xText( m_xTextObject
);
1936 case FIELD_PROP_DATE
:
1938 rAny
<<= m_aDateTime
.GetUNODate();
1941 case FIELD_PROP_DATE_TIME
:
1943 rAny
<<= m_aDateTime
.GetUNODateTime();
1946 case FIELD_PROP_PAR5
:
1948 rAny
<<= OUString(OUString::number(m_nParentId
, 16).toAsciiUpperCase());
1951 case FIELD_PROP_PAR6
:
1953 rAny
<<= OUString(OUString::number(m_nPostItId
, 16).toAsciiUpperCase());
1956 case FIELD_PROP_TITLE
:
1964 bool SwPostItField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
1968 case FIELD_PROP_PAR1
:
1971 case FIELD_PROP_PAR2
:
1973 //#i100374# new string via api, delete complex text object so SwPostItNote picks up the new string
1976 case FIELD_PROP_PAR3
:
1977 rAny
>>= m_sInitials
;
1979 case FIELD_PROP_PAR4
:
1982 case FIELD_PROP_PAR7
: // PAR5 (Parent Para Id) and PAR6 (Para Id) are skipped - they are not written into xml. Used for file conversion.
1983 rAny
>>= m_sParentName
;
1985 case FIELD_PROP_BOOL1
:
1986 rAny
>>= m_bResolved
;
1988 case FIELD_PROP_TEXT
:
1989 OSL_FAIL("Not implemented!");
1991 case FIELD_PROP_DATE
:
1992 if( auto aSetDate
= o3tl::tryAccess
<util::Date
>(rAny
) )
1994 m_aDateTime
= DateTime( Date(aSetDate
->Day
, aSetDate
->Month
, aSetDate
->Year
) );
1997 case FIELD_PROP_DATE_TIME
:
1999 util::DateTime aDateTimeValue
;
2000 if(!(rAny
>>= aDateTimeValue
))
2002 m_aDateTime
= DateTime(aDateTimeValue
);
2005 case FIELD_PROP_PAR5
:
2009 m_nParentId
= sTemp
.toInt32(16);
2012 case FIELD_PROP_PAR6
:
2016 m_nPostItId
= sTemp
.toInt32(16);
2025 void SwPostItField::dumpAsXml(xmlTextWriterPtr pWriter
) const
2027 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwPostItField"));
2028 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr()));
2030 SwField::dumpAsXml(pWriter
);
2032 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("mpText"));
2033 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", mpText
? &*mpText
: nullptr);
2035 mpText
->dumpAsXml(pWriter
);
2036 (void)xmlTextWriterEndElement(pWriter
);
2038 (void)xmlTextWriterEndElement(pWriter
);
2041 // extended user information field type
2043 SwExtUserFieldType::SwExtUserFieldType()
2044 : SwFieldType( SwFieldIds::ExtUser
)
2048 std::unique_ptr
<SwFieldType
> SwExtUserFieldType::Copy() const
2050 return std::make_unique
<SwExtUserFieldType
>();
2053 OUString
SwExtUserFieldType::Expand(sal_uInt16 nSub
)
2055 UserOptToken nRet
= static_cast<UserOptToken
>(USHRT_MAX
);
2058 case EU_FIRSTNAME
: nRet
= UserOptToken::FirstName
; break;
2059 case EU_NAME
: nRet
= UserOptToken::LastName
; break;
2060 case EU_SHORTCUT
: nRet
= UserOptToken::ID
; break;
2062 case EU_COMPANY
: nRet
= UserOptToken::Company
; break;
2063 case EU_STREET
: nRet
= UserOptToken::Street
; break;
2064 case EU_TITLE
: nRet
= UserOptToken::Title
; break;
2065 case EU_POSITION
: nRet
= UserOptToken::Position
; break;
2066 case EU_PHONE_PRIVATE
: nRet
= UserOptToken::TelephoneHome
; break;
2067 case EU_PHONE_COMPANY
: nRet
= UserOptToken::TelephoneWork
; break;
2068 case EU_FAX
: nRet
= UserOptToken::Fax
; break;
2069 case EU_EMAIL
: nRet
= UserOptToken::Email
; break;
2070 case EU_COUNTRY
: nRet
= UserOptToken::Country
; break;
2071 case EU_ZIP
: nRet
= UserOptToken::Zip
; break;
2072 case EU_CITY
: nRet
= UserOptToken::City
; break;
2073 case EU_STATE
: nRet
= UserOptToken::State
; break;
2074 case EU_FATHERSNAME
: nRet
= UserOptToken::FathersName
; break;
2075 case EU_APARTMENT
: nRet
= UserOptToken::Apartment
; break;
2076 default: OSL_ENSURE( false, "Field unknown");
2078 if( static_cast<UserOptToken
>(USHRT_MAX
) != nRet
)
2080 SvtUserOptions
& rUserOpt
= SwModule::get()->GetUserOptions();
2081 return rUserOpt
.GetToken( nRet
);
2086 // extended user information field
2088 SwExtUserField::SwExtUserField(SwExtUserFieldType
* pTyp
, sal_uInt16 nSubTyp
, sal_uInt32 nFormat
) :
2089 SwField(pTyp
, nFormat
), m_nType(nSubTyp
)
2091 m_aContent
= SwExtUserFieldType::Expand(m_nType
);
2094 OUString
SwExtUserField::ExpandImpl(SwRootFrame
const*const) const
2097 const_cast<SwExtUserField
*>(this)->m_aContent
= SwExtUserFieldType::Expand(m_nType
);
2102 std::unique_ptr
<SwField
> SwExtUserField::Copy() const
2104 std::unique_ptr
<SwExtUserField
> pField(new SwExtUserField(static_cast<SwExtUserFieldType
*>(GetTyp()), m_nType
, GetFormat()));
2105 pField
->SetExpansion(m_aContent
);
2107 return std::unique_ptr
<SwField
>(pField
.release());
2110 sal_uInt16
SwExtUserField::GetSubType() const
2115 void SwExtUserField::SetSubType(sal_uInt16 nSub
)
2120 bool SwExtUserField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
2124 case FIELD_PROP_PAR1
:
2125 rAny
<<= m_aContent
;
2128 case FIELD_PROP_USHORT1
:
2130 sal_Int16 nTmp
= m_nType
;
2134 case FIELD_PROP_BOOL1
:
2143 bool SwExtUserField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
2147 case FIELD_PROP_PAR1
:
2148 rAny
>>= m_aContent
;
2151 case FIELD_PROP_USHORT1
:
2158 case FIELD_PROP_BOOL1
:
2159 if( *o3tl::doAccess
<bool>(rAny
) )
2160 SetFormat(GetFormat() | AF_FIXED
);
2162 SetFormat(GetFormat() & ~AF_FIXED
);
2170 // field type for relative page numbers
2172 SwRefPageSetFieldType::SwRefPageSetFieldType()
2173 : SwFieldType( SwFieldIds::RefPageSet
)
2177 std::unique_ptr
<SwFieldType
> SwRefPageSetFieldType::Copy() const
2179 return std::make_unique
<SwRefPageSetFieldType
>();
2182 // overridden since there is nothing to update
2183 void SwRefPageSetFieldType::SwClientNotify(const SwModify
&, const SfxHint
&)
2187 // field for relative page numbers
2189 SwRefPageSetField::SwRefPageSetField( SwRefPageSetFieldType
* pTyp
,
2190 short nOff
, bool bFlag
)
2191 : SwField( pTyp
), m_nOffset( nOff
), m_bOn( bFlag
)
2195 OUString
SwRefPageSetField::ExpandImpl(SwRootFrame
const*const) const
2200 std::unique_ptr
<SwField
> SwRefPageSetField::Copy() const
2202 return std::make_unique
<SwRefPageSetField
>( static_cast<SwRefPageSetFieldType
*>(GetTyp()), m_nOffset
, m_bOn
);
2205 OUString
SwRefPageSetField::GetPar2() const
2207 return OUString::number(GetOffset());
2210 void SwRefPageSetField::SetPar2(const OUString
& rStr
)
2212 SetOffset( static_cast<short>(rStr
.toInt32()) );
2215 bool SwRefPageSetField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
2219 case FIELD_PROP_BOOL1
:
2222 case FIELD_PROP_USHORT1
:
2223 rAny
<<= static_cast<sal_Int16
>(m_nOffset
);
2231 bool SwRefPageSetField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
2235 case FIELD_PROP_BOOL1
:
2236 m_bOn
= *o3tl::doAccess
<bool>(rAny
);
2238 case FIELD_PROP_USHORT1
:
2247 // relative page numbers - query field
2249 SwRefPageGetFieldType::SwRefPageGetFieldType( SwDoc
& rDc
)
2250 : SwFieldType( SwFieldIds::RefPageGet
), m_rDoc( rDc
), m_nNumberingType( SVX_NUM_ARABIC
)
2254 std::unique_ptr
<SwFieldType
> SwRefPageGetFieldType::Copy() const
2256 std::unique_ptr
<SwRefPageGetFieldType
> pNew(new SwRefPageGetFieldType( m_rDoc
));
2257 pNew
->m_nNumberingType
= m_nNumberingType
;
2261 void SwRefPageGetFieldType::SwClientNotify(const SwModify
&, const SfxHint
& rHint
)
2263 if (rHint
.GetId() == SfxHintId::SwFormatChange
2264 || rHint
.GetId() == SfxHintId::SwObjectDying
2265 || rHint
.GetId() == SfxHintId::SwUpdateAttr
)
2267 // forward to text fields, they "expand" the text
2268 CallSwClientNotify(rHint
);
2271 if (rHint
.GetId() != SfxHintId::SwLegacyModify
&& rHint
.GetId() != SfxHintId::SwAttrSetChange
)
2273 const sw::LegacyModifyHint
* pLegacy
= nullptr;
2274 const sw::AttrSetChangeHint
* pChangeHint
= nullptr;
2275 if (rHint
.GetId() == SfxHintId::SwLegacyModify
)
2276 pLegacy
= static_cast<const sw::LegacyModifyHint
*>(&rHint
);
2277 else // rHint.GetId() == SfxHintId::SwAttrSetChange
2278 pChangeHint
= static_cast<const sw::AttrSetChangeHint
*>(&rHint
);
2279 auto const ModifyImpl
= [this](SwRootFrame
const*const pLayout
)
2281 // first collect all SetPageRefFields
2282 SetGetExpFields aTmpLst
;
2283 if (MakeSetList(aTmpLst
, pLayout
))
2285 std::vector
<SwFormatField
*> vFields
;
2286 GatherFields(vFields
);
2287 for(auto pFormatField
: vFields
)
2288 UpdateField(pFormatField
->GetTextField(), aTmpLst
, pLayout
);
2292 // update all GetReference fields
2293 if( (pLegacy
&& !pLegacy
->m_pNew
&& !pLegacy
->m_pOld
&& HasWriterListeners())
2294 || (pChangeHint
&& !pChangeHint
->m_pNew
&& !pChangeHint
->m_pOld
&& HasWriterListeners()))
2296 SwRootFrame
const* pLayout(nullptr);
2297 SwRootFrame
const* pLayoutRLHidden(nullptr);
2298 for (SwRootFrame
const*const pLay
: m_rDoc
.GetAllLayouts())
2300 if (pLay
->IsHideRedlines())
2302 pLayoutRLHidden
= pLay
;
2309 ModifyImpl(pLayout
);
2310 if (pLayoutRLHidden
)
2312 ModifyImpl(pLayoutRLHidden
);
2316 // forward to text fields, they "expand" the text
2317 CallSwClientNotify(rHint
);
2320 bool SwRefPageGetFieldType::MakeSetList(SetGetExpFields
& rTmpLst
,
2321 SwRootFrame
const*const pLayout
)
2323 IDocumentRedlineAccess
const& rIDRA(m_rDoc
.getIDocumentRedlineAccess());
2324 std::vector
<SwFormatField
*> vFields
;
2325 m_rDoc
.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::RefPageSet
)->GatherFields(vFields
);
2326 for(auto pFormatField
: vFields
)
2328 // update only the GetRef fields
2329 const SwTextField
* pTField
= pFormatField
->GetTextField();
2330 if (!pLayout
|| !pLayout
->IsHideRedlines() || !sw::IsFieldDeletedInModel(rIDRA
, *pTField
))
2332 const SwTextNode
& rTextNd
= pTField
->GetTextNode();
2334 // Always the first! (in Tab-Headline, header/footer )
2336 std::pair
<Point
, bool> const tmp(aPt
, false);
2337 const SwContentFrame
*const pFrame
= rTextNd
.getLayoutFrame(
2338 pLayout
, nullptr, &tmp
);
2340 std::unique_ptr
<SetGetExpField
> pNew
;
2343 pFrame
->IsInDocBody() ||
2345 // Check if pFrame is not yet connected to the layout.
2346 !pFrame
->FindPageFrame() )
2348 pNew
.reset( new SetGetExpField( rTextNd
, pTField
) );
2352 // create index for determination of the TextNode
2353 SwPosition
aPos( m_rDoc
.GetNodes().GetEndOfPostIts() );
2354 bool const bResult
= GetBodyTextNode( m_rDoc
, aPos
, *pFrame
);
2355 OSL_ENSURE(bResult
, "where is the Field?");
2356 pNew
.reset( new SetGetExpField( aPos
.GetNode(), pTField
,
2357 aPos
.GetContentIndex() ) );
2360 rTmpLst
.insert( std::move(pNew
) );
2363 return !rTmpLst
.empty();
2366 void SwRefPageGetFieldType::UpdateField( SwTextField
const * pTextField
,
2367 SetGetExpFields
const & rSetList
,
2368 SwRootFrame
const*const pLayout
)
2370 SwRefPageGetField
* pGetField
= const_cast<SwRefPageGetField
*>(static_cast<const SwRefPageGetField
*>(pTextField
->GetFormatField().GetField()));
2371 pGetField
->SetText( OUString(), pLayout
);
2373 // then search the correct RefPageSet field
2374 SwTextNode
* pTextNode
= &pTextField
->GetTextNode();
2375 if( pTextNode
->StartOfSectionIndex() >
2376 m_rDoc
.GetNodes().GetEndOfExtras().GetIndex() )
2378 SetGetExpField
aEndField( *pTextNode
, pTextField
);
2380 SetGetExpFields::const_iterator itLast
= rSetList
.lower_bound( &aEndField
);
2382 if( itLast
!= rSetList
.begin() )
2385 const SwTextField
* pRefTextField
= (*itLast
)->GetTextField();
2386 const SwRefPageSetField
* pSetField
=
2387 static_cast<const SwRefPageSetField
*>(pRefTextField
->GetFormatField().GetField());
2388 if( pSetField
->IsOn() )
2390 // determine the correct offset
2392 std::pair
<Point
, bool> const tmp(aPt
, false);
2393 const SwContentFrame
*const pFrame
= pTextNode
->getLayoutFrame(
2394 pLayout
, nullptr, &tmp
);
2395 const SwContentFrame
*const pRefFrame
= pRefTextField
->GetTextNode().getLayoutFrame(
2396 pLayout
, nullptr, &tmp
);
2397 const SwPageFrame
* pPgFrame
= nullptr;
2399 if ( pFrame
&& pRefFrame
)
2401 pPgFrame
= pFrame
->FindPageFrame();
2402 nDiff
= pPgFrame
->GetPhyPageNum() -
2403 pRefFrame
->FindPageFrame()->GetPhyPageNum() + 1;
2406 SvxNumType nTmpFormat
= SVX_NUM_PAGEDESC
== static_cast<SvxNumType
>(pGetField
->GetFormat())
2409 : pPgFrame
->GetPageDesc()->GetNumType().GetNumberingType() )
2410 : static_cast<SvxNumType
>(pGetField
->GetFormat());
2411 const short nPageNum
= std::max
<short>(0, pSetField
->GetOffset() + nDiff
);
2412 pGetField
->SetText(FormatNumber(nPageNum
, nTmpFormat
), pLayout
);
2417 const_cast<SwFormatField
&>(pTextField
->GetFormatField()).ForceUpdateTextNode();
2420 // queries for relative page numbering
2422 SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType
* pTyp
,
2423 sal_uInt32 nFormat
)
2424 : SwField( pTyp
, nFormat
)
2428 void SwRefPageGetField::SetText(const OUString
& rText
,
2429 SwRootFrame
const*const pLayout
)
2431 if (!pLayout
|| !pLayout
->IsHideRedlines())
2435 if (!pLayout
|| pLayout
->IsHideRedlines())
2437 m_sTextRLHidden
= rText
;
2441 OUString
SwRefPageGetField::ExpandImpl(SwRootFrame
const*const pLayout
) const
2443 return pLayout
&& pLayout
->IsHideRedlines() ? m_sTextRLHidden
: m_sText
;
2446 std::unique_ptr
<SwField
> SwRefPageGetField::Copy() const
2448 std::unique_ptr
<SwRefPageGetField
> pCpy(new SwRefPageGetField(
2449 static_cast<SwRefPageGetFieldType
*>(GetTyp()), GetFormat() ));
2450 pCpy
->m_sText
= m_sText
;
2451 pCpy
->m_sTextRLHidden
= m_sTextRLHidden
;
2452 return std::unique_ptr
<SwField
>(pCpy
.release());
2455 void SwRefPageGetField::ChangeExpansion(const SwFrame
& rFrame
,
2456 const SwTextField
* pField
)
2458 // only fields in Footer, Header, FootNote, Flys
2459 SwRefPageGetFieldType
* pGetType
= static_cast<SwRefPageGetFieldType
*>(GetTyp());
2460 SwDoc
& rDoc
= pGetType
->GetDoc();
2461 if( pField
->GetTextNode().StartOfSectionIndex() >
2462 rDoc
.GetNodes().GetEndOfExtras().GetIndex() )
2465 SwRootFrame
const& rLayout(*rFrame
.getRootFrame());
2466 OUString
& rText(rLayout
.IsHideRedlines() ? m_sTextRLHidden
: m_sText
);
2469 OSL_ENSURE(!rFrame
.IsInDocBody(), "Flag incorrect, frame is in DocBody");
2471 // collect all SetPageRefFields
2472 SetGetExpFields aTmpLst
;
2473 if (!pGetType
->MakeSetList(aTmpLst
, &rLayout
))
2476 // create index for determination of the TextNode
2477 SwPosition
aPos( rDoc
.GetNodes() );
2478 SwTextNode
* pTextNode
= const_cast<SwTextNode
*>(GetBodyTextNode(rDoc
, aPos
, rFrame
));
2480 // If no layout exists, ChangeExpansion is called for header and
2481 // footer lines via layout formatting without existing TextNode.
2485 SetGetExpField
aEndField( aPos
.GetNode(), pField
, aPos
.GetContentIndex() );
2487 SetGetExpFields::const_iterator itLast
= aTmpLst
.lower_bound( &aEndField
);
2489 if( itLast
== aTmpLst
.begin() )
2490 return; // there is no corresponding set-field in front
2493 const SwTextField
* pRefTextField
= (*itLast
)->GetTextField();
2494 const SwRefPageSetField
* pSetField
=
2495 static_cast<const SwRefPageSetField
*>(pRefTextField
->GetFormatField().GetField());
2497 std::pair
<Point
, bool> const tmp(aPt
, false);
2498 const SwContentFrame
*const pRefFrame
= pRefTextField
->GetTextNode().getLayoutFrame(
2499 &rLayout
, nullptr, &tmp
);
2500 if( !(pSetField
->IsOn() && pRefFrame
) )
2503 // determine the correct offset
2504 const SwPageFrame
* pPgFrame
= rFrame
.FindPageFrame();
2505 const short nDiff
= pPgFrame
->GetPhyPageNum() -
2506 pRefFrame
->FindPageFrame()->GetPhyPageNum() + 1;
2508 SwRefPageGetField
* pGetField
= const_cast<SwRefPageGetField
*>(static_cast<const SwRefPageGetField
*>(pField
->GetFormatField().GetField()));
2509 SvxNumType nTmpFormat
= SVX_NUM_PAGEDESC
== pGetField
->GetFormat()
2510 ? pPgFrame
->GetPageDesc()->GetNumType().GetNumberingType()
2511 : static_cast<SvxNumType
>(pGetField
->GetFormat());
2512 const short nPageNum
= std::max
<short>(0, pSetField
->GetOffset() + nDiff
);
2513 pGetField
->SetText(FormatNumber(nPageNum
, nTmpFormat
), &rLayout
);
2516 bool SwRefPageGetField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
2520 case FIELD_PROP_USHORT1
:
2521 rAny
<<= static_cast<sal_Int16
>(GetFormat());
2523 case FIELD_PROP_PAR1
:
2532 bool SwRefPageGetField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
2536 case FIELD_PROP_USHORT1
:
2540 if(nSet
<= SVX_NUM_PAGEDESC
)
2544 case FIELD_PROP_PAR1
:
2546 m_sTextRLHidden
= m_sText
;
2554 // field type to jump to and edit
2556 SwJumpEditFieldType::SwJumpEditFieldType( SwDoc
& rD
)
2557 : SwFieldType( SwFieldIds::JumpEdit
), m_rDoc( rD
), m_aDep( *this )
2561 std::unique_ptr
<SwFieldType
> SwJumpEditFieldType::Copy() const
2563 return std::make_unique
<SwJumpEditFieldType
>( m_rDoc
);
2566 SwCharFormat
* SwJumpEditFieldType::GetCharFormat()
2568 SwCharFormat
* pFormat
= m_rDoc
.getIDocumentStylePoolAccess().GetCharFormatFromPool( RES_POOLCHR_JUMPEDIT
);
2569 m_aDep
.StartListening(pFormat
);
2573 SwJumpEditField::SwJumpEditField( SwJumpEditFieldType
* pTyp
, sal_uInt32 nForm
,
2574 OUString aText
, OUString aHelp
)
2575 : SwField( pTyp
, nForm
), m_sText( std::move(aText
) ), m_sHelp( std::move(aHelp
) )
2579 OUString
SwJumpEditField::ExpandImpl(SwRootFrame
const*const) const
2581 return "<" + m_sText
+ ">";
2584 std::unique_ptr
<SwField
> SwJumpEditField::Copy() const
2586 return std::make_unique
<SwJumpEditField
>( static_cast<SwJumpEditFieldType
*>(GetTyp()), GetFormat(),
2590 /// get place holder text
2591 OUString
SwJumpEditField::GetPar1() const
2596 /// set place holder text
2597 void SwJumpEditField::SetPar1(const OUString
& rStr
)
2603 OUString
SwJumpEditField::GetPar2() const
2609 void SwJumpEditField::SetPar2(const OUString
& rStr
)
2614 bool SwJumpEditField::QueryValue( uno::Any
& rAny
, sal_uInt16 nWhichId
) const
2618 case FIELD_PROP_USHORT1
:
2621 switch( GetFormat() )
2623 case JE_FMT_TABLE
: nRet
= text::PlaceholderType::TABLE
; break;
2624 case JE_FMT_FRAME
: nRet
= text::PlaceholderType::TEXTFRAME
; break;
2625 case JE_FMT_GRAPHIC
:nRet
= text::PlaceholderType::GRAPHIC
; break;
2626 case JE_FMT_OLE
: nRet
= text::PlaceholderType::OBJECT
; break;
2628 nRet
= text::PlaceholderType::TEXT
; break;
2633 case FIELD_PROP_PAR1
:
2636 case FIELD_PROP_PAR2
:
2645 bool SwJumpEditField::PutValue( const uno::Any
& rAny
, sal_uInt16 nWhichId
)
2649 case FIELD_PROP_USHORT1
:
2651 //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
2652 // called with a int32 value! But normally we need
2653 // here only a int16
2658 case text::PlaceholderType::TEXT
: SetFormat(JE_FMT_TEXT
); break;
2659 case text::PlaceholderType::TABLE
: SetFormat(JE_FMT_TABLE
); break;
2660 case text::PlaceholderType::TEXTFRAME
: SetFormat(JE_FMT_FRAME
); break;
2661 case text::PlaceholderType::GRAPHIC
: SetFormat(JE_FMT_GRAPHIC
); break;
2662 case text::PlaceholderType::OBJECT
: SetFormat(JE_FMT_OLE
); break;
2666 case FIELD_PROP_PAR1
:
2669 case FIELD_PROP_PAR2
:
2678 // combined character field type
2680 SwCombinedCharFieldType::SwCombinedCharFieldType()
2681 : SwFieldType( SwFieldIds::CombinedChars
)
2685 std::unique_ptr
<SwFieldType
> SwCombinedCharFieldType::Copy() const
2687 return std::make_unique
<SwCombinedCharFieldType
>();
2690 // combined character field
2692 SwCombinedCharField::SwCombinedCharField( SwCombinedCharFieldType
* pFTyp
,
2693 const OUString
& rChars
)
2694 : SwField( pFTyp
, 0 ),
2695 m_sCharacters( rChars
.copy( 0, std::min
<sal_Int32
>(rChars
.getLength(), MAX_COMBINED_CHARACTERS
) ))
2699 OUString
SwCombinedCharField::ExpandImpl(SwRootFrame
const*const) const
2701 return m_sCharacters
;
2704 std::unique_ptr
<SwField
> SwCombinedCharField::Copy() const
2706 return std::make_unique
<SwCombinedCharField
>( static_cast<SwCombinedCharFieldType
*>(GetTyp()),
2710 OUString
SwCombinedCharField::GetPar1() const
2712 return m_sCharacters
;
2715 void SwCombinedCharField::SetPar1(const OUString
& rStr
)
2717 m_sCharacters
= rStr
.copy(0, std::min
<sal_Int32
>(rStr
.getLength(), MAX_COMBINED_CHARACTERS
));
2720 bool SwCombinedCharField::QueryValue( uno::Any
& rAny
,
2721 sal_uInt16 nWhichId
) const
2725 case FIELD_PROP_PAR1
:
2726 rAny
<<= m_sCharacters
;
2734 bool SwCombinedCharField::PutValue( const uno::Any
& rAny
,
2735 sal_uInt16 nWhichId
)
2739 case FIELD_PROP_PAR1
:
2752 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */