1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <fldbas.hxx>
21
22 #include <float.h>
23 #include <math.h>
24
25 #include <libxml/xmlwriter.h>
26
27 #include <rtl/math.hxx>
28 #include <svl/zforlist.hxx>
29 #include <svl/zformat.hxx>
30 #include <editeng/unolingu.hxx>
31 #include <o3tl/enumarray.hxx>
32 #include <unofldmid.h>
33 #include <doc.hxx>
34 #include <editsh.hxx>
35 #include <frame.hxx>
36 #include <flddat.hxx>
37 #include <ndtxt.hxx>
38 #include <fmtfld.hxx>
39 #include <txtfld.hxx>
40 #include <pam.hxx>
41 #include <docfld.hxx>
42 #include <swtable.hxx>
43 #include <docufld.hxx>
44 #include <expfld.hxx>
45 #include <shellres.hxx>
46 #include <calc.hxx>
47 #include <strings.hrc>
48 #include <docary.hxx>
49 #include <authfld.hxx>
50 #include <calbck.hxx>
51
52 using namespace ::com::sun::star;
53 using namespace nsSwDocInfoSubType;
54
lcl_GetLanguageOfFormat(LanguageType nLng,sal_uLong nFormat,const SvNumberFormatter & rFormatter)55 static LanguageType lcl_GetLanguageOfFormat( LanguageType nLng, sal_uLong nFormat,
56 const SvNumberFormatter& rFormatter )
57 {
58 if( nLng == LANGUAGE_NONE ) // Bug #60010
59 nLng = LANGUAGE_SYSTEM;
60 else if( nLng == ::GetAppLanguage() )
61 switch( rFormatter.GetIndexTableOffset( nFormat ))
62 {
63 case NF_NUMBER_SYSTEM:
64 case NF_DATE_SYSTEM_SHORT:
65 case NF_DATE_SYSTEM_LONG:
66 case NF_DATETIME_SYSTEM_SHORT_HHMM:
67 nLng = LANGUAGE_SYSTEM;
68 break;
69 default: break;
70 }
71 return nLng;
72 }
73
74 // Globals
75
76 /// field names
77 std::vector<OUString>* SwFieldType::s_pFieldNames = nullptr;
78
79 namespace
80 {
81
82 const o3tl::enumarray<SwFieldIds,SwFieldTypesEnum> aTypeTab {
83 /* SwFieldIds::Database */ SwFieldTypesEnum::Database,
84 /* SwFieldIds::User */ SwFieldTypesEnum::User,
85 /* SwFieldIds::Filename */ SwFieldTypesEnum::Filename,
86 /* SwFieldIds::DatabaseName */ SwFieldTypesEnum::DatabaseName,
87 /* SwFieldIds::Date */ SwFieldTypesEnum::Date,
88 /* SwFieldIds::Time */ SwFieldTypesEnum::Time,
89 /* SwFieldIds::PageNumber */ SwFieldTypesEnum::PageNumber, // dynamic
90 /* SwFieldIds::Author */ SwFieldTypesEnum::Author,
91 /* SwFieldIds::Chapter */ SwFieldTypesEnum::Chapter,
92 /* SwFieldIds::DocStat */ SwFieldTypesEnum::DocumentStatistics,
93 /* SwFieldIds::GetExp */ SwFieldTypesEnum::Get, // dynamic
94 /* SwFieldIds::SetExp */ SwFieldTypesEnum::Set, // dynamic
95 /* SwFieldIds::GetRef */ SwFieldTypesEnum::GetRef,
96 /* SwFieldIds::HiddenText */ SwFieldTypesEnum::HiddenText,
97 /* SwFieldIds::Postit */ SwFieldTypesEnum::Postit,
98 /* SwFieldIds::FixDate */ SwFieldTypesEnum::FixedDate,
99 /* SwFieldIds::FixTime */ SwFieldTypesEnum::FixedTime,
100 /* SwFieldIds::Reg */ SwFieldTypesEnum::Begin, // old (no change since 2000)
101 /* SwFieldIds::VarReg */ SwFieldTypesEnum::Begin, // old (no change since 2000)
102 /* SwFieldIds::SetRef */ SwFieldTypesEnum::SetRef,
103 /* SwFieldIds::Input */ SwFieldTypesEnum::Input,
104 /* SwFieldIds::Macro */ SwFieldTypesEnum::Macro,
105 /* SwFieldIds::Dde */ SwFieldTypesEnum::DDE,
106 /* SwFieldIds::Table */ SwFieldTypesEnum::Formel,
107 /* SwFieldIds::HiddenPara */ SwFieldTypesEnum::HiddenParagraph,
108 /* SwFieldIds::DocInfo */ SwFieldTypesEnum::DocumentInfo,
109 /* SwFieldIds::TemplateName */ SwFieldTypesEnum::TemplateName,
110 /* SwFieldIds::DbNextSet */ SwFieldTypesEnum::DatabaseNextSet,
111 /* SwFieldIds::DbNumSet */ SwFieldTypesEnum::DatabaseNumberSet,
112 /* SwFieldIds::DbSetNumber */ SwFieldTypesEnum::DatabaseSetNumber,
113 /* SwFieldIds::ExtUser */ SwFieldTypesEnum::ExtendedUser,
114 /* SwFieldIds::RefPageSet */ SwFieldTypesEnum::SetRefPage,
115 /* SwFieldIds::RefPageGet */ SwFieldTypesEnum::GetRefPage,
116 /* SwFieldIds::Internet */ SwFieldTypesEnum::Internet,
117 /* SwFieldIds::JumpEdit */ SwFieldTypesEnum::JumpEdit,
118 /* SwFieldIds::Script */ SwFieldTypesEnum::Script,
119 /* SwFieldIds::DateTime */ SwFieldTypesEnum::Begin, // dynamic
120 /* SwFieldIds::TableOfAuthorities*/ SwFieldTypesEnum::Authority,
121 /* SwFieldIds::CombinedChars */ SwFieldTypesEnum::CombinedChars,
122 /* SwFieldIds::Dropdown */ SwFieldTypesEnum::Dropdown,
123 /* SwFieldIds::ParagraphSignature */ SwFieldTypesEnum::ParagraphSignature
124 };
125
126 }
127
GetTypeStr(SwFieldTypesEnum nTypeId)128 OUString SwFieldType::GetTypeStr(SwFieldTypesEnum nTypeId)
129 {
130 if (!s_pFieldNames)
131 GetFieldName_();
132
133 return (*SwFieldType::s_pFieldNames)[static_cast<int>(nTypeId)];
134 }
135
136 // each field references a field type that is unique for each document
SwFieldType(SwFieldIds nWhichId)137 SwFieldType::SwFieldType( SwFieldIds nWhichId )
138 : SwModify()
139 , m_nWhich(nWhichId)
140 {
141 }
142
GetName() const143 OUString SwFieldType::GetName() const
144 {
145 return OUString();
146 }
147
QueryValue(uno::Any &,sal_uInt16) const148 void SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const
149 {
150 }
PutValue(const uno::Any &,sal_uInt16)151 void SwFieldType::PutValue( const uno::Any& , sal_uInt16 )
152 {
153 }
154
dumpAsXml(xmlTextWriterPtr pWriter) const155 void SwFieldType::dumpAsXml(xmlTextWriterPtr pWriter) const
156 {
157 SwIterator<SwFormatField, SwFieldType> aIter(*this);
158 if (!aIter.First())
159 return;
160 xmlTextWriterStartElement(pWriter, BAD_CAST("SwFieldType"));
161 for (const SwFormatField* pFormatField = aIter.First(); pFormatField;
162 pFormatField = aIter.Next())
163 pFormatField->dumpAsXml(pWriter);
164 xmlTextWriterEndElement(pWriter);
165 }
166
dumpAsXml(xmlTextWriterPtr pWriter) const167 void SwFieldTypes::dumpAsXml(xmlTextWriterPtr pWriter) const
168 {
169 xmlTextWriterStartElement(pWriter, BAD_CAST("SwFieldTypes"));
170 sal_uInt16 nCount = size();
171 for (sal_uInt16 nType = 0; nType < nCount; ++nType)
172 (*this)[nType]->dumpAsXml(pWriter);
173 xmlTextWriterEndElement(pWriter);
174 }
175
176 // Base class for all fields.
177 // A field (multiple can exist) references a field type (can exists only once)
SwField(SwFieldType * pType,sal_uInt32 nFormat,LanguageType nLang,bool bUseFieldValueCache)178 SwField::SwField(
179 SwFieldType* pType,
180 sal_uInt32 nFormat,
181 LanguageType nLang,
182 bool bUseFieldValueCache)
183 : m_Cache()
184 , m_bUseFieldValueCache( bUseFieldValueCache )
185 , m_nLang( nLang )
186 , m_bIsAutomaticLanguage( true )
187 , m_nFormat( nFormat )
188 , m_pType( pType )
189 {
190 assert(m_pType);
191 }
192
~SwField()193 SwField::~SwField()
194 {
195 }
196
197 // instead of indirectly via the type
198
199 #ifdef DBG_UTIL
Which() const200 SwFieldIds SwField::Which() const
201 {
202 assert(m_pType);
203 return m_pType->Which();
204 }
205 #endif
206
GetTypeId() const207 SwFieldTypesEnum SwField::GetTypeId() const
208 {
209
210 SwFieldTypesEnum nRet;
211 switch (m_pType->Which())
212 {
213 case SwFieldIds::DateTime:
214 if (GetSubType() & FIXEDFLD)
215 nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::FixedDate : SwFieldTypesEnum::FixedTime;
216 else
217 nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::Date : SwFieldTypesEnum::Time;
218 break;
219 case SwFieldIds::GetExp:
220 nRet = nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? SwFieldTypesEnum::Formel : SwFieldTypesEnum::Get;
221 break;
222
223 case SwFieldIds::HiddenText:
224 nRet = static_cast<SwFieldTypesEnum>(GetSubType());
225 break;
226
227 case SwFieldIds::SetExp:
228 if( nsSwGetSetExpType::GSE_SEQ & GetSubType() )
229 nRet = SwFieldTypesEnum::Sequence;
230 else if( static_cast<const SwSetExpField*>(this)->GetInputFlag() )
231 nRet = SwFieldTypesEnum::SetInput;
232 else
233 nRet = SwFieldTypesEnum::Set;
234 break;
235
236 case SwFieldIds::PageNumber:
237 {
238 auto nSubType = GetSubType();
239 if( PG_NEXT == nSubType )
240 nRet = SwFieldTypesEnum::NextPage;
241 else if( PG_PREV == nSubType )
242 nRet = SwFieldTypesEnum::PreviousPage;
243 else
244 nRet = SwFieldTypesEnum::PageNumber;
245 }
246 break;
247
248 default:
249 nRet = aTypeTab[ m_pType->Which() ];
250 }
251 return nRet;
252 }
253
254 /// get name or content
GetFieldName() const255 OUString SwField::GetFieldName() const
256 {
257 SwFieldTypesEnum nTypeId = GetTypeId();
258 if (SwFieldIds::DateTime == GetTyp()->Which())
259 {
260 nTypeId =
261 ((GetSubType() & DATEFLD) != 0) ? SwFieldTypesEnum::Date : SwFieldTypesEnum::Time;
262 }
263 OUString sRet = SwFieldType::GetTypeStr( nTypeId );
264 if (IsFixed())
265 {
266 sRet += " " + SwViewShell::GetShellRes()->aFixedStr;
267 }
268 return sRet;
269 }
270
GetPar1() const271 OUString SwField::GetPar1() const
272 {
273 return OUString();
274 }
275
GetPar2() const276 OUString SwField::GetPar2() const
277 {
278 return OUString();
279 }
280
GetFormula() const281 OUString SwField::GetFormula() const
282 {
283 return GetPar2();
284 }
285
SetPar1(const OUString &)286 void SwField::SetPar1(const OUString& )
287 {}
288
SetPar2(const OUString &)289 void SwField::SetPar2(const OUString& )
290 {}
291
GetSubType() const292 sal_uInt16 SwField::GetSubType() const
293 {
294 return 0;
295 }
296
SetSubType(sal_uInt16)297 void SwField::SetSubType(sal_uInt16 )
298 {
299 }
300
QueryValue(uno::Any & rVal,sal_uInt16 nWhichId) const301 bool SwField::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
302 {
303 switch( nWhichId )
304 {
305 case FIELD_PROP_BOOL4:
306 rVal <<= !m_bIsAutomaticLanguage;
307 break;
308 default:
309 assert(false);
310 }
311 return true;
312 }
313
PutValue(const uno::Any & rVal,sal_uInt16 nWhichId)314 bool SwField::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
315 {
316 switch( nWhichId )
317 {
318 case FIELD_PROP_BOOL4:
319 {
320 bool bFixed = false;
321 if(rVal >>= bFixed)
322 m_bIsAutomaticLanguage = !bFixed;
323 }
324 break;
325 default:
326 assert(false);
327 }
328 return true;
329 }
330
331 /** Set a new type
332 *
333 * This is needed/used for copying between documents.
334 * Needs to be always of the same type.
335 * @param pNewType The new type.
336 * @return The old type.
337 */
ChgTyp(SwFieldType * pNewType)338 SwFieldType* SwField::ChgTyp( SwFieldType* pNewType )
339 {
340 assert(pNewType && pNewType->Which() == m_pType->Which());
341
342 SwFieldType* pOld = m_pType;
343 m_pType = pNewType;
344 return pOld;
345 }
346
347 /// Does the field have an action on a ClickHandler? (E.g. INetFields,...)
HasClickHdl() const348 bool SwField::HasClickHdl() const
349 {
350 bool bRet = false;
351 switch (m_pType->Which())
352 {
353 case SwFieldIds::Internet:
354 case SwFieldIds::JumpEdit:
355 case SwFieldIds::GetRef:
356 case SwFieldIds::Macro:
357 case SwFieldIds::Input:
358 case SwFieldIds::Dropdown :
359 bRet = true;
360 break;
361
362 case SwFieldIds::SetExp:
363 bRet = static_cast<const SwSetExpField*>(this)->GetInputFlag();
364 break;
365 default: break;
366 }
367 return bRet;
368 }
369
SetLanguage(LanguageType const nLang)370 void SwField::SetLanguage(LanguageType const nLang)
371 {
372 m_nLang = nLang;
373 }
374
ChangeFormat(sal_uInt32 const nFormat)375 void SwField::ChangeFormat(sal_uInt32 const nFormat)
376 {
377 m_nFormat = nFormat;
378 }
379
IsFixed() const380 bool SwField::IsFixed() const
381 {
382 bool bRet = false;
383 switch (m_pType->Which())
384 {
385 case SwFieldIds::FixDate:
386 case SwFieldIds::FixTime:
387 bRet = true;
388 break;
389
390 case SwFieldIds::DateTime:
391 bRet = 0 != (GetSubType() & FIXEDFLD);
392 break;
393
394 case SwFieldIds::ExtUser:
395 case SwFieldIds::Author:
396 bRet = 0 != (GetFormat() & AF_FIXED);
397 break;
398
399 case SwFieldIds::Filename:
400 bRet = 0 != (GetFormat() & FF_FIXED);
401 break;
402
403 case SwFieldIds::DocInfo:
404 bRet = 0 != (GetSubType() & DI_SUB_FIXED);
405 break;
406 default: break;
407 }
408 return bRet;
409 }
410
411 OUString
ExpandField(bool const bCached,SwRootFrame const * const pLayout) const412 SwField::ExpandField(bool const bCached, SwRootFrame const*const pLayout) const
413 {
414 if ( m_bUseFieldValueCache )
415 {
416 if (!bCached) // #i85766# do not expand fields in clipboard documents
417 {
418 if (GetTypeId() == SwFieldTypesEnum::Authority)
419 {
420 const SwAuthorityField* pAuthorityField = static_cast<const SwAuthorityField*>(this);
421 m_Cache = pAuthorityField->ConditionalExpandAuthIdentifier(pLayout);
422 }
423 else
424 m_Cache = ExpandImpl(pLayout);
425 }
426 return m_Cache;
427 }
428
429 return ExpandImpl(pLayout);
430 }
431
CopyField() const432 std::unique_ptr<SwField> SwField::CopyField() const
433 {
434 std::unique_ptr<SwField> pNew = Copy();
435 // #i85766# cache expansion of source (for clipboard)
436 // use this->cache, not this->Expand(): only text formatting calls Expand()
437 pNew->m_Cache = m_Cache;
438 pNew->m_bUseFieldValueCache = m_bUseFieldValueCache;
439
440 return pNew;
441 }
442
443 /// expand numbering
FormatNumber(sal_uInt32 nNum,SvxNumType nFormat,LanguageType nLang)444 OUString FormatNumber(sal_uInt32 nNum, SvxNumType nFormat, LanguageType nLang)
445 {
446 if(SVX_NUM_PAGEDESC == nFormat)
447 return OUString::number( nNum );
448 SvxNumberType aNumber;
449
450 OSL_ENSURE(nFormat != SVX_NUM_NUMBER_NONE, "wrong number format" );
451
452 aNumber.SetNumberingType(nFormat);
453
454 if (nLang == LANGUAGE_NONE)
455 return aNumber.GetNumStr(nNum);
456 else
457 return aNumber.GetNumStr(nNum, LanguageTag::convertToLocale(nLang));
458 }
459
SwValueFieldType(SwDoc * const pDoc,SwFieldIds const nWhichId)460 SwValueFieldType::SwValueFieldType(SwDoc *const pDoc, SwFieldIds const nWhichId)
461 : SwFieldType(nWhichId)
462 , m_pDoc(pDoc)
463 , m_bUseFormat(true)
464 {
465 }
466
SwValueFieldType(const SwValueFieldType & rTyp)467 SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp )
468 : SwFieldType(rTyp.Which())
469 , m_pDoc(rTyp.GetDoc())
470 , m_bUseFormat(rTyp.UseFormat())
471 {
472 }
473
474 /// return value formatted as string
ExpandValue(const double & rVal,sal_uInt32 nFormat,LanguageType nLng) const475 OUString SwValueFieldType::ExpandValue( const double& rVal,
476 sal_uInt32 nFormat, LanguageType nLng) const
477 {
478 if (rVal >= DBL_MAX) // error string for calculator
479 return SwViewShell::GetShellRes()->aCalc_Error;
480
481 OUString sExpand;
482 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
483 Color* pCol = nullptr;
484
485 // Bug #60010
486 LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, nFormat, *pFormatter );
487
488 if( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFormatLng )
489 {
490 SvNumFormatType nType = SvNumFormatType::DEFINED;
491 sal_Int32 nDummy;
492
493 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
494
495 if (pEntry && nLng != pEntry->GetLanguage())
496 {
497 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
498 nFormatLng);
499
500 if (nNewFormat == nFormat)
501 {
502 // probably user-defined format
503 OUString sFormat(pEntry->GetFormatstring());
504
505 pFormatter->PutandConvertEntry(sFormat, nDummy, nType, nFormat,
506 pEntry->GetLanguage(), nFormatLng, false);
507 }
508 else
509 nFormat = nNewFormat;
510 }
511 OSL_ENSURE(pEntry, "unknown number format!");
512 }
513
514 if( pFormatter->IsTextFormat( nFormat ) )
515 {
516 pFormatter->GetOutputString(DoubleToString(rVal, nFormatLng), nFormat,
517 sExpand, &pCol);
518 }
519 else
520 {
521 pFormatter->GetOutputString(rVal, nFormat, sExpand, &pCol);
522 }
523 return sExpand;
524 }
525
DoubleToString(const double & rVal,sal_uInt32 nFormat) const526 OUString SwValueFieldType::DoubleToString(const double &rVal,
527 sal_uInt32 nFormat) const
528 {
529 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
530 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
531
532 if (!pEntry)
533 return OUString();
534
535 return DoubleToString(rVal, pEntry->GetLanguage());
536 }
537
DoubleToString(const double & rVal,LanguageType nLng) const538 OUString SwValueFieldType::DoubleToString( const double &rVal,
539 LanguageType nLng ) const
540 {
541 SvNumberFormatter* pFormatter = m_pDoc->GetNumberFormatter();
542
543 // Bug #60010
544 if( nLng == LANGUAGE_NONE )
545 nLng = LANGUAGE_SYSTEM;
546
547 pFormatter->ChangeIntl( nLng ); // get separator in the correct language
548 return ::rtl::math::doubleToUString( rVal, rtl_math_StringFormat_F, 12,
549 pFormatter->GetNumDecimalSep()[0], true );
550 }
551
SwValueField(SwValueFieldType * pFieldType,sal_uInt32 nFormat,LanguageType nLng,const double fVal)552 SwValueField::SwValueField( SwValueFieldType* pFieldType, sal_uInt32 nFormat,
553 LanguageType nLng, const double fVal )
554 : SwField(pFieldType, nFormat, nLng)
555 , m_fValue(fVal)
556 {
557 }
558
SwValueField(const SwValueField & rField)559 SwValueField::SwValueField( const SwValueField& rField )
560 : SwField(rField)
561 , m_fValue(rField.GetValue())
562 {
563 }
564
~SwValueField()565 SwValueField::~SwValueField()
566 {
567 }
568
569 /** Set a new type
570 *
571 * This is needed/used for copying between documents.
572 * Needs to be always of the same type.
573 * @param pNewType The new type.
574 * @return The old type.
575 */
ChgTyp(SwFieldType * pNewType)576 SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType )
577 {
578 SwDoc* pNewDoc = static_cast<SwValueFieldType *>(pNewType)->GetDoc();
579 SwDoc* pDoc = GetDoc();
580
581 if( pNewDoc && pDoc && pDoc != pNewDoc)
582 {
583 SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter();
584
585 if( pFormatter && pFormatter->HasMergeFormatTable() &&
586 static_cast<SwValueFieldType *>(GetTyp())->UseFormat() )
587 SetFormat(pFormatter->GetMergeFormatIndex( GetFormat() ));
588 }
589
590 return SwField::ChgTyp(pNewType);
591 }
592
593 /// get format in office language
GetSystemFormat(SvNumberFormatter * pFormatter,sal_uInt32 nFormat)594 sal_uInt32 SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, sal_uInt32 nFormat)
595 {
596 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormat);
597 LanguageType nLng = SvtSysLocale().GetLanguageTag().getLanguageType();
598
599 if (pEntry && nLng != pEntry->GetLanguage())
600 {
601 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFormat,
602 nLng);
603
604 if (nNewFormat == nFormat)
605 {
606 // probably user-defined format
607 SvNumFormatType nType = SvNumFormatType::DEFINED;
608 sal_Int32 nDummy;
609
610 OUString sFormat(pEntry->GetFormatstring());
611
612 sal_uInt32 nTempFormat = nFormat;
613 pFormatter->PutandConvertEntry(sFormat, nDummy, nType,
614 nTempFormat, pEntry->GetLanguage(), nLng, true);
615 nFormat = nTempFormat;
616 }
617 else
618 nFormat = nNewFormat;
619 }
620
621 return nFormat;
622 }
623
dumpAsXml(xmlTextWriterPtr pWriter) const624 void SwValueField::dumpAsXml(xmlTextWriterPtr pWriter) const
625 {
626 xmlTextWriterStartElement(pWriter, BAD_CAST("SwValueField"));
627 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_fValue"), BAD_CAST(OString::number(m_fValue).getStr()));
628 SwField::dumpAsXml(pWriter);
629 xmlTextWriterEndElement(pWriter);
630 }
631
632 /// set language of the format
SetLanguage(LanguageType nLng)633 void SwValueField::SetLanguage( LanguageType nLng )
634 {
635 if( IsAutomaticLanguage() &&
636 static_cast<SwValueFieldType *>(GetTyp())->UseFormat() &&
637 GetFormat() != SAL_MAX_UINT32 )
638 {
639 // Bug #60010
640 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
641 LanguageType nFormatLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(),
642 *pFormatter );
643
644 if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
645 LANGUAGE_SYSTEM != nFormatLng ) &&
646 !(Which() == SwFieldIds::User && (GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
647 {
648 const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
649
650 if( pEntry && nFormatLng != pEntry->GetLanguage() )
651 {
652 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(
653 GetFormat(), nFormatLng );
654
655 if( nNewFormat == GetFormat() )
656 {
657 // probably user-defined format
658 SvNumFormatType nType = SvNumFormatType::DEFINED;
659 sal_Int32 nDummy;
660 OUString sFormat( pEntry->GetFormatstring() );
661 pFormatter->PutandConvertEntry( sFormat, nDummy, nType,
662 nNewFormat,
663 pEntry->GetLanguage(),
664 nFormatLng, false);
665 }
666 SetFormat( nNewFormat );
667 }
668 OSL_ENSURE(pEntry, "unknown number format!");
669 }
670 }
671
672 SwField::SetLanguage(nLng);
673 }
674
GetValue() const675 double SwValueField::GetValue() const
676 {
677 return m_fValue;
678 }
679
SetValue(const double & rVal)680 void SwValueField::SetValue( const double& rVal )
681 {
682 m_fValue = rVal;
683 }
684
SwFormulaField(SwValueFieldType * pFieldType,sal_uInt32 nFormat,const double fVal)685 SwFormulaField::SwFormulaField( SwValueFieldType* pFieldType, sal_uInt32 nFormat, const double fVal)
686 : SwValueField(pFieldType, nFormat, LANGUAGE_SYSTEM, fVal)
687 {
688 }
689
SwFormulaField(const SwFormulaField & rField)690 SwFormulaField::SwFormulaField( const SwFormulaField& rField )
691 : SwValueField(static_cast<SwValueFieldType *>(rField.GetTyp()), rField.GetFormat(),
692 rField.GetLanguage(), rField.GetValue())
693 {
694 }
695
GetFormula() const696 OUString SwFormulaField::GetFormula() const
697 {
698 return m_sFormula;
699 }
700
SetFormula(const OUString & rStr)701 void SwFormulaField::SetFormula(const OUString& rStr)
702 {
703 m_sFormula = rStr;
704
705 sal_uLong nFormat(GetFormat());
706
707 if( nFormat && SAL_MAX_UINT32 != nFormat )
708 {
709 sal_Int32 nPos = 0;
710 double fTmpValue;
711 if( SwCalc::Str2Double( rStr, nPos, fTmpValue, GetDoc() ) )
712 SwValueField::SetValue( fTmpValue );
713 }
714 }
715
SetExpandedFormula(const OUString & rStr)716 void SwFormulaField::SetExpandedFormula( const OUString& rStr )
717 {
718 sal_uInt32 nFormat(GetFormat());
719
720 if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
721 {
722 double fTmpValue;
723
724 if (GetDoc()->IsNumberFormat(rStr, nFormat, fTmpValue))
725 {
726 SwValueField::SetValue(fTmpValue);
727
728 m_sFormula = static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(fTmpValue, nFormat);
729 return;
730 }
731 }
732 m_sFormula = rStr;
733 }
734
GetExpandedFormula() const735 OUString SwFormulaField::GetExpandedFormula() const
736 {
737 sal_uInt32 nFormat(GetFormat());
738
739 if (nFormat && nFormat != SAL_MAX_UINT32 && static_cast<SwValueFieldType *>(GetTyp())->UseFormat())
740 {
741 OUString sFormattedValue;
742 Color* pCol = nullptr;
743
744 SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
745
746 if (pFormatter->IsTextFormat(nFormat))
747 {
748 OUString sTempIn(static_cast<SwValueFieldType *>(GetTyp())->DoubleToString(GetValue(), nFormat));
749 pFormatter->GetOutputString(sTempIn, nFormat, sFormattedValue, &pCol);
750 }
751 else
752 {
753 pFormatter->GetOutputString(GetValue(), nFormat, sFormattedValue, &pCol);
754 }
755 return sFormattedValue;
756 }
757 else
758 return GetFormula();
759 }
760
GetDescription() const761 OUString SwField::GetDescription() const
762 {
763 return SwResId(STR_FIELD);
764 }
765
IsClickable() const766 bool SwField::IsClickable() const
767 {
768 switch (Which())
769 {
770 case SwFieldIds::JumpEdit:
771 case SwFieldIds::Macro:
772 case SwFieldIds::GetRef:
773 case SwFieldIds::Input:
774 case SwFieldIds::SetExp:
775 case SwFieldIds::Dropdown:
776 return true;
777 default: break;
778 }
779 return false;
780 }
781
dumpAsXml(xmlTextWriterPtr pWriter) const782 void SwField::dumpAsXml(xmlTextWriterPtr pWriter) const
783 {
784 xmlTextWriterStartElement(pWriter, BAD_CAST("SwField"));
785 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
786 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
787 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nFormat"), BAD_CAST(OString::number(m_nFormat).getStr()));
788 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nLang"), BAD_CAST(OString::number(m_nLang.get()).getStr()));
789
790 xmlTextWriterEndElement(pWriter);
791 }
792
793 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
794