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