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 .
24 #include <libxml/xmlwriter.h>
26 #include <rtl/math.hxx>
27 #include <comphelper/string.hxx>
28 #include <svl/numformat.hxx>
29 #include <svl/zforlist.hxx>
30 #include <svl/zformat.hxx>
31 #include <o3tl/enumarray.hxx>
32 #include <osl/diagnose.h>
33 #include <unofldmid.h>
36 #include <docufld.hxx>
38 #include <shellres.hxx>
40 #include <strings.hrc>
42 #include <authfld.hxx>
46 #include <unofield.hxx>
48 using namespace ::com::sun::star
;
49 using namespace nsSwDocInfoSubType
;
51 static LanguageType
lcl_GetLanguageOfFormat( LanguageType nLng
, sal_uLong nFormat
,
52 const SvNumberFormatter
& rFormatter
)
54 if( nLng
== LANGUAGE_NONE
) // Bug #60010
55 nLng
= LANGUAGE_SYSTEM
;
56 else if( nLng
== ::GetAppLanguage() )
57 switch( rFormatter
.GetIndexTableOffset( nFormat
))
59 case NF_NUMBER_SYSTEM
:
60 case NF_DATE_SYSTEM_SHORT
:
61 case NF_DATE_SYSTEM_LONG
:
62 case NF_DATETIME_SYSTEM_SHORT_HHMM
:
63 nLng
= LANGUAGE_SYSTEM
;
73 std::vector
<OUString
>* SwFieldType::s_pFieldNames
= nullptr;
78 const o3tl::enumarray
<SwFieldIds
,SwFieldTypesEnum
> aTypeTab
{
79 /* SwFieldIds::Database */ SwFieldTypesEnum::Database
,
80 /* SwFieldIds::User */ SwFieldTypesEnum::User
,
81 /* SwFieldIds::Filename */ SwFieldTypesEnum::Filename
,
82 /* SwFieldIds::DatabaseName */ SwFieldTypesEnum::DatabaseName
,
83 /* SwFieldIds::Date */ SwFieldTypesEnum::Date
,
84 /* SwFieldIds::Time */ SwFieldTypesEnum::Time
,
85 /* SwFieldIds::PageNumber */ SwFieldTypesEnum::PageNumber
, // dynamic
86 /* SwFieldIds::Author */ SwFieldTypesEnum::Author
,
87 /* SwFieldIds::Chapter */ SwFieldTypesEnum::Chapter
,
88 /* SwFieldIds::DocStat */ SwFieldTypesEnum::DocumentStatistics
,
89 /* SwFieldIds::GetExp */ SwFieldTypesEnum::Get
, // dynamic
90 /* SwFieldIds::SetExp */ SwFieldTypesEnum::Set
, // dynamic
91 /* SwFieldIds::GetRef */ SwFieldTypesEnum::GetRef
,
92 /* SwFieldIds::HiddenText */ SwFieldTypesEnum::HiddenText
,
93 /* SwFieldIds::Postit */ SwFieldTypesEnum::Postit
,
94 /* SwFieldIds::FixDate */ SwFieldTypesEnum::FixedDate
,
95 /* SwFieldIds::FixTime */ SwFieldTypesEnum::FixedTime
,
96 /* SwFieldIds::Reg */ SwFieldTypesEnum::Begin
, // old (no change since 2000)
97 /* SwFieldIds::VarReg */ SwFieldTypesEnum::Begin
, // old (no change since 2000)
98 /* SwFieldIds::SetRef */ SwFieldTypesEnum::SetRef
,
99 /* SwFieldIds::Input */ SwFieldTypesEnum::Input
,
100 /* SwFieldIds::Macro */ SwFieldTypesEnum::Macro
,
101 /* SwFieldIds::Dde */ SwFieldTypesEnum::DDE
,
102 /* SwFieldIds::Table */ SwFieldTypesEnum::Formel
,
103 /* SwFieldIds::HiddenPara */ SwFieldTypesEnum::HiddenParagraph
,
104 /* SwFieldIds::DocInfo */ SwFieldTypesEnum::DocumentInfo
,
105 /* SwFieldIds::TemplateName */ SwFieldTypesEnum::TemplateName
,
106 /* SwFieldIds::DbNextSet */ SwFieldTypesEnum::DatabaseNextSet
,
107 /* SwFieldIds::DbNumSet */ SwFieldTypesEnum::DatabaseNumberSet
,
108 /* SwFieldIds::DbSetNumber */ SwFieldTypesEnum::DatabaseSetNumber
,
109 /* SwFieldIds::ExtUser */ SwFieldTypesEnum::ExtendedUser
,
110 /* SwFieldIds::RefPageSet */ SwFieldTypesEnum::SetRefPage
,
111 /* SwFieldIds::RefPageGet */ SwFieldTypesEnum::GetRefPage
,
112 /* SwFieldIds::Internet */ SwFieldTypesEnum::Internet
,
113 /* SwFieldIds::JumpEdit */ SwFieldTypesEnum::JumpEdit
,
114 /* SwFieldIds::Script */ SwFieldTypesEnum::Script
,
115 /* SwFieldIds::DateTime */ SwFieldTypesEnum::Begin
, // dynamic
116 /* SwFieldIds::TableOfAuthorities*/ SwFieldTypesEnum::Authority
,
117 /* SwFieldIds::CombinedChars */ SwFieldTypesEnum::CombinedChars
,
118 /* SwFieldIds::Dropdown */ SwFieldTypesEnum::Dropdown
,
119 /* SwFieldIds::ParagraphSignature */ SwFieldTypesEnum::ParagraphSignature
124 const OUString
& SwFieldType::GetTypeStr(SwFieldTypesEnum nTypeId
)
129 return (*SwFieldType::s_pFieldNames
)[static_cast<int>(nTypeId
)];
132 // each field references a field type that is unique for each document
133 SwFieldType::SwFieldType( SwFieldIds nWhichId
)
134 : sw::BroadcastingModify()
139 OUString
SwFieldType::GetName() const
144 void SwFieldType::QueryValue( uno::Any
&, sal_uInt16
) const
147 void SwFieldType::PutValue( const uno::Any
& , sal_uInt16
)
151 void SwFieldType::PrintHiddenPara()
153 const SwMsgPoolItem
aHint(RES_HIDDENPARA_PRINT
);
154 SwClientNotify(*this, sw::LegacyModifyHint(&aHint
, nullptr));
157 void SwFieldType::dumpAsXml(xmlTextWriterPtr pWriter
) const
159 std::vector
<SwFormatField
*> vFields
;
160 GatherFields(vFields
);
163 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwFieldType"));
164 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
165 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
166 for(const auto pFormatField
: vFields
)
167 pFormatField
->dumpAsXml(pWriter
);
168 (void)xmlTextWriterEndElement(pWriter
);
171 SwFormatField
* SwFieldType::FindFormatForField(const SwField
* pField
) const {
172 SwFormatField
* pFormat
= nullptr;
173 CallSwClientNotify(sw::FindFormatForFieldHint(pField
, pFormat
));
177 SwFormatField
* SwFieldType::FindFormatForPostItId(sal_uInt32 nPostItId
) const {
178 SwFormatField
* pFormat
= nullptr;
179 CallSwClientNotify(sw::FindFormatForPostItIdHint(nPostItId
, pFormat
));
183 void SwFieldType::CollectPostIts(std::vector
<SwFormatField
*>& rvFormatFields
, IDocumentRedlineAccess
const& rIDRA
, const bool bHideRedlines
)
185 CallSwClientNotify(sw::CollectPostItsHint(rvFormatFields
, rIDRA
, bHideRedlines
));
188 bool SwFieldType::HasHiddenInformationNotes() const
190 bool bHasHiddenInformationNotes
= false;
191 CallSwClientNotify(sw::HasHiddenInformationNotesHint(bHasHiddenInformationNotes
));
192 return bHasHiddenInformationNotes
;
195 void SwFieldType::GatherNodeIndex(std::vector
<SwNodeOffset
>& rvNodeIndex
)
197 CallSwClientNotify(sw::GatherNodeIndexHint(rvNodeIndex
));
200 void SwFieldType::GatherRefFields(std::vector
<SwGetRefField
*>& rvRFields
, const sal_uInt16 nTyp
)
202 CallSwClientNotify(sw::GatherRefFieldsHint(rvRFields
, nTyp
));
205 void SwFieldType::GatherFields(std::vector
<SwFormatField
*>& rvFields
, bool bCollectOnlyInDocNodes
) const
207 CallSwClientNotify(sw::GatherFieldsHint(rvFields
, bCollectOnlyInDocNodes
));
210 void SwFieldType::GatherDdeTables(std::vector
<SwDDETable
*>& rvTables
) const
212 CallSwClientNotify(sw::GatherDdeTablesHint(rvTables
));
215 void SwFieldType::UpdateDocPos(const SwTwips nDocPos
)
217 CallSwClientNotify(sw::DocPosUpdate(nDocPos
));
219 void SwFieldType::UpdateFields()
221 CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
224 void SwFieldType::SetXObject(rtl::Reference
<SwXFieldMaster
> const& xFieldMaster
)
226 m_wXFieldMaster
= xFieldMaster
.get();
229 void SwFieldTypes::dumpAsXml(xmlTextWriterPtr pWriter
) const
231 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwFieldTypes"));
232 sal_uInt16 nCount
= size();
233 for (sal_uInt16 nType
= 0; nType
< nCount
; ++nType
)
234 (*this)[nType
]->dumpAsXml(pWriter
);
235 (void)xmlTextWriterEndElement(pWriter
);
240 // Base class for all fields.
241 // A field (multiple can exist) references a field type (can exists only once)
246 bool bUseFieldValueCache
)
248 , m_nFormat( nFormat
)
250 , m_bUseFieldValueCache( bUseFieldValueCache
)
251 , m_bIsAutomaticLanguage( true )
260 // instead of indirectly via the type
263 SwFieldIds
SwField::Which() const
266 return m_pType
->Which();
270 SwFieldTypesEnum
SwField::GetTypeId() const
273 SwFieldTypesEnum nRet
;
274 switch (m_pType
->Which())
276 case SwFieldIds::DateTime
:
277 if (GetSubType() & FIXEDFLD
)
278 nRet
= GetSubType() & DATEFLD
? SwFieldTypesEnum::FixedDate
: SwFieldTypesEnum::FixedTime
;
280 nRet
= GetSubType() & DATEFLD
? SwFieldTypesEnum::Date
: SwFieldTypesEnum::Time
;
282 case SwFieldIds::GetExp
:
283 nRet
= nsSwGetSetExpType::GSE_FORMULA
& GetSubType() ? SwFieldTypesEnum::Formel
: SwFieldTypesEnum::Get
;
286 case SwFieldIds::HiddenText
:
287 nRet
= static_cast<SwFieldTypesEnum
>(GetSubType());
290 case SwFieldIds::SetExp
:
291 if( nsSwGetSetExpType::GSE_SEQ
& GetSubType() )
292 nRet
= SwFieldTypesEnum::Sequence
;
293 else if( static_cast<const SwSetExpField
*>(this)->GetInputFlag() )
294 nRet
= SwFieldTypesEnum::SetInput
;
296 nRet
= SwFieldTypesEnum::Set
;
299 case SwFieldIds::PageNumber
:
301 auto nSubType
= GetSubType();
302 if( PG_NEXT
== nSubType
)
303 nRet
= SwFieldTypesEnum::NextPage
;
304 else if( PG_PREV
== nSubType
)
305 nRet
= SwFieldTypesEnum::PreviousPage
;
307 nRet
= SwFieldTypesEnum::PageNumber
;
312 nRet
= aTypeTab
[ m_pType
->Which() ];
317 /// get name or content
318 OUString
SwField::GetFieldName() const
320 SwFieldTypesEnum nTypeId
= GetTypeId();
321 if (SwFieldIds::DateTime
== GetTyp()->Which())
324 ((GetSubType() & DATEFLD
) != 0) ? SwFieldTypesEnum::Date
: SwFieldTypesEnum::Time
;
326 OUString sRet
= SwFieldType::GetTypeStr( nTypeId
);
329 sRet
+= " " + SwViewShell::GetShellRes()->aFixedStr
;
334 OUString
SwField::GetPar1() const
339 OUString
SwField::GetPar2() const
344 OUString
SwField::GetFormula() const
349 void SwField::SetPar1(const OUString
& )
352 void SwField::SetPar2(const OUString
& )
355 sal_uInt16
SwField::GetSubType() const
360 void SwField::SetSubType(sal_uInt16
)
364 bool SwField::QueryValue( uno::Any
& rVal
, sal_uInt16 nWhichId
) const
368 case FIELD_PROP_BOOL4
:
369 rVal
<<= !m_bIsAutomaticLanguage
;
371 case FIELD_PROP_TITLE
:
382 bool SwField::PutValue( const uno::Any
& rVal
, sal_uInt16 nWhichId
)
386 case FIELD_PROP_BOOL4
:
390 m_bIsAutomaticLanguage
= !bFixed
;
393 case FIELD_PROP_TITLE
:
410 * This is needed/used for copying between documents.
411 * Needs to be always of the same type.
412 * @param pNewType The new type.
413 * @return The old type.
415 SwFieldType
* SwField::ChgTyp( SwFieldType
* pNewType
)
417 assert(pNewType
&& pNewType
->Which() == m_pType
->Which());
419 SwFieldType
* pOld
= m_pType
;
424 /// Does the field have an action on a ClickHandler? (E.g. INetFields,...)
425 bool SwField::HasClickHdl() const
428 switch (m_pType
->Which())
430 case SwFieldIds::Internet
:
431 case SwFieldIds::JumpEdit
:
432 case SwFieldIds::GetRef
:
433 case SwFieldIds::Macro
:
434 case SwFieldIds::Input
:
435 case SwFieldIds::Dropdown
:
436 case SwFieldIds::TableOfAuthorities
:
440 case SwFieldIds::SetExp
:
441 bRet
= static_cast<const SwSetExpField
*>(this)->GetInputFlag();
449 void SwField::SetLanguage(LanguageType
const nLang
)
454 void SwField::ChangeFormat(sal_uInt32
const nFormat
)
459 bool SwField::IsFixed() const
462 switch (m_pType
->Which())
464 case SwFieldIds::FixDate
:
465 case SwFieldIds::FixTime
:
469 case SwFieldIds::DateTime
:
470 bRet
= 0 != (GetSubType() & FIXEDFLD
);
473 case SwFieldIds::ExtUser
:
474 case SwFieldIds::Author
:
475 bRet
= 0 != (GetFormat() & AF_FIXED
);
478 case SwFieldIds::Filename
:
479 bRet
= 0 != (GetFormat() & FF_FIXED
);
482 case SwFieldIds::DocInfo
:
483 bRet
= 0 != (GetSubType() & DI_SUB_FIXED
);
491 SwField::ExpandField(bool const bCached
, SwRootFrame
const*const pLayout
) const
493 if ( m_bUseFieldValueCache
)
495 if (!bCached
) // #i85766# do not expand fields in clipboard documents
497 if (GetTypeId() == SwFieldTypesEnum::Authority
)
499 const SwAuthorityField
* pAuthorityField
= static_cast<const SwAuthorityField
*>(this);
500 m_Cache
= pAuthorityField
->ConditionalExpandAuthIdentifier(pLayout
);
503 m_Cache
= ExpandImpl(pLayout
);
508 return ExpandImpl(pLayout
);
511 std::unique_ptr
<SwField
> SwField::CopyField() const
513 std::unique_ptr
<SwField
> pNew
= Copy();
514 // #i85766# cache expansion of source (for clipboard)
515 // use this->cache, not this->Expand(): only text formatting calls Expand()
516 pNew
->m_Cache
= m_Cache
;
517 pNew
->m_bUseFieldValueCache
= m_bUseFieldValueCache
;
523 OUString
FormatNumber(sal_uInt32 nNum
, SvxNumType nFormat
, LanguageType nLang
)
525 if(SVX_NUM_PAGEDESC
== nFormat
)
526 return OUString::number( nNum
);
527 SvxNumberType aNumber
;
529 OSL_ENSURE(nFormat
!= SVX_NUM_NUMBER_NONE
, "wrong number format" );
531 aNumber
.SetNumberingType(nFormat
);
533 if (nLang
== LANGUAGE_NONE
)
534 return aNumber
.GetNumStr(nNum
);
536 return aNumber
.GetNumStr(nNum
, LanguageTag::convertToLocale(nLang
));
539 SwFieldTypesEnum
SwFieldTypeFromString(std::u16string_view rString
)
541 if (rString
== u
"Date")
542 return SwFieldTypesEnum::Date
;
543 if (rString
== u
"Time")
544 return SwFieldTypesEnum::Time
;
545 if (rString
== u
"Filename")
546 return SwFieldTypesEnum::Filename
;
547 if (rString
== u
"DatabaseName")
548 return SwFieldTypesEnum::DatabaseName
;
549 if (rString
== u
"Chapter")
550 return SwFieldTypesEnum::Chapter
;
551 if (rString
== u
"PageNumber")
552 return SwFieldTypesEnum::PageNumber
;
553 if (rString
== u
"DocumentStatistics")
554 return SwFieldTypesEnum::DocumentStatistics
;
555 if (rString
== u
"Author")
556 return SwFieldTypesEnum::Author
;
557 if (rString
== u
"Set")
558 return SwFieldTypesEnum::Set
;
559 if (rString
== u
"Get")
560 return SwFieldTypesEnum::Get
;
561 if (rString
== u
"Formel")
562 return SwFieldTypesEnum::Formel
;
563 if (rString
== u
"HiddenText")
564 return SwFieldTypesEnum::HiddenText
;
565 if (rString
== u
"SetRef")
566 return SwFieldTypesEnum::SetRef
;
567 return SwFieldTypesEnum::Unknown
;
570 SwValueFieldType::SwValueFieldType(SwDoc
*const pDoc
, SwFieldIds
const nWhichId
)
571 : SwFieldType(nWhichId
)
577 SwValueFieldType::SwValueFieldType( const SwValueFieldType
& rTyp
)
578 : SwFieldType(rTyp
.Which())
579 , m_pDoc(rTyp
.GetDoc())
580 , m_bUseFormat(rTyp
.UseFormat())
584 /// return value formatted as string
585 OUString
SwValueFieldType::ExpandValue( const double& rVal
,
586 sal_uInt32 nFormat
, LanguageType nLng
) const
588 if (rVal
>= DBL_MAX
) // error string for calculator
589 return SwViewShell::GetShellRes()->aCalc_Error
;
592 SvNumberFormatter
* pFormatter
= m_pDoc
->GetNumberFormatter();
593 const Color
* pCol
= nullptr;
596 LanguageType nFormatLng
= ::lcl_GetLanguageOfFormat( nLng
, nFormat
, *pFormatter
);
598 if( nFormat
< SV_COUNTRY_LANGUAGE_OFFSET
&& LANGUAGE_SYSTEM
!= nFormatLng
)
600 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormat
);
602 if (pEntry
&& nLng
!= pEntry
->GetLanguage())
604 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(nFormat
,
606 if (nNewFormat
== nFormat
)
608 // probably user-defined format
609 OUString
sFormat(pEntry
->GetFormatstring());
611 SvNumFormatType nType
= SvNumFormatType::DEFINED
;
613 pFormatter
->PutandConvertEntry(sFormat
, nDummy
, nType
, nFormat
,
614 pEntry
->GetLanguage(), nFormatLng
, false);
617 nFormat
= nNewFormat
;
619 OSL_ENSURE(pEntry
, "unknown number format!");
622 if( pFormatter
->IsTextFormat( nFormat
) )
624 pFormatter
->GetOutputString(DoubleToString(rVal
, nFormatLng
), nFormat
,
629 pFormatter
->GetOutputString(rVal
, nFormat
, sExpand
, &pCol
);
634 OUString
SwValueFieldType::DoubleToString(const double &rVal
,
635 sal_uInt32 nFormat
) const
637 SvNumberFormatter
* pFormatter
= m_pDoc
->GetNumberFormatter();
638 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormat
);
643 return DoubleToString(rVal
, pEntry
->GetLanguage());
646 OUString
SwValueFieldType::DoubleToString( const double &rVal
,
647 LanguageType nLng
) const
649 SvNumberFormatter
* pFormatter
= m_pDoc
->GetNumberFormatter();
652 if( nLng
== LANGUAGE_NONE
)
653 nLng
= LANGUAGE_SYSTEM
;
655 pFormatter
->ChangeIntl( nLng
); // get separator in the correct language
656 return ::rtl::math::doubleToUString( rVal
, rtl_math_StringFormat_F
, 12,
657 pFormatter
->GetNumDecimalSep()[0], true );
660 OUString
SwValueFieldType::GetInputOrDateTime( const OUString
& rInput
, const double& rVal
, sal_uInt32 nFormat
) const
662 if (nFormat
&& nFormat
!= SAL_MAX_UINT32
&& UseFormat())
664 SvNumberFormatter
* pFormatter
= m_pDoc
->GetNumberFormatter();
665 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormat
);
666 if (pEntry
&& (pEntry
->GetType() & SvNumFormatType::DATETIME
))
669 pFormatter
->GetInputLineString( rVal
, nFormat
, aEdit
);
676 SwValueField::SwValueField( SwValueFieldType
* pFieldType
, sal_uInt32 nFormat
,
677 LanguageType nLng
, const double fVal
)
678 : SwField(pFieldType
, nFormat
, nLng
)
683 SwValueField::SwValueField( const SwValueField
& rField
)
685 , m_fValue(rField
.GetValue())
689 SwValueField::~SwValueField()
695 * This is needed/used for copying between documents.
696 * Needs to be always of the same type.
697 * @param pNewType The new type.
698 * @return The old type.
700 SwFieldType
* SwValueField::ChgTyp( SwFieldType
* pNewType
)
702 SwDoc
* pNewDoc
= static_cast<SwValueFieldType
*>(pNewType
)->GetDoc();
703 SwDoc
* pDoc
= GetDoc();
705 if( pNewDoc
&& pDoc
&& pDoc
!= pNewDoc
)
707 SvNumberFormatter
* pFormatter
= pNewDoc
->GetNumberFormatter();
709 if( pFormatter
&& pFormatter
->HasMergeFormatTable() &&
710 static_cast<SwValueFieldType
*>(GetTyp())->UseFormat() )
711 SetFormat(pFormatter
->GetMergeFormatIndex( GetFormat() ));
714 return SwField::ChgTyp(pNewType
);
717 /// get format in office language
718 sal_uInt32
SwValueField::GetSystemFormat(SvNumberFormatter
* pFormatter
, sal_uInt32 nFormat
)
720 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFormat
);
721 LanguageType nLng
= SvtSysLocale().GetLanguageTag().getLanguageType();
723 if (pEntry
&& nLng
!= pEntry
->GetLanguage())
725 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(nFormat
,
728 if (nNewFormat
== nFormat
)
730 // probably user-defined format
731 SvNumFormatType nType
= SvNumFormatType::DEFINED
;
734 OUString
sFormat(pEntry
->GetFormatstring());
736 sal_uInt32 nTempFormat
= nFormat
;
737 pFormatter
->PutandConvertEntry(sFormat
, nDummy
, nType
,
738 nTempFormat
, pEntry
->GetLanguage(), nLng
, true);
739 nFormat
= nTempFormat
;
742 nFormat
= nNewFormat
;
748 void SwValueField::dumpAsXml(xmlTextWriterPtr pWriter
) const
750 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwValueField"));
751 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_fValue"), BAD_CAST(OString::number(m_fValue
).getStr()));
752 SwField::dumpAsXml(pWriter
);
753 (void)xmlTextWriterEndElement(pWriter
);
756 /// set language of the format
757 void SwValueField::SetLanguage( LanguageType nLng
)
759 if( IsAutomaticLanguage() &&
760 static_cast<SwValueFieldType
*>(GetTyp())->UseFormat() &&
761 GetFormat() != SAL_MAX_UINT32
)
764 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
765 LanguageType nFormatLng
= ::lcl_GetLanguageOfFormat( nLng
, GetFormat(),
768 if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET
||
769 LANGUAGE_SYSTEM
!= nFormatLng
) &&
770 !(Which() == SwFieldIds::User
&& (GetSubType()&nsSwExtendedSubType::SUB_CMD
) ) )
772 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(GetFormat());
774 if( pEntry
&& nFormatLng
!= pEntry
->GetLanguage() )
776 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(
777 GetFormat(), nFormatLng
);
779 if( nNewFormat
== GetFormat() )
781 // probably user-defined format
782 SvNumFormatType nType
= SvNumFormatType::DEFINED
;
784 OUString
sFormat( pEntry
->GetFormatstring() );
785 pFormatter
->PutandConvertEntry( sFormat
, nDummy
, nType
,
787 pEntry
->GetLanguage(),
790 SetFormat( nNewFormat
);
792 OSL_ENSURE(pEntry
, "unknown number format!");
796 SwField::SetLanguage(nLng
);
799 double SwValueField::GetValue() const
804 void SwValueField::SetValue( const double& rVal
)
809 SwFormulaField::SwFormulaField( SwValueFieldType
* pFieldType
, sal_uInt32 nFormat
, const double fVal
)
810 : SwValueField(pFieldType
, nFormat
, LANGUAGE_SYSTEM
, fVal
)
814 SwFormulaField::SwFormulaField( const SwFormulaField
& rField
)
815 : SwValueField(static_cast<SwValueFieldType
*>(rField
.GetTyp()), rField
.GetFormat(),
816 rField
.GetLanguage(), rField
.GetValue())
820 OUString
SwFormulaField::GetFormula() const
825 void SwFormulaField::SetFormula(const OUString
& rStr
)
829 sal_uLong
nFormat(GetFormat());
831 if( nFormat
&& SAL_MAX_UINT32
!= nFormat
)
835 // Uses the SwCalc document locale.
836 if( SwCalc::Str2Double( rStr
, nPos
, fTmpValue
, GetDoc() ) )
837 SwValueField::SetValue( fTmpValue
);
841 void SwFormulaField::SetExpandedFormula( const OUString
& rStr
)
843 sal_uInt32
nFormat(GetFormat());
845 if (nFormat
&& nFormat
!= SAL_MAX_UINT32
&& static_cast<SwValueFieldType
*>(GetTyp())->UseFormat())
849 if (GetDoc()->IsNumberFormat(rStr
, nFormat
, fTmpValue
))
851 SwValueField::SetValue(fTmpValue
);
853 // Will get reinterpreted by SwCalc when updating fields, so use
854 // the proper locale.
855 m_sFormula
= static_cast<SwValueFieldType
*>(GetTyp())->DoubleToString( fTmpValue
,
856 SwCalc::GetDocAppScriptLang( *GetDoc()));
863 OUString
SwFormulaField::GetExpandedFormula() const
865 sal_uInt32
nFormat(GetFormat());
867 if (nFormat
&& nFormat
!= SAL_MAX_UINT32
&& static_cast<SwValueFieldType
*>(GetTyp())->UseFormat())
869 OUString sFormattedValue
;
870 const Color
* pCol
= nullptr;
872 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
874 if (pFormatter
->IsTextFormat(nFormat
))
876 OUString
sTempIn(static_cast<SwValueFieldType
*>(GetTyp())->DoubleToString(GetValue(), nFormat
));
877 pFormatter
->GetOutputString(sTempIn
, nFormat
, sFormattedValue
, &pCol
);
881 pFormatter
->GetOutputString(GetValue(), nFormat
, sFormattedValue
, &pCol
);
883 return sFormattedValue
;
889 OUString
SwFormulaField::GetInputOrDateTime() const
891 // GetFormula() leads to problems with date formats because only the
892 // number string without formatting is returned (additionally that may or
893 // may not use a localized decimal separator due to the convoluted handling
894 // of "formula"). It must be used for expressions though because otherwise
895 // with GetPar2() only the value calculated by SwCalc would be displayed
896 // (instead of test2 = test + 1).
897 // Force a formatted edit value for date+time formats, assuming they are
898 // not editable calculated expressions if the formula doesn't contain
899 // arithmetic operators or assignment.
901 const OUString
aFormula( GetFormula());
903 if (comphelper::string::indexOfAny( aFormula
, u
"=+-*/", 0) == -1)
904 return static_cast<SwValueFieldType
*>(GetTyp())->GetInputOrDateTime( aFormula
, GetValue(), GetFormat());
909 OUString
SwField::GetDescription() const
911 return SwResId(STR_FIELD
);
914 bool SwField::IsClickable() const
918 case SwFieldIds::JumpEdit
:
919 case SwFieldIds::Macro
:
920 case SwFieldIds::GetRef
:
921 case SwFieldIds::Input
:
922 case SwFieldIds::SetExp
:
923 case SwFieldIds::Dropdown
:
924 case SwFieldIds::TableOfAuthorities
:
931 void SwField::dumpAsXml(xmlTextWriterPtr pWriter
) const
933 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwField"));
934 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
935 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
936 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_nFormat"), BAD_CAST(OString::number(m_nFormat
).getStr()));
937 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_nLang"), BAD_CAST(OString::number(m_nLang
.get()).getStr()));
938 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("m_aTitle"), BAD_CAST(m_aTitle
.toUtf8().getStr()));
940 (void)xmlTextWriterEndElement(pWriter
);
943 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */