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 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 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 137 SwFieldType::SwFieldType( SwFieldIds nWhichId ) 138 : SwModify(nullptr) 139 , m_nWhich(nWhichId) 140 { 141 } 142 143 OUString SwFieldType::GetName() const 144 { 145 return OUString(); 146 } 147 148 void SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const 149 { 150 } 151 void SwFieldType::PutValue( const uno::Any& , sal_uInt16 ) 152 { 153 } 154 155 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 167 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) 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 193 SwField::~SwField() 194 { 195 } 196 197 // instead of indirectly via the type 198 199 #ifdef DBG_UTIL 200 SwFieldIds SwField::Which() const 201 { 202 assert(m_pType); 203 return m_pType->Which(); 204 } 205 #endif 206 207 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 255 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 271 OUString SwField::GetPar1() const 272 { 273 return OUString(); 274 } 275 276 OUString SwField::GetPar2() const 277 { 278 return OUString(); 279 } 280 281 OUString SwField::GetFormula() const 282 { 283 return GetPar2(); 284 } 285 286 void SwField::SetPar1(const OUString& ) 287 {} 288 289 void SwField::SetPar2(const OUString& ) 290 {} 291 292 sal_uInt16 SwField::GetSubType() const 293 { 294 return 0; 295 } 296 297 void SwField::SetSubType(sal_uInt16 ) 298 { 299 } 300 301 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 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 */ 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,...) 348 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 370 void SwField::SetLanguage(LanguageType const nLang) 371 { 372 m_nLang = nLang; 373 } 374 375 void SwField::ChangeFormat(sal_uInt32 const nFormat) 376 { 377 m_nFormat = nFormat; 378 } 379 380 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 412 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 432 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 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 460 SwValueFieldType::SwValueFieldType(SwDoc *const pDoc, SwFieldIds const nWhichId) 461 : SwFieldType(nWhichId) 462 , m_pDoc(pDoc) 463 , m_bUseFormat(true) 464 { 465 } 466 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 475 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 526 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 538 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 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 559 SwValueField::SwValueField( const SwValueField& rField ) 560 : SwField(rField) 561 , m_fValue(rField.GetValue()) 562 { 563 } 564 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 */ 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 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 624 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 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 675 double SwValueField::GetValue() const 676 { 677 return m_fValue; 678 } 679 680 void SwValueField::SetValue( const double& rVal ) 681 { 682 m_fValue = rVal; 683 } 684 685 SwFormulaField::SwFormulaField( SwValueFieldType* pFieldType, sal_uInt32 nFormat, const double fVal) 686 : SwValueField(pFieldType, nFormat, LANGUAGE_SYSTEM, fVal) 687 { 688 } 689 690 SwFormulaField::SwFormulaField( const SwFormulaField& rField ) 691 : SwValueField(static_cast<SwValueFieldType *>(rField.GetTyp()), rField.GetFormat(), 692 rField.GetLanguage(), rField.GetValue()) 693 { 694 } 695 696 OUString SwFormulaField::GetFormula() const 697 { 698 return m_sFormula; 699 } 700 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 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 735 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 761 OUString SwField::GetDescription() const 762 { 763 return SwResId(STR_FIELD); 764 } 765 766 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 782 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
