nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / core / fields / fldbas.cxx
blobcbc73b27bcfb797225b8c78b7fe1c11acd690f69
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 <fldbas.hxx>
22 #include <float.h>
24 #include <libxml/xmlwriter.h>
26 #include <rtl/math.hxx>
27 #include <svl/zforlist.hxx>
28 #include <svl/zformat.hxx>
29 #include <o3tl/enumarray.hxx>
30 #include <osl/diagnose.h>
31 #include <unofldmid.h>
32 #include <doc.hxx>
33 #include <fmtfld.hxx>
34 #include <docufld.hxx>
35 #include <expfld.hxx>
36 #include <shellres.hxx>
37 #include <calc.hxx>
38 #include <strings.hrc>
39 #include <docary.hxx>
40 #include <authfld.hxx>
41 #include <calbck.hxx>
42 #include <viewsh.hxx>
43 #include <hints.hxx>
45 using namespace ::com::sun::star;
46 using namespace nsSwDocInfoSubType;
48 static LanguageType lcl_GetLanguageOfFormat( LanguageType nLng, sal_uLong nFormat,
49 const SvNumberFormatter& rFormatter )
51 if( nLng == LANGUAGE_NONE ) // Bug #60010
52 nLng = LANGUAGE_SYSTEM;
53 else if( nLng == ::GetAppLanguage() )
54 switch( rFormatter.GetIndexTableOffset( nFormat ))
56 case NF_NUMBER_SYSTEM:
57 case NF_DATE_SYSTEM_SHORT:
58 case NF_DATE_SYSTEM_LONG:
59 case NF_DATETIME_SYSTEM_SHORT_HHMM:
60 nLng = LANGUAGE_SYSTEM;
61 break;
62 default: break;
64 return nLng;
67 // Globals
69 /// field names
70 std::vector<OUString>* SwFieldType::s_pFieldNames = nullptr;
72 namespace
75 const o3tl::enumarray<SwFieldIds,SwFieldTypesEnum> aTypeTab {
76 /* SwFieldIds::Database */ SwFieldTypesEnum::Database,
77 /* SwFieldIds::User */ SwFieldTypesEnum::User,
78 /* SwFieldIds::Filename */ SwFieldTypesEnum::Filename,
79 /* SwFieldIds::DatabaseName */ SwFieldTypesEnum::DatabaseName,
80 /* SwFieldIds::Date */ SwFieldTypesEnum::Date,
81 /* SwFieldIds::Time */ SwFieldTypesEnum::Time,
82 /* SwFieldIds::PageNumber */ SwFieldTypesEnum::PageNumber, // dynamic
83 /* SwFieldIds::Author */ SwFieldTypesEnum::Author,
84 /* SwFieldIds::Chapter */ SwFieldTypesEnum::Chapter,
85 /* SwFieldIds::DocStat */ SwFieldTypesEnum::DocumentStatistics,
86 /* SwFieldIds::GetExp */ SwFieldTypesEnum::Get, // dynamic
87 /* SwFieldIds::SetExp */ SwFieldTypesEnum::Set, // dynamic
88 /* SwFieldIds::GetRef */ SwFieldTypesEnum::GetRef,
89 /* SwFieldIds::HiddenText */ SwFieldTypesEnum::HiddenText,
90 /* SwFieldIds::Postit */ SwFieldTypesEnum::Postit,
91 /* SwFieldIds::FixDate */ SwFieldTypesEnum::FixedDate,
92 /* SwFieldIds::FixTime */ SwFieldTypesEnum::FixedTime,
93 /* SwFieldIds::Reg */ SwFieldTypesEnum::Begin, // old (no change since 2000)
94 /* SwFieldIds::VarReg */ SwFieldTypesEnum::Begin, // old (no change since 2000)
95 /* SwFieldIds::SetRef */ SwFieldTypesEnum::SetRef,
96 /* SwFieldIds::Input */ SwFieldTypesEnum::Input,
97 /* SwFieldIds::Macro */ SwFieldTypesEnum::Macro,
98 /* SwFieldIds::Dde */ SwFieldTypesEnum::DDE,
99 /* SwFieldIds::Table */ SwFieldTypesEnum::Formel,
100 /* SwFieldIds::HiddenPara */ SwFieldTypesEnum::HiddenParagraph,
101 /* SwFieldIds::DocInfo */ SwFieldTypesEnum::DocumentInfo,
102 /* SwFieldIds::TemplateName */ SwFieldTypesEnum::TemplateName,
103 /* SwFieldIds::DbNextSet */ SwFieldTypesEnum::DatabaseNextSet,
104 /* SwFieldIds::DbNumSet */ SwFieldTypesEnum::DatabaseNumberSet,
105 /* SwFieldIds::DbSetNumber */ SwFieldTypesEnum::DatabaseSetNumber,
106 /* SwFieldIds::ExtUser */ SwFieldTypesEnum::ExtendedUser,
107 /* SwFieldIds::RefPageSet */ SwFieldTypesEnum::SetRefPage,
108 /* SwFieldIds::RefPageGet */ SwFieldTypesEnum::GetRefPage,
109 /* SwFieldIds::Internet */ SwFieldTypesEnum::Internet,
110 /* SwFieldIds::JumpEdit */ SwFieldTypesEnum::JumpEdit,
111 /* SwFieldIds::Script */ SwFieldTypesEnum::Script,
112 /* SwFieldIds::DateTime */ SwFieldTypesEnum::Begin, // dynamic
113 /* SwFieldIds::TableOfAuthorities*/ SwFieldTypesEnum::Authority,
114 /* SwFieldIds::CombinedChars */ SwFieldTypesEnum::CombinedChars,
115 /* SwFieldIds::Dropdown */ SwFieldTypesEnum::Dropdown,
116 /* SwFieldIds::ParagraphSignature */ SwFieldTypesEnum::ParagraphSignature
121 OUString SwFieldType::GetTypeStr(SwFieldTypesEnum nTypeId)
123 if (!s_pFieldNames)
124 GetFieldName_();
126 return (*SwFieldType::s_pFieldNames)[static_cast<int>(nTypeId)];
129 // each field references a field type that is unique for each document
130 SwFieldType::SwFieldType( SwFieldIds nWhichId )
131 : sw::BroadcastingModify()
132 , m_nWhich(nWhichId)
136 OUString SwFieldType::GetName() const
138 return OUString();
141 void SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const
144 void SwFieldType::PutValue( const uno::Any& , sal_uInt16 )
148 void SwFieldType::UpdateFields() const
150 const_cast<SwFieldType*>(this)->SwClientNotify(*this, sw::LegacyModifyHint(nullptr, nullptr));
153 void SwFieldType::PrintHiddenPara()
155 const SwMsgPoolItem aHint(RES_HIDDENPARA_PRINT);
156 SwClientNotify(*this, sw::LegacyModifyHint(&aHint, nullptr));
159 void SwFieldType::dumpAsXml(xmlTextWriterPtr pWriter) const
161 std::vector<SwFormatField*> vFields;
162 GatherFields(vFields);
163 if(!vFields.size())
164 return;
165 xmlTextWriterStartElement(pWriter, BAD_CAST("SwFieldType"));
166 for(const auto pFormatField: vFields)
167 pFormatField->dumpAsXml(pWriter);
168 xmlTextWriterEndElement(pWriter);
171 SwFormatField* SwFieldType::FindFormatForField(const SwField* pField) const {
172 SwFormatField* pFormat = nullptr;
173 CallSwClientNotify(sw::FindFormatForFieldHint(pField, pFormat));
174 return pFormat;
177 SwFormatField* SwFieldType::FindFormatForPostItId(sal_uInt32 nPostItId) const {
178 SwFormatField* pFormat = nullptr;
179 CallSwClientNotify(sw::FindFormatForPostItIdHint(nPostItId, pFormat));
180 return 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<sal_uLong>& 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 SwFieldTypes::dumpAsXml(xmlTextWriterPtr pWriter) const
217 xmlTextWriterStartElement(pWriter, BAD_CAST("SwFieldTypes"));
218 sal_uInt16 nCount = size();
219 for (sal_uInt16 nType = 0; nType < nCount; ++nType)
220 (*this)[nType]->dumpAsXml(pWriter);
221 xmlTextWriterEndElement(pWriter);
224 // Base class for all fields.
225 // A field (multiple can exist) references a field type (can exists only once)
226 SwField::SwField(
227 SwFieldType* pType,
228 sal_uInt32 nFormat,
229 LanguageType nLang,
230 bool bUseFieldValueCache)
231 : m_Cache()
232 , m_pType( pType )
233 , m_nFormat( nFormat )
234 , m_nLang( nLang )
235 , m_bUseFieldValueCache( bUseFieldValueCache )
236 , m_bIsAutomaticLanguage( true )
238 assert(m_pType);
241 SwField::~SwField()
245 // instead of indirectly via the type
247 #ifdef DBG_UTIL
248 SwFieldIds SwField::Which() const
250 assert(m_pType);
251 return m_pType->Which();
253 #endif
255 SwFieldTypesEnum SwField::GetTypeId() const
258 SwFieldTypesEnum nRet;
259 switch (m_pType->Which())
261 case SwFieldIds::DateTime:
262 if (GetSubType() & FIXEDFLD)
263 nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::FixedDate : SwFieldTypesEnum::FixedTime;
264 else
265 nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::Date : SwFieldTypesEnum::Time;
266 break;
267 case SwFieldIds::GetExp:
268 nRet = nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? SwFieldTypesEnum::Formel : SwFieldTypesEnum::Get;
269 break;
271 case SwFieldIds::HiddenText:
272 nRet = static_cast<SwFieldTypesEnum>(GetSubType());
273 break;
275 case SwFieldIds::SetExp:
276 if( nsSwGetSetExpType::GSE_SEQ & GetSubType() )
277 nRet = SwFieldTypesEnum::Sequence;
278 else if( static_cast<const SwSetExpField*>(this)->GetInputFlag() )
279 nRet = SwFieldTypesEnum::SetInput;
280 else
281 nRet = SwFieldTypesEnum::Set;
282 break;
284 case SwFieldIds::PageNumber:
286 auto nSubType = GetSubType();
287 if( PG_NEXT == nSubType )
288 nRet = SwFieldTypesEnum::NextPage;
289 else if( PG_PREV == nSubType )
290 nRet = SwFieldTypesEnum::PreviousPage;
291 else
292 nRet = SwFieldTypesEnum::PageNumber;
294 break;
296 default:
297 nRet = aTypeTab[ m_pType->Which() ];
299 return nRet;
302 /// get name or content
303 OUString SwField::GetFieldName() const
305 SwFieldTypesEnum nTypeId = GetTypeId();
306 if (SwFieldIds::DateTime == GetTyp()->Which())
308 nTypeId =
309 ((GetSubType() & DATEFLD) != 0) ? SwFieldTypesEnum::Date : SwFieldTypesEnum::Time;
311 OUString sRet = SwFieldType::GetTypeStr( nTypeId );
312 if (IsFixed())
314 sRet += " " + SwViewShell::GetShellRes()->aFixedStr;
316 return sRet;
319 OUString SwField::GetPar1() const
321 return OUString();
324 OUString SwField::GetPar2() const
326 return OUString();
329 OUString SwField::GetFormula() const
331 return GetPar2();
334 void SwField::SetPar1(const OUString& )
337 void SwField::SetPar2(const OUString& )
340 sal_uInt16 SwField::GetSubType() const
342 return 0;
345 void SwField::SetSubType(sal_uInt16 )
349 bool SwField::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
351 switch( nWhichId )
353 case FIELD_PROP_BOOL4:
354 rVal <<= !m_bIsAutomaticLanguage;
355 break;
356 default:
357 assert(false);
359 return true;
362 bool SwField::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
364 switch( nWhichId )
366 case FIELD_PROP_BOOL4:
368 bool bFixed = false;
369 if(rVal >>= bFixed)
370 m_bIsAutomaticLanguage = !bFixed;
372 break;
373 default:
374 assert(false);
376 return true;
379 /** Set a new type
381 * This is needed/used for copying between documents.
382 * Needs to be always of the same type.
383 * @param pNewType The new type.
384 * @return The old type.
386 SwFieldType* SwField::ChgTyp( SwFieldType* pNewType )
388 assert(pNewType && pNewType->Which() == m_pType->Which());
390 SwFieldType* pOld = m_pType;
391 m_pType = pNewType;
392 return pOld;
395 /// Does the field have an action on a ClickHandler? (E.g. INetFields,...)
396 bool SwField::HasClickHdl() const
398 bool bRet = false;
399 switch (m_pType->Which())
401 case SwFieldIds::Internet:
402 case SwFieldIds::JumpEdit:
403 case SwFieldIds::GetRef:
404 case SwFieldIds::Macro:
405 case SwFieldIds::Input:
406 case SwFieldIds::Dropdown :
407 bRet = true;
408 break;
410 case SwFieldIds::SetExp:
411 bRet = static_cast<const SwSetExpField*>(this)->GetInputFlag();
412 break;
413 default: break;
415 return bRet;
418 void SwField::SetLanguage(LanguageType const nLang)
420 m_nLang = nLang;
423 void SwField::ChangeFormat(sal_uInt32 const nFormat)
425 m_nFormat = nFormat;
428 bool SwField::IsFixed() const
430 bool bRet = false;
431 switch (m_pType->Which())
433 case SwFieldIds::FixDate:
434 case SwFieldIds::FixTime:
435 bRet = true;
436 break;
438 case SwFieldIds::DateTime:
439 bRet = 0 != (GetSubType() & FIXEDFLD);
440 break;
442 case SwFieldIds::ExtUser:
443 case SwFieldIds::Author:
444 bRet = 0 != (GetFormat() & AF_FIXED);
445 break;
447 case SwFieldIds::Filename:
448 bRet = 0 != (GetFormat() & FF_FIXED);
449 break;
451 case SwFieldIds::DocInfo:
452 bRet = 0 != (GetSubType() & DI_SUB_FIXED);
453 break;
454 default: break;
456 return bRet;
459 OUString
460 SwField::ExpandField(bool const bCached, SwRootFrame const*const pLayout) const
462 if ( m_bUseFieldValueCache )
464 if (!bCached) // #i85766# do not expand fields in clipboard documents
466 if (GetTypeId() == SwFieldTypesEnum::Authority)
468 const SwAuthorityField* pAuthorityField = static_cast<const SwAuthorityField*>(this);
469 m_Cache = pAuthorityField->ConditionalExpandAuthIdentifier(pLayout);
471 else
472 m_Cache = ExpandImpl(pLayout);
474 return m_Cache;
477 return ExpandImpl(pLayout);
480 std::unique_ptr<SwField> SwField::CopyField() const
482 std::unique_ptr<SwField> pNew = Copy();
483 // #i85766# cache expansion of source (for clipboard)
484 // use this->cache, not this->Expand(): only text formatting calls Expand()
485 pNew->m_Cache = m_Cache;
486 pNew->m_bUseFieldValueCache = m_bUseFieldValueCache;
488 return pNew;
491 /// expand numbering
492 OUString FormatNumber(sal_uInt32 nNum, SvxNumType nFormat, LanguageType nLang)
494 if(SVX_NUM_PAGEDESC == nFormat)
495 return OUString::number( nNum );
496 SvxNumberType aNumber;
498 OSL_ENSURE(nFormat != SVX_NUM_NUMBER_NONE, "wrong number format" );
500 aNumber.SetNumberingType(nFormat);
502 if (nLang == LANGUAGE_NONE)
503 return aNumber.GetNumStr(nNum);
504 else
505 return aNumber.GetNumStr(nNum, LanguageTag::convertToLocale(nLang));
508 SwValueFieldType::SwValueFieldType(SwDoc *const pDoc, SwFieldIds const nWhichId)
509 : SwFieldType(nWhichId)
510 , m_pDoc(pDoc)
511 , m_bUseFormat(true)
515 SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp )
516 : SwFieldType(rTyp.Which())
517 , m_pDoc(rTyp.GetDoc())
518 , m_bUseFormat(rTyp.UseFormat())
522 /// return value formatted as string
523 OUString SwValueFieldType::ExpandValue( const double& rVal,
524 sal_uInt32 nFormat, LanguageType nLng) const
526 if (rVal >= DBL_MAX) // error string for calculator
527 return SwViewShell::GetShellRes()->aCalc_Error;
529 OUString sExpand;
530 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
531 const Color* pCol = nullptr;
533 // Bug #60010
534 LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, nFormat, *pFormatter );
536 if( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFormatLng )
538 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
540 if (pEntry && nLng != pEntry->GetLanguage())
542 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
543 nFormatLng);
544 if (nNewFormat == nFormat)
546 // probably user-defined format
547 OUString sFormat(pEntry->GetFormatstring());
548 sal_Int32 nDummy;
549 SvNumFormatType nType = SvNumFormatType::DEFINED;
551 pFormatter->PutandConvertEntry(sFormat, nDummy, nType, nFormat,
552 pEntry->GetLanguage(), nFormatLng, false);
554 else
555 nFormat = nNewFormat;
557 OSL_ENSURE(pEntry, "unknown number format!");
560 if( pFormatter->IsTextFormat( nFormat ) )
562 pFormatter->GetOutputString(DoubleToString(rVal, nFormatLng), nFormat,
563 sExpand, &pCol);
565 else
567 pFormatter->GetOutputString(rVal, nFormat, sExpand, &pCol);
569 return sExpand;
572 OUString SwValueFieldType::DoubleToString(const double &rVal,
573 sal_uInt32 nFormat) const
575 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
576 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
578 if (!pEntry)
579 return OUString();
581 return DoubleToString(rVal, pEntry->GetLanguage());
584 OUString SwValueFieldType::DoubleToString( const double &rVal,
585 LanguageType nLng ) const
587 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
589 // Bug #60010
590 if( nLng == LANGUAGE_NONE )
591 nLng = LANGUAGE_SYSTEM;
593 pFormatter->ChangeIntl( nLng ); // get separator in the correct language
594 return ::rtl::math::doubleToUString( rVal, rtl_math_StringFormat_F, 12,
595 pFormatter->GetNumDecimalSep()[0], true );
598 SwValueField::SwValueField( SwValueFieldType* pFieldType, sal_uInt32 nFormat,
599 LanguageType nLng, const double fVal )
600 : SwField(pFieldType, nFormat, nLng)
601 , m_fValue(fVal)
605 SwValueField::SwValueField( const SwValueField& rField )
606 : SwField(rField)
607 , m_fValue(rField.GetValue())
611 SwValueField::~SwValueField()
615 /** Set a new type
617 * This is needed/used for copying between documents.
618 * Needs to be always of the same type.
619 * @param pNewType The new type.
620 * @return The old type.
622 SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType )
624 SwDoc* pNewDoc = static_cast<SwValueFieldType *>(pNewType)->GetDoc();
625 SwDoc* pDoc = GetDoc();
627 if( pNewDoc && pDoc && pDoc != pNewDoc)
629 SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter();
631 if( pFormatter && pFormatter->HasMergeFormatTable() &&
632 static_cast<SwValueFieldType *>(GetTyp())->UseFormat() )
633 SetFormat(pFormatter->GetMergeFormatIndex( GetFormat() ));
636 return SwField::ChgTyp(pNewType);
639 /// get format in office language
640 sal_uInt32 SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, sal_uInt32 nFormat)
642 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
643 LanguageType nLng = SvtSysLocale().GetLanguageTag().getLanguageType();
645 if (pEntry && nLng != pEntry->GetLanguage())
647 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
648 nLng);
650 if (nNewFormat == nFormat)
652 // probably user-defined format
653 SvNumFormatType nType = SvNumFormatType::DEFINED;
654 sal_Int32 nDummy;
656 OUString sFormat(pEntry->GetFormatstring());
658 sal_uInt32 nTempFormat = nFormat;
659 pFormatter->PutandConvertEntry(sFormat, nDummy, nType,
660 nTempFormat, pEntry->GetLanguage(), nLng, true);
661 nFormat = nTempFormat;
663 else
664 nFormat = nNewFormat;
667 return nFormat;
670 void SwValueField::dumpAsXml(xmlTextWriterPtr pWriter) const
672 xmlTextWriterStartElement(pWriter, BAD_CAST("SwValueField"));
673 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_fValue"), BAD_CAST(OString::number(m_fValue).getStr()));
674 SwField::dumpAsXml(pWriter);
675 xmlTextWriterEndElement(pWriter);
678 /// set language of the format
679 void SwValueField::SetLanguage( LanguageType nLng )
681 if( IsAutomaticLanguage() &&
682 static_cast<SwValueFieldType *>(GetTyp())->UseFormat() &&
683 GetFormat() != SAL_MAX_UINT32 )
685 // Bug #60010
686 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
687 LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(),
688 *pFormatter );
690 if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
691 LANGUAGE_SYSTEM != nFormatLng ) &&
692 !(Which() == SwFieldIds::User && (GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
694 const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
696 if( pEntry && nFormatLng != pEntry->GetLanguage() )
698 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(
699 GetFormat(), nFormatLng );
701 if( nNewFormat == GetFormat() )
703 // probably user-defined format
704 SvNumFormatType nType = SvNumFormatType::DEFINED;
705 sal_Int32 nDummy;
706 OUString sFormat( pEntry->GetFormatstring() );
707 pFormatter->PutandConvertEntry( sFormat, nDummy, nType,
708 nNewFormat,
709 pEntry->GetLanguage(),
710 nFormatLng, false);
712 SetFormat( nNewFormat );
714 OSL_ENSURE(pEntry, "unknown number format!");
718 SwField::SetLanguage(nLng);
721 double SwValueField::GetValue() const
723 return m_fValue;
726 void SwValueField::SetValue( const double& rVal )
728 m_fValue = rVal;
731 SwFormulaField::SwFormulaField( SwValueFieldType* pFieldType, sal_uInt32 nFormat, const double fVal)
732 : SwValueField(pFieldType, nFormat, LANGUAGE_SYSTEM, fVal)
736 SwFormulaField::SwFormulaField( const SwFormulaField& rField )
737 : SwValueField(static_cast<SwValueFieldType *>(rField.GetTyp()), rField.GetFormat(),
738 rField.GetLanguage(), rField.GetValue())
742 OUString SwFormulaField::GetFormula() const
744 return m_sFormula;
747 void SwFormulaField::SetFormula(const OUString& rStr)
749 m_sFormula = rStr;
751 sal_uLong nFormat(GetFormat());
753 if( nFormat && SAL_MAX_UINT32 != nFormat )
755 sal_Int32 nPos = 0;
756 double fTmpValue;
757 if( SwCalc::Str2Double( rStr, nPos, fTmpValue, GetDoc() ) )
758 SwValueField::SetValue( fTmpValue );
762 void SwFormulaField::SetExpandedFormula( const OUString& rStr )
764 sal_uInt32 nFormat(GetFormat());
766 if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
768 double fTmpValue;
770 if (GetDoc()->IsNumberFormat(rStr, nFormat, fTmpValue))
772 SwValueField::SetValue(fTmpValue);
774 m_sFormula = static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(fTmpValue, nFormat);
775 return;
778 m_sFormula = rStr;
781 OUString SwFormulaField::GetExpandedFormula() const
783 sal_uInt32 nFormat(GetFormat());
785 if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
787 OUString sFormattedValue;
788 const Color* pCol = nullptr;
790 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
792 if (pFormatter->IsTextFormat(nFormat))
794 OUString sTempIn(static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(GetValue(), nFormat));
795 pFormatter->GetOutputString(sTempIn, nFormat, sFormattedValue, &pCol);
797 else
799 pFormatter->GetOutputString(GetValue(), nFormat, sFormattedValue, &pCol);
801 return sFormattedValue;
803 else
804 return GetFormula();
807 OUString SwField::GetDescription() const
809 return SwResId(STR_FIELD);
812 bool SwField::IsClickable() const
814 switch (Which())
816 case SwFieldIds::JumpEdit:
817 case SwFieldIds::Macro:
818 case SwFieldIds::GetRef:
819 case SwFieldIds::Input:
820 case SwFieldIds::SetExp:
821 case SwFieldIds::Dropdown:
822 return true;
823 default: break;
825 return false;
828 void SwField::dumpAsXml(xmlTextWriterPtr pWriter) const
830 xmlTextWriterStartElement(pWriter, BAD_CAST("SwField"));
831 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
832 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
833 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nFormat"), BAD_CAST(OString::number(m_nFormat).getStr()));
834 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nLang"), BAD_CAST(OString::number(m_nLang.get()).getStr()));
836 xmlTextWriterEndElement(pWriter);
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */