xref: /trunk/main/sw/source/core/fields/fldbas.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <float.h>
32 #include <rtl/math.hxx>
33 #include <svl/zforlist.hxx>
34 #include <svl/zformat.hxx>
35 #include <editeng/unolingu.hxx>
36 #include <unofldmid.h>
37 #include <doc.hxx>
38 #include <editsh.hxx>
39 #include <frame.hxx>
40 #include <fldbas.hxx>
41 #include <flddat.hxx>
42 #include <ndtxt.hxx>
43 #include <fmtfld.hxx>
44 #include <txtfld.hxx>
45 #include <pam.hxx>
46 #include <docfld.hxx>
47 #include <swtable.hxx>
48 #include <docufld.hxx>
49 #include <expfld.hxx>
50 #include <shellres.hxx>
51 #include <calc.hxx>
52 #include <comcore.hrc>
53 
54 #include <math.h>
55 #include <float.h>
56 
57 using namespace ::com::sun::star;
58 using namespace nsSwDocInfoSubType;
59 
60 sal_uInt16 lcl_GetLanguageOfFormat( sal_uInt16 nLng, sal_uLong nFmt,
61                                 const SvNumberFormatter& rFormatter )
62 {
63     if( nLng == LANGUAGE_NONE ) // wegen Bug #60010
64         nLng = LANGUAGE_SYSTEM;
65     else if( nLng == ::GetAppLanguage() )
66         switch( rFormatter.GetIndexTableOffset( nFmt ))
67         {
68         case NF_NUMBER_SYSTEM:
69         case NF_DATE_SYSTEM_SHORT:
70         case NF_DATE_SYSTEM_LONG:
71         case NF_DATETIME_SYSTEM_SHORT_HHMM:
72             nLng = LANGUAGE_SYSTEM;
73             break;
74         default: break;
75         }
76     return nLng;
77 }
78 
79 /*--------------------------------------------------------------------
80     Beschreibung: Globals
81  --------------------------------------------------------------------*/
82 // Array der Feldname
83 
84 SvStringsDtor* SwFieldType::pFldNames = 0;
85 
86 DBG_NAME(SwFieldType)
87 
88     sal_uInt16 __FAR_DATA aTypeTab[] = {
89     /* RES_DBFLD            */      TYP_DBFLD,
90     /* RES_USERFLD          */      TYP_USERFLD,
91     /* RES_FILENAMEFLD      */      TYP_FILENAMEFLD,
92     /* RES_DBNAMEFLD        */      TYP_DBNAMEFLD,
93     /* RES_DATEFLD          */      TYP_DATEFLD,
94     /* RES_TIMEFLD          */      TYP_TIMEFLD,
95     /* RES_PAGENUMBERFLD    */      TYP_PAGENUMBERFLD,  // dynamisch
96     /* RES_AUTHORFLD        */      TYP_AUTHORFLD,
97     /* RES_CHAPTERFLD       */      TYP_CHAPTERFLD,
98     /* RES_DOCSTATFLD       */      TYP_DOCSTATFLD,
99     /* RES_GETEXPFLD        */      TYP_GETFLD,         // dynamisch
100     /* RES_SETEXPFLD        */      TYP_SETFLD,         // dynamisch
101     /* RES_GETREFFLD        */      TYP_GETREFFLD,
102     /* RES_HIDDENTXTFLD     */      TYP_HIDDENTXTFLD,
103     /* RES_POSTITFLD        */      TYP_POSTITFLD,
104     /* RES_FIXDATEFLD       */      TYP_FIXDATEFLD,
105     /* RES_FIXTIMEFLD       */      TYP_FIXTIMEFLD,
106     /* RES_REGFLD           */      0,                  // alt
107     /* RES_VARREGFLD        */      0,                  // alt
108     /* RES_SETREFFLD        */      TYP_SETREFFLD,
109     /* RES_INPUTFLD         */      TYP_INPUTFLD,
110     /* RES_MACROFLD         */      TYP_MACROFLD,
111     /* RES_DDEFLD           */      TYP_DDEFLD,
112     /* RES_TABLEFLD         */      TYP_FORMELFLD,
113     /* RES_HIDDENPARAFLD    */      TYP_HIDDENPARAFLD,
114     /* RES_DOCINFOFLD       */      TYP_DOCINFOFLD,
115     /* RES_TEMPLNAMEFLD     */      TYP_TEMPLNAMEFLD,
116     /* RES_DBNEXTSETFLD     */      TYP_DBNEXTSETFLD,
117     /* RES_DBNUMSETFLD      */      TYP_DBNUMSETFLD,
118     /* RES_DBSETNUMBERFLD   */      TYP_DBSETNUMBERFLD,
119     /* RES_EXTUSERFLD       */      TYP_EXTUSERFLD,
120     /* RES_REFPAGESETFLD    */      TYP_SETREFPAGEFLD,
121     /* RES_REFPAGEGETFLD    */      TYP_GETREFPAGEFLD,
122     /* RES_INTERNETFLD      */      TYP_INTERNETFLD,
123     /* RES_JUMPEDITFLD      */      TYP_JUMPEDITFLD,
124     /* RES_SCRIPTFLD        */      TYP_SCRIPTFLD,
125     /* RES_DATETIMEFLD      */      0,                  // dynamisch
126     /* RES_AUTHORITY        */      TYP_AUTHORITY,
127     /* RES_COMBINED_CHARS   */      TYP_COMBINED_CHARS,
128     /* RES_DROPDOWN         */      TYP_DROPDOWN
129     };
130         // ????? TYP_USRINPFLD,
131 
132 
133 
134 const String& SwFieldType::GetTypeStr(sal_uInt16 nTypeId)
135 {
136     if( !pFldNames )
137         _GetFldName();
138 
139     if( nTypeId < SwFieldType::pFldNames->Count() )
140         return *SwFieldType::pFldNames->GetObject( nTypeId );
141     else
142         return aEmptyStr;
143 }
144 
145 
146 /*---------------------------------------------------
147  Jedes Feld referenziert einen Feldtypen, der fuer
148  jedes Dokument einmalig ist.
149  --------------------------------------------------*/
150 
151 SwFieldType::SwFieldType( sal_uInt16 nWhichId )
152     : SwModify(0),
153     nWhich( nWhichId )
154 {
155     DBG_CTOR( SwFieldType, 0 );
156 }
157 
158 #ifdef DBG_UTIL
159 
160 SwFieldType::~SwFieldType()
161 {
162     DBG_DTOR( SwFieldType, 0 );
163 }
164 
165 #endif
166 
167 const String& SwFieldType::GetName() const
168 {
169     return aEmptyStr;
170 }
171 
172 sal_Bool SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const
173 {
174     return sal_False;
175 }
176 sal_Bool SwFieldType::PutValue( const uno::Any& , sal_uInt16 )
177 {
178     return sal_False;
179 }
180 
181 /*--------------------------------------------------------------------
182     Beschreibung:   Basisklasse aller Felder
183                     Felder referenzieren einen Feldtyp
184                     Felder sind n-mal vorhanden, Feldtypen nur einmal
185  --------------------------------------------------------------------*/
186 
187 SwField::SwField(SwFieldType* pTyp, sal_uInt32 nFmt, sal_uInt16 nLng) :
188     nLang(nLng),
189     bIsAutomaticLanguage(sal_True),
190     nFormat(nFmt)
191 {
192     ASSERT( pTyp, "SwField: ungueltiger SwFieldType" );
193     pType = pTyp;
194 }
195 
196 SwField::~SwField()
197 {
198 }
199 
200 /*--------------------------------------------------------------------
201     Beschreibung: Statt Umweg ueber den Typ
202  --------------------------------------------------------------------*/
203 
204 #ifdef DBG_UTIL
205 sal_uInt16 SwField::Which() const
206 {
207     ASSERT(pType, "Kein Typ vorhanden");
208     return pType->Which();
209 }
210 #endif
211 
212 /*--------------------------------------------------------------------
213     Beschreibung:
214  --------------------------------------------------------------------*/
215 
216 sal_uInt16 SwField::GetTypeId() const
217 {
218 
219     sal_uInt16 nRet;
220     switch( pType->Which() )
221     {
222     case RES_DATETIMEFLD:
223         if (GetSubType() & FIXEDFLD)
224             nRet = static_cast<sal_uInt16>(GetSubType() & DATEFLD ? TYP_FIXDATEFLD : TYP_FIXTIMEFLD);
225         else
226             nRet = static_cast<sal_uInt16>(GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD);
227         break;
228     case RES_GETEXPFLD:
229         nRet = static_cast<sal_uInt16>(nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? TYP_FORMELFLD : TYP_GETFLD);
230         break;
231 
232     case RES_HIDDENTXTFLD:
233         nRet = GetSubType();
234         break;
235 
236     case RES_SETEXPFLD:
237         if( nsSwGetSetExpType::GSE_SEQ & GetSubType() )
238             nRet = TYP_SEQFLD;
239         else if( ((SwSetExpField*)this)->GetInputFlag() )
240             nRet = TYP_SETINPFLD;
241         else
242             nRet = TYP_SETFLD;
243         break;
244 
245     case RES_PAGENUMBERFLD:
246         nRet = GetSubType();
247         if( PG_NEXT == nRet )
248             nRet = TYP_NEXTPAGEFLD;
249         else if( PG_PREV == nRet )
250             nRet = TYP_PREVPAGEFLD;
251         else
252             nRet = TYP_PAGENUMBERFLD;
253         break;
254 
255     default:
256         nRet = aTypeTab[ pType->Which() ];
257     }
258     return nRet;
259 }
260 
261 
262 /*--------------------------------------------------------------------
263     Beschreibung: liefert den Namen oder den Inhalt
264  --------------------------------------------------------------------*/
265 
266 String SwField::GetFieldName() const
267 {
268     sal_uInt16 nTypeId = GetTypeId();
269     if (RES_DATETIMEFLD == GetTyp()->Which())
270     {
271         nTypeId = static_cast<sal_uInt16>(
272             ((GetSubType() & DATEFLD) != 0) ? TYP_DATEFLD : TYP_TIMEFLD);
273     }
274     String sRet = SwFieldType::GetTypeStr( nTypeId );
275     if (IsFixed())
276     {
277         sRet += ' ';
278         sRet += ViewShell::GetShellRes()->aFixedStr;
279     }
280     return sRet;
281 }
282 
283 /*--------------------------------------------------------------------
284     Beschreibung: Parameter setzen auslesen
285  --------------------------------------------------------------------*/
286 
287 const String& SwField::GetPar1() const
288 {
289     return aEmptyStr;
290 }
291 
292 String SwField::GetPar2() const
293 {
294     return aEmptyStr;
295 }
296 
297 String SwField::GetFormula() const
298 {
299     return GetPar2();
300 }
301 
302 void SwField::SetPar1(const String& )
303 {}
304 
305 void SwField::SetPar2(const String& )
306 {}
307 
308 sal_uInt16 SwField::GetSubType() const
309 {
310 //  ASSERT(0, "Sorry Not implemented");
311     return 0;
312 }
313 
314 void SwField::SetSubType(sal_uInt16 )
315 {
316 //  ASSERT(0, "Sorry Not implemented");
317 }
318 
319 sal_Bool  SwField::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
320 {
321     switch( nWhichId )
322     {
323         case FIELD_PROP_BOOL4:
324         {
325             sal_Bool bFixed = !bIsAutomaticLanguage;
326             rVal.setValue(&bFixed, ::getCppuBooleanType());
327         }
328         break;
329         default:
330             DBG_ERROR("illegal property");
331     }
332     return sal_True;
333 }
334 sal_Bool SwField::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
335 {
336     switch( nWhichId )
337     {
338         case FIELD_PROP_BOOL4:
339         {
340             sal_Bool bFixed = sal_False;
341             if(rVal >>= bFixed)
342                 bIsAutomaticLanguage = !bFixed;
343         }
344         break;
345         default:
346             DBG_ERROR("illegal property");
347     }
348     return sal_True;
349 }
350 
351 
352 /*--------------------------------------------------------------------
353     Beschreibung:   neuen Typ setzen
354                     (wird fuer das Kopieren zwischen Dokumenten benutzt)
355                     muss immer vom gleichen Typ sein.
356  --------------------------------------------------------------------*/
357 
358 SwFieldType* SwField::ChgTyp( SwFieldType* pNewType )
359 {
360     ASSERT( pNewType && pNewType->Which() == pType->Which(),
361             "kein Typ oder ungleiche Typen" );
362 
363     SwFieldType* pOld = pType;
364     pType = pNewType;
365     return pOld;
366 }
367 
368     // hat das Feld eine Action auf dem ClickHandler ? (z.B. INetFelder,..)
369 sal_Bool SwField::HasClickHdl() const
370 {
371     sal_Bool bRet = sal_False;
372     switch( pType->Which() )
373     {
374     case RES_INTERNETFLD:
375     case RES_JUMPEDITFLD:
376     case RES_GETREFFLD:
377     case RES_MACROFLD:
378     case RES_INPUTFLD:
379     case RES_DROPDOWN :
380         bRet = sal_True;
381         break;
382 
383     case RES_SETEXPFLD:
384         bRet = ((SwSetExpField*)this)->GetInputFlag();
385         break;
386     }
387     return bRet;
388 }
389 
390 void SwField::SetLanguage(sal_uInt16 nLng)
391 {
392     nLang = nLng;
393 }
394 
395 void SwField::ChangeFormat(sal_uInt32 n)
396 {
397     nFormat = n;
398 }
399 
400 sal_Bool SwField::IsFixed() const
401 {
402     sal_Bool bRet = sal_False;
403     switch( pType->Which() )
404     {
405     case RES_FIXDATEFLD:
406     case RES_FIXTIMEFLD:
407         bRet = sal_True;
408         break;
409 
410     case RES_DATETIMEFLD:
411         bRet = 0 != (GetSubType() & FIXEDFLD);
412         break;
413 
414     case RES_EXTUSERFLD:
415     case RES_AUTHORFLD:
416         bRet = 0 != (GetFormat() & AF_FIXED);
417         break;
418 
419     case RES_FILENAMEFLD:
420         bRet = 0 != (GetFormat() & FF_FIXED);
421         break;
422 
423     case RES_DOCINFOFLD:
424         bRet = 0 != (GetSubType() & DI_SUB_FIXED);
425         break;
426     }
427     return bRet;
428 }
429 
430 String SwField::ExpandField(bool const bCached) const
431 {
432     if (!bCached) // #i85766# do not expand fields in clipboard documents
433     {
434         m_Cache = Expand();
435     }
436     return m_Cache;
437 }
438 
439 SwField * SwField::CopyField() const
440 {
441     SwField *const pNew = Copy();
442     // #i85766# cache expansion of source (for clipboard)
443     // use this->cache, not this->Expand(): only text formatting calls Expand()
444     pNew->m_Cache = m_Cache;
445     return pNew;
446 }
447 
448 /*--------------------------------------------------------------------
449     Beschreibung: Numerierung expandieren
450  --------------------------------------------------------------------*/
451 
452 String FormatNumber(sal_uInt16 nNum, sal_uInt32 nFormat)
453 {
454     if(SVX_NUM_PAGEDESC == nFormat)
455         return  String::CreateFromInt32( nNum );
456     SvxNumberType aNumber;
457 
458     ASSERT(nFormat != SVX_NUM_NUMBER_NONE, "Falsches Nummern-Format" );
459 
460     aNumber.SetNumberingType((sal_Int16)nFormat);
461     return aNumber.GetNumStr(nNum);
462 }
463 
464 /*--------------------------------------------------------------------
465     Beschreibung: CTOR SwValueFieldType
466  --------------------------------------------------------------------*/
467 
468 SwValueFieldType::SwValueFieldType( SwDoc* pDocPtr, sal_uInt16 nWhichId )
469     : SwFieldType(nWhichId),
470     pDoc(pDocPtr),
471     bUseFormat(sal_True)
472 {
473 }
474 
475 SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp )
476     : SwFieldType(rTyp.Which()),
477     pDoc(rTyp.GetDoc()),
478     bUseFormat(rTyp.UseFormat())
479 {
480 }
481 
482 /*--------------------------------------------------------------------
483     Beschreibung: Wert formatiert als String zurueckgeben
484  --------------------------------------------------------------------*/
485 
486 String SwValueFieldType::ExpandValue( const double& rVal,
487                                         sal_uInt32 nFmt, sal_uInt16 nLng) const
488 {
489     if (rVal >= DBL_MAX)        // FehlerString fuer Calculator
490         return ViewShell::GetShellRes()->aCalc_Error;
491 
492     String sExpand;
493     SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
494     Color* pCol = 0;
495 
496     // wegen Bug #60010
497     sal_uInt16 nFmtLng = ::lcl_GetLanguageOfFormat( nLng, nFmt, *pFormatter );
498 
499     if( nFmt < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFmtLng )
500     {
501         short nType = NUMBERFORMAT_DEFINED;
502         xub_StrLen nDummy;
503 
504         const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
505 
506         if (pEntry && nLng != pEntry->GetLanguage())
507         {
508             sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt,
509                                                     (LanguageType)nFmtLng);
510 
511             if (nNewFormat == nFmt)
512             {
513                 // Warscheinlich benutzerdefiniertes Format
514                 String sFmt(pEntry->GetFormatstring());
515 
516                 pFormatter->PutandConvertEntry(sFmt, nDummy, nType, nFmt,
517                                         pEntry->GetLanguage(), nFmtLng );
518             }
519             else
520                 nFmt = nNewFormat;
521         }
522         ASSERT(pEntry, "Unbekanntes Zahlenformat!");
523     }
524 
525     if( pFormatter->IsTextFormat( nFmt ) )
526     {
527         String sValue;
528         DoubleToString(sValue, rVal, nFmtLng);
529         pFormatter->GetOutputString(sValue, nFmt, sExpand, &pCol);
530     }
531     else
532         pFormatter->GetOutputString(rVal, nFmt, sExpand, &pCol);
533 
534     return sExpand;
535 }
536 
537 /*--------------------------------------------------------------------
538     Beschreibung:
539  --------------------------------------------------------------------*/
540 
541 void SwValueFieldType::DoubleToString( String &rValue, const double &rVal,
542                                         sal_uInt32 nFmt) const
543 {
544     SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
545     const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
546 
547     if (pEntry)
548         DoubleToString(rValue, rVal, pEntry->GetLanguage());
549 }
550 
551 /*--------------------------------------------------------------------
552     Beschreibung:
553  --------------------------------------------------------------------*/
554 
555 void SwValueFieldType::DoubleToString( String &rValue, const double &rVal,
556                                         sal_uInt16 nLng ) const
557 {
558     SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
559 
560     // wegen Bug #60010
561     if( nLng == LANGUAGE_NONE ) // wegen Bug #60010
562         nLng = LANGUAGE_SYSTEM;
563 
564     pFormatter->ChangeIntl( nLng ); // Separator in der richtigen Sprache besorgen
565     rValue = ::rtl::math::doubleToUString( rVal, rtl_math_StringFormat_F, 12,
566                                     pFormatter->GetDecSep(), true );
567 }
568 
569 /*--------------------------------------------------------------------
570     Beschreibung: CTOR SwValueField
571  --------------------------------------------------------------------*/
572 
573 SwValueField::SwValueField( SwValueFieldType* pFldType, sal_uInt32 nFmt,
574                             sal_uInt16 nLng, const double fVal )
575     : SwField(pFldType, nFmt, nLng),
576     fValue(fVal)
577 {
578 }
579 
580 SwValueField::SwValueField( const SwValueField& rFld )
581     : SwField(rFld),
582     fValue(rFld.GetValue())
583 {
584 }
585 
586 SwValueField::~SwValueField()
587 {
588 }
589 /*--------------------------------------------------------------------
590     Beschreibung:   neuen Typ setzen
591                     (wird fuer das Kopieren zwischen Dokumenten benutzt)
592                     muss immer vom gleichen Typ sein.
593  --------------------------------------------------------------------*/
594 
595 SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType )
596 {
597     SwDoc* pNewDoc = ((SwValueFieldType *)pNewType)->GetDoc();
598     SwDoc* pDoc    = GetDoc();
599 
600     if( pNewDoc && pDoc && pDoc != pNewDoc)
601     {
602         SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter();
603 
604         if( pFormatter && pFormatter->HasMergeFmtTbl() &&
605             ((SwValueFieldType *)GetTyp())->UseFormat() )
606             SetFormat(pFormatter->GetMergeFmtIndex( GetFormat() ));
607     }
608 
609     return SwField::ChgTyp(pNewType);
610 }
611 
612 /*--------------------------------------------------------------------
613     Beschreibung: Format in Office-Sprache ermitteln
614  --------------------------------------------------------------------*/
615 
616 sal_uInt32 SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, sal_uInt32 nFmt)
617 {
618     const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt);
619     sal_uInt16 nLng = SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() );
620 
621     if (pEntry && nLng != pEntry->GetLanguage())
622     {
623         sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt,
624                                                         (LanguageType)nLng);
625 
626         if (nNewFormat == nFmt)
627         {
628             // Warscheinlich benutzerdefiniertes Format
629             short nType = NUMBERFORMAT_DEFINED;
630             xub_StrLen nDummy;
631 
632             String sFmt(pEntry->GetFormatstring());
633 
634             sal_uInt32 nFormat = nFmt;
635             pFormatter->PutandConvertEntry(sFmt, nDummy, nType,
636                                 nFormat, pEntry->GetLanguage(), nLng);
637             nFmt = nFormat;
638         }
639         else
640             nFmt = nNewFormat;
641     }
642 
643     return nFmt;
644 }
645 
646 /*--------------------------------------------------------------------
647     Beschreibung: Sprache im Format anpassen
648  --------------------------------------------------------------------*/
649 
650 void SwValueField::SetLanguage( sal_uInt16 nLng )
651 {
652     if( IsAutomaticLanguage() &&
653             ((SwValueFieldType *)GetTyp())->UseFormat() &&
654         GetFormat() != SAL_MAX_UINT32 )
655     {
656         // wegen Bug #60010
657         SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
658         sal_uInt16 nFmtLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(),
659                                                     *pFormatter );
660 
661         if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
662              LANGUAGE_SYSTEM != nFmtLng ) &&
663             !(Which() == RES_USERFLD && (GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
664         {
665             const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
666 
667             if( pEntry && nFmtLng != pEntry->GetLanguage() )
668             {
669                 sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(
670                                         GetFormat(), (LanguageType)nFmtLng );
671 
672                 if( nNewFormat == GetFormat() )
673                 {
674                     // Warscheinlich benutzerdefiniertes Format
675                     short nType = NUMBERFORMAT_DEFINED;
676                     xub_StrLen nDummy;
677                     String sFmt( pEntry->GetFormatstring() );
678                     pFormatter->PutandConvertEntry( sFmt, nDummy, nType,
679                                                     nNewFormat,
680                                                     pEntry->GetLanguage(),
681                                                     nFmtLng );
682                 }
683                 SetFormat( nNewFormat );
684             }
685             ASSERT(pEntry, "Unbekanntes Zahlenformat!");
686         }
687     }
688 
689     SwField::SetLanguage(nLng);
690 }
691 
692 /*--------------------------------------------------------------------
693     Beschreibung:
694  --------------------------------------------------------------------*/
695 
696 double SwValueField::GetValue() const
697 {
698     return fValue;
699 }
700 
701 void SwValueField::SetValue( const double& rVal )
702 {
703     fValue = rVal;
704 }
705 
706 /*--------------------------------------------------------------------
707     Beschreibung: SwFormulaField
708  --------------------------------------------------------------------*/
709 
710 SwFormulaField::SwFormulaField( SwValueFieldType* pFldType, sal_uInt32 nFmt, const double fVal)
711     : SwValueField(pFldType, nFmt, LANGUAGE_SYSTEM, fVal)
712 {
713 }
714 
715 SwFormulaField::SwFormulaField( const SwFormulaField& rFld )
716     : SwValueField((SwValueFieldType *)rFld.GetTyp(), rFld.GetFormat(),
717                     rFld.GetLanguage(), rFld.GetValue())
718 {
719 }
720 
721 /*--------------------------------------------------------------------
722     Beschreibung:
723  --------------------------------------------------------------------*/
724 
725 String SwFormulaField::GetFormula() const
726 {
727     return sFormula;
728 }
729 
730 /*--------------------------------------------------------------------
731     Beschreibung:
732  --------------------------------------------------------------------*/
733 
734 void SwFormulaField::SetFormula(const String& rStr)
735 {
736     sFormula = rStr;
737 
738     sal_uLong nFmt(GetFormat());
739 
740     if( nFmt && SAL_MAX_UINT32 != nFmt )
741     {
742         xub_StrLen nPos = 0;
743         double fTmpValue;
744         if( SwCalc::Str2Double( rStr, nPos, fTmpValue, GetDoc() ) )
745             SwValueField::SetValue( fTmpValue );
746     }
747 }
748 
749 /*--------------------------------------------------------------------
750     Beschreibung:
751  --------------------------------------------------------------------*/
752 
753 void SwFormulaField::SetExpandedFormula( const String& rStr )
754 {
755     sal_uInt32 nFmt(GetFormat());
756 
757     if (nFmt && nFmt != SAL_MAX_UINT32 && ((SwValueFieldType *)GetTyp())->UseFormat())
758     {
759         double fTmpValue;
760 
761         SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
762 
763         if (pFormatter->IsNumberFormat(rStr, nFmt, fTmpValue))
764         {
765             SwValueField::SetValue(fTmpValue);
766             sFormula.Erase();
767 
768             ((SwValueFieldType *)GetTyp())->DoubleToString(sFormula, fTmpValue, nFmt);
769             return;
770         }
771     }
772     sFormula = rStr;
773 }
774 
775 /*--------------------------------------------------------------------
776     Beschreibung:
777  --------------------------------------------------------------------*/
778 
779 String SwFormulaField::GetExpandedFormula() const
780 {
781     sal_uInt32 nFmt(GetFormat());
782 
783     if (nFmt && nFmt != SAL_MAX_UINT32 && ((SwValueFieldType *)GetTyp())->UseFormat())
784     {
785         String sFormattedValue;
786         Color* pCol = 0;
787 
788         SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
789 
790         if (pFormatter->IsTextFormat(nFmt))
791         {
792             String sValue;
793             ((SwValueFieldType *)GetTyp())->DoubleToString(sValue, GetValue(), nFmt);
794             pFormatter->GetOutputString(sValue, nFmt, sFormattedValue, &pCol);
795         }
796         else
797             pFormatter->GetOutputString(GetValue(), nFmt, sFormattedValue, &pCol);
798 
799         return sFormattedValue;
800     }
801     else
802         return GetFormula();
803 }
804 
805 String SwField::GetDescription() const
806 {
807     return SW_RES(STR_FIELD);
808 }
809