1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fldbas.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #include <rtl/math.hxx>
38 #include <svtools/zforlist.hxx>
39 #include <svtools/zformat.hxx>
40 #include <svx/unolingu.hxx>
42 #include <unofldmid.h>
54 #include <swtable.hxx>
55 #include <docufld.hxx>
57 #include <shellres.hxx>
60 #include <comcore.hrc>
69 using namespace ::com::sun::star
;
70 using namespace nsSwDocInfoSubType
;
72 USHORT
lcl_GetLanguageOfFormat( USHORT nLng
, ULONG nFmt
,
73 const SvNumberFormatter
& rFormatter
)
75 if( nLng
== LANGUAGE_NONE
) // wegen Bug #60010
76 nLng
= LANGUAGE_SYSTEM
;
77 else if( nLng
== ::GetAppLanguage() )
78 switch( rFormatter
.GetIndexTableOffset( nFmt
))
80 case NF_NUMBER_SYSTEM
:
81 case NF_DATE_SYSTEM_SHORT
:
82 case NF_DATE_SYSTEM_LONG
:
83 case NF_DATETIME_SYSTEM_SHORT_HHMM
:
84 nLng
= LANGUAGE_SYSTEM
;
91 /*--------------------------------------------------------------------
93 --------------------------------------------------------------------*/
96 SvStringsDtor
* SwFieldType::pFldNames
= 0;
100 USHORT __FAR_DATA aTypeTab
[] = {
101 /* RES_DBFLD */ TYP_DBFLD
,
102 /* RES_USERFLD */ TYP_USERFLD
,
103 /* RES_FILENAMEFLD */ TYP_FILENAMEFLD
,
104 /* RES_DBNAMEFLD */ TYP_DBNAMEFLD
,
105 /* RES_DATEFLD */ TYP_DATEFLD
,
106 /* RES_TIMEFLD */ TYP_TIMEFLD
,
107 /* RES_PAGENUMBERFLD */ TYP_PAGENUMBERFLD
, // dynamisch
108 /* RES_AUTHORFLD */ TYP_AUTHORFLD
,
109 /* RES_CHAPTERFLD */ TYP_CHAPTERFLD
,
110 /* RES_DOCSTATFLD */ TYP_DOCSTATFLD
,
111 /* RES_GETEXPFLD */ TYP_GETFLD
, // dynamisch
112 /* RES_SETEXPFLD */ TYP_SETFLD
, // dynamisch
113 /* RES_GETREFFLD */ TYP_GETREFFLD
,
114 /* RES_HIDDENTXTFLD */ TYP_HIDDENTXTFLD
,
115 /* RES_POSTITFLD */ TYP_POSTITFLD
,
116 /* RES_FIXDATEFLD */ TYP_FIXDATEFLD
,
117 /* RES_FIXTIMEFLD */ TYP_FIXTIMEFLD
,
118 /* RES_REGFLD */ 0, // alt
119 /* RES_VARREGFLD */ 0, // alt
120 /* RES_SETREFFLD */ TYP_SETREFFLD
,
121 /* RES_INPUTFLD */ TYP_INPUTFLD
,
122 /* RES_MACROFLD */ TYP_MACROFLD
,
123 /* RES_DDEFLD */ TYP_DDEFLD
,
124 /* RES_TABLEFLD */ TYP_FORMELFLD
,
125 /* RES_HIDDENPARAFLD */ TYP_HIDDENPARAFLD
,
126 /* RES_DOCINFOFLD */ TYP_DOCINFOFLD
,
127 /* RES_TEMPLNAMEFLD */ TYP_TEMPLNAMEFLD
,
128 /* RES_DBNEXTSETFLD */ TYP_DBNEXTSETFLD
,
129 /* RES_DBNUMSETFLD */ TYP_DBNUMSETFLD
,
130 /* RES_DBSETNUMBERFLD */ TYP_DBSETNUMBERFLD
,
131 /* RES_EXTUSERFLD */ TYP_EXTUSERFLD
,
132 /* RES_REFPAGESETFLD */ TYP_SETREFPAGEFLD
,
133 /* RES_REFPAGEGETFLD */ TYP_GETREFPAGEFLD
,
134 /* RES_INTERNETFLD */ TYP_INTERNETFLD
,
135 /* RES_JUMPEDITFLD */ TYP_JUMPEDITFLD
,
136 /* RES_SCRIPTFLD */ TYP_SCRIPTFLD
,
137 /* RES_DATETIMEFLD */ 0, // dynamisch
138 /* RES_AUTHORITY */ TYP_AUTHORITY
,
139 /* RES_COMBINED_CHARS */ TYP_COMBINED_CHARS
,
140 /* RES_DROPDOWN */ TYP_DROPDOWN
142 // ????? TYP_USRINPFLD,
146 const String
& SwFieldType::GetTypeStr(USHORT nTypeId
)
151 if( nTypeId
< SwFieldType::pFldNames
->Count() )
152 return *SwFieldType::pFldNames
->GetObject( nTypeId
);
158 /*---------------------------------------------------
159 Jedes Feld referenziert einen Feldtypen, der fuer
160 jedes Dokument einmalig ist.
161 --------------------------------------------------*/
163 SwFieldType::SwFieldType( USHORT nWhichId
)
167 DBG_CTOR( SwFieldType
, 0 );
172 SwFieldType::~SwFieldType()
174 DBG_DTOR( SwFieldType
, 0 );
179 const String
& SwFieldType::GetName() const
184 BOOL
SwFieldType::QueryValue( uno::Any
&, USHORT
) const
188 BOOL
SwFieldType::PutValue( const uno::Any
& , USHORT
)
193 /*--------------------------------------------------------------------
194 Beschreibung: Basisklasse aller Felder
195 Felder referenzieren einen Feldtyp
196 Felder sind n-mal vorhanden, Feldtypen nur einmal
197 --------------------------------------------------------------------*/
199 SwField::SwField(SwFieldType
* pTyp
, sal_uInt32 nFmt
, USHORT nLng
) :
201 bIsAutomaticLanguage(TRUE
),
204 ASSERT( pTyp
, "SwField: ungueltiger SwFieldType" );
212 /*--------------------------------------------------------------------
213 Beschreibung: Statt Umweg ueber den Typ
214 --------------------------------------------------------------------*/
217 USHORT
SwField::Which() const
219 ASSERT(pType
, "Kein Typ vorhanden");
220 return pType
->Which();
224 /*--------------------------------------------------------------------
226 --------------------------------------------------------------------*/
228 USHORT
SwField::GetTypeId() const
232 switch( pType
->Which() )
234 case RES_DATETIMEFLD
:
235 if (GetSubType() & FIXEDFLD
)
236 nRet
= static_cast<USHORT
>(GetSubType() & DATEFLD
? TYP_FIXDATEFLD
: TYP_FIXTIMEFLD
);
238 nRet
= static_cast<USHORT
>(GetSubType() & DATEFLD
? TYP_DATEFLD
: TYP_TIMEFLD
);
241 nRet
= static_cast<USHORT
>(nsSwGetSetExpType::GSE_FORMULA
& GetSubType() ? TYP_FORMELFLD
: TYP_GETFLD
);
244 case RES_HIDDENTXTFLD
:
249 if( nsSwGetSetExpType::GSE_SEQ
& GetSubType() )
251 else if( ((SwSetExpField
*)this)->GetInputFlag() )
252 nRet
= TYP_SETINPFLD
;
257 case RES_PAGENUMBERFLD
:
259 if( PG_NEXT
== nRet
)
260 nRet
= TYP_NEXTPAGEFLD
;
261 else if( PG_PREV
== nRet
)
262 nRet
= TYP_PREVPAGEFLD
;
264 nRet
= TYP_PAGENUMBERFLD
;
268 nRet
= aTypeTab
[ pType
->Which() ];
274 /*--------------------------------------------------------------------
275 Beschreibung: liefert den Namen oder den Inhalt
276 --------------------------------------------------------------------*/
278 String
SwField::GetCntnt( BOOL bName
) const
283 USHORT nTypeId
= GetTypeId();
284 if( RES_DATETIMEFLD
== GetTyp()->Which() )
285 nTypeId
= static_cast<USHORT
>(GetSubType() & DATEFLD
? TYP_DATEFLD
: TYP_TIMEFLD
);
287 sRet
= SwFieldType::GetTypeStr( nTypeId
);
289 ( sRet
+= ' ' ) += ViewShell::GetShellRes()->aFixedStr
;
296 /*--------------------------------------------------------------------
297 Beschreibung: Parameter setzen auslesen
298 --------------------------------------------------------------------*/
300 const String
& SwField::GetPar1() const
305 String
SwField::GetPar2() const
310 String
SwField::GetFormula() const
315 void SwField::SetPar1(const String
& )
318 void SwField::SetPar2(const String
& )
321 USHORT
SwField::GetSubType() const
323 // ASSERT(0, "Sorry Not implemented");
327 void SwField::SetSubType(USHORT
)
329 // ASSERT(0, "Sorry Not implemented");
332 BOOL
SwField::QueryValue( uno::Any
& rVal
, USHORT nWhichId
) const
336 case FIELD_PROP_BOOL4
:
338 BOOL bFixed
= !bIsAutomaticLanguage
;
339 rVal
.setValue(&bFixed
, ::getCppuBooleanType());
343 DBG_ERROR("illegal property");
347 BOOL
SwField::PutValue( const uno::Any
& rVal
, USHORT nWhichId
)
351 case FIELD_PROP_BOOL4
:
355 bIsAutomaticLanguage
= !bFixed
;
359 DBG_ERROR("illegal property");
365 /*--------------------------------------------------------------------
366 Beschreibung: neuen Typ setzen
367 (wird fuer das Kopieren zwischen Dokumenten benutzt)
368 muss immer vom gleichen Typ sein.
369 --------------------------------------------------------------------*/
371 SwFieldType
* SwField::ChgTyp( SwFieldType
* pNewType
)
373 ASSERT( pNewType
&& pNewType
->Which() == pType
->Which(),
374 "kein Typ oder ungleiche Typen" );
376 SwFieldType
* pOld
= pType
;
381 // hat das Feld eine Action auf dem ClickHandler ? (z.B. INetFelder,..)
382 BOOL
SwField::HasClickHdl() const
385 switch( pType
->Which() )
387 case RES_INTERNETFLD
:
388 case RES_JUMPEDITFLD
:
397 bRet
= ((SwSetExpField
*)this)->GetInputFlag();
403 void SwField::SetLanguage(USHORT nLng
)
408 void SwField::ChangeFormat(sal_uInt32 n
)
413 BOOL
SwField::IsFixed() const
416 switch( pType
->Which() )
423 case RES_DATETIMEFLD
:
424 bRet
= 0 != (GetSubType() & FIXEDFLD
);
429 bRet
= 0 != (GetFormat() & AF_FIXED
);
432 case RES_FILENAMEFLD
:
433 bRet
= 0 != (GetFormat() & FF_FIXED
);
437 bRet
= 0 != (GetSubType() & DI_SUB_FIXED
);
443 /*--------------------------------------------------------------------
444 Beschreibung: Numerierung expandieren
445 --------------------------------------------------------------------*/
447 String
FormatNumber(USHORT nNum
, sal_uInt32 nFormat
)
449 if(SVX_NUM_PAGEDESC
== nFormat
)
450 return String::CreateFromInt32( nNum
);
451 SvxNumberType aNumber
;
453 ASSERT(nFormat
!= SVX_NUM_NUMBER_NONE
, "Falsches Nummern-Format" );
455 aNumber
.SetNumberingType((sal_Int16
)nFormat
);
456 return aNumber
.GetNumStr(nNum
);
459 /*--------------------------------------------------------------------
460 Beschreibung: CTOR SwValueFieldType
461 --------------------------------------------------------------------*/
463 SwValueFieldType::SwValueFieldType( SwDoc
* pDocPtr
, USHORT nWhichId
)
464 : SwFieldType(nWhichId
),
470 SwValueFieldType::SwValueFieldType( const SwValueFieldType
& rTyp
)
471 : SwFieldType(rTyp
.Which()),
473 bUseFormat(rTyp
.UseFormat())
477 /*--------------------------------------------------------------------
478 Beschreibung: Wert formatiert als String zurueckgeben
479 --------------------------------------------------------------------*/
481 String
SwValueFieldType::ExpandValue( const double& rVal
,
482 sal_uInt32 nFmt
, USHORT nLng
) const
484 if (rVal
>= DBL_MAX
) // FehlerString fuer Calculator
485 return ViewShell::GetShellRes()->aCalc_Error
;
488 SvNumberFormatter
* pFormatter
= pDoc
->GetNumberFormatter();
492 USHORT nFmtLng
= ::lcl_GetLanguageOfFormat( nLng
, nFmt
, *pFormatter
);
494 if( nFmt
< SV_COUNTRY_LANGUAGE_OFFSET
&& LANGUAGE_SYSTEM
!= nFmtLng
)
496 short nType
= NUMBERFORMAT_DEFINED
;
499 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFmt
);
501 if (pEntry
&& nLng
!= pEntry
->GetLanguage())
503 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(nFmt
,
504 (LanguageType
)nFmtLng
);
506 if (nNewFormat
== nFmt
)
508 // Warscheinlich benutzerdefiniertes Format
509 String
sFmt(pEntry
->GetFormatstring());
511 pFormatter
->PutandConvertEntry(sFmt
, nDummy
, nType
, nFmt
,
512 pEntry
->GetLanguage(), nFmtLng
);
517 ASSERT(pEntry
, "Unbekanntes Zahlenformat!");
520 if( pFormatter
->IsTextFormat( nFmt
) )
523 DoubleToString(sValue
, rVal
, nFmtLng
);
524 pFormatter
->GetOutputString(sValue
, nFmt
, sExpand
, &pCol
);
527 pFormatter
->GetOutputString(rVal
, nFmt
, sExpand
, &pCol
);
532 /*--------------------------------------------------------------------
534 --------------------------------------------------------------------*/
536 void SwValueFieldType::DoubleToString( String
&rValue
, const double &rVal
,
537 sal_uInt32 nFmt
) const
539 SvNumberFormatter
* pFormatter
= pDoc
->GetNumberFormatter();
540 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFmt
);
543 DoubleToString(rValue
, rVal
, pEntry
->GetLanguage());
546 /*--------------------------------------------------------------------
548 --------------------------------------------------------------------*/
550 void SwValueFieldType::DoubleToString( String
&rValue
, const double &rVal
,
553 SvNumberFormatter
* pFormatter
= pDoc
->GetNumberFormatter();
556 if( nLng
== LANGUAGE_NONE
) // wegen Bug #60010
557 nLng
= LANGUAGE_SYSTEM
;
559 pFormatter
->ChangeIntl( nLng
); // Separator in der richtigen Sprache besorgen
560 rValue
= ::rtl::math::doubleToUString( rVal
, rtl_math_StringFormat_F
, 12,
561 pFormatter
->GetDecSep(), true );
564 /*--------------------------------------------------------------------
565 Beschreibung: CTOR SwValueField
566 --------------------------------------------------------------------*/
568 SwValueField::SwValueField( SwValueFieldType
* pFldType
, sal_uInt32 nFmt
,
569 USHORT nLng
, const double fVal
)
570 : SwField(pFldType
, nFmt
, nLng
),
575 SwValueField::SwValueField( const SwValueField
& rFld
)
577 fValue(rFld
.GetValue())
581 SwValueField::~SwValueField()
584 /*--------------------------------------------------------------------
585 Beschreibung: neuen Typ setzen
586 (wird fuer das Kopieren zwischen Dokumenten benutzt)
587 muss immer vom gleichen Typ sein.
588 --------------------------------------------------------------------*/
590 SwFieldType
* SwValueField::ChgTyp( SwFieldType
* pNewType
)
592 SwDoc
* pNewDoc
= ((SwValueFieldType
*)pNewType
)->GetDoc();
593 SwDoc
* pDoc
= GetDoc();
595 if( pNewDoc
&& pDoc
&& pDoc
!= pNewDoc
)
597 SvNumberFormatter
* pFormatter
= pNewDoc
->GetNumberFormatter();
599 if( pFormatter
&& pFormatter
->HasMergeFmtTbl() &&
600 ((SwValueFieldType
*)GetTyp())->UseFormat() )
601 SetFormat(pFormatter
->GetMergeFmtIndex( GetFormat() ));
604 return SwField::ChgTyp(pNewType
);
607 /*--------------------------------------------------------------------
608 Beschreibung: Format in Office-Sprache ermitteln
609 --------------------------------------------------------------------*/
611 sal_uInt32
SwValueField::GetSystemFormat(SvNumberFormatter
* pFormatter
, sal_uInt32 nFmt
)
613 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(nFmt
);
614 USHORT nLng
= SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() );
616 if (pEntry
&& nLng
!= pEntry
->GetLanguage())
618 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(nFmt
,
621 if (nNewFormat
== nFmt
)
623 // Warscheinlich benutzerdefiniertes Format
624 short nType
= NUMBERFORMAT_DEFINED
;
627 String
sFmt(pEntry
->GetFormatstring());
629 sal_uInt32 nFormat
= nFmt
;
630 pFormatter
->PutandConvertEntry(sFmt
, nDummy
, nType
,
631 nFormat
, pEntry
->GetLanguage(), nLng
);
641 /*--------------------------------------------------------------------
642 Beschreibung: Sprache im Format anpassen
643 --------------------------------------------------------------------*/
645 void SwValueField::SetLanguage( USHORT nLng
)
647 if( IsAutomaticLanguage() &&
648 ((SwValueFieldType
*)GetTyp())->UseFormat() &&
649 GetFormat() != SAL_MAX_UINT32
)
652 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
653 USHORT nFmtLng
= ::lcl_GetLanguageOfFormat( nLng
, GetFormat(),
656 if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET
||
657 LANGUAGE_SYSTEM
!= nFmtLng
) &&
658 !(Which() == RES_USERFLD
&& (GetSubType()&nsSwExtendedSubType::SUB_CMD
) ) )
660 const SvNumberformat
* pEntry
= pFormatter
->GetEntry(GetFormat());
662 if( pEntry
&& nFmtLng
!= pEntry
->GetLanguage() )
664 sal_uInt32 nNewFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn(
665 GetFormat(), (LanguageType
)nFmtLng
);
667 if( nNewFormat
== GetFormat() )
669 // Warscheinlich benutzerdefiniertes Format
670 short nType
= NUMBERFORMAT_DEFINED
;
672 String
sFmt( pEntry
->GetFormatstring() );
673 pFormatter
->PutandConvertEntry( sFmt
, nDummy
, nType
,
675 pEntry
->GetLanguage(),
678 SetFormat( nNewFormat
);
680 ASSERT(pEntry
, "Unbekanntes Zahlenformat!");
684 SwField::SetLanguage(nLng
);
687 /*--------------------------------------------------------------------
689 --------------------------------------------------------------------*/
691 double SwValueField::GetValue() const
696 void SwValueField::SetValue( const double& rVal
)
701 /*--------------------------------------------------------------------
702 Beschreibung: SwFormulaField
703 --------------------------------------------------------------------*/
705 SwFormulaField::SwFormulaField( SwValueFieldType
* pFldType
, sal_uInt32 nFmt
, const double fVal
)
706 : SwValueField(pFldType
, nFmt
, LANGUAGE_SYSTEM
, fVal
)
710 SwFormulaField::SwFormulaField( const SwFormulaField
& rFld
)
711 : SwValueField((SwValueFieldType
*)rFld
.GetTyp(), rFld
.GetFormat(),
712 rFld
.GetLanguage(), rFld
.GetValue())
716 /*--------------------------------------------------------------------
718 --------------------------------------------------------------------*/
720 String
SwFormulaField::GetFormula() const
725 /*--------------------------------------------------------------------
727 --------------------------------------------------------------------*/
729 void SwFormulaField::SetFormula(const String
& rStr
)
733 ULONG
nFmt(GetFormat());
735 if( nFmt
&& SAL_MAX_UINT32
!= nFmt
)
739 if( SwCalc::Str2Double( rStr
, nPos
, fTmpValue
, GetDoc() ) )
740 SwValueField::SetValue( fTmpValue
);
744 /*--------------------------------------------------------------------
746 --------------------------------------------------------------------*/
748 void SwFormulaField::SetExpandedFormula( const String
& rStr
)
750 sal_uInt32
nFmt(GetFormat());
752 if (nFmt
&& nFmt
!= SAL_MAX_UINT32
&& ((SwValueFieldType
*)GetTyp())->UseFormat())
756 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
758 if (pFormatter
->IsNumberFormat(rStr
, nFmt
, fTmpValue
))
760 SwValueField::SetValue(fTmpValue
);
763 ((SwValueFieldType
*)GetTyp())->DoubleToString(sFormula
, fTmpValue
, nFmt
);
770 /*--------------------------------------------------------------------
772 --------------------------------------------------------------------*/
774 String
SwFormulaField::GetExpandedFormula() const
776 sal_uInt32
nFmt(GetFormat());
778 if (nFmt
&& nFmt
!= SAL_MAX_UINT32
&& ((SwValueFieldType
*)GetTyp())->UseFormat())
780 String sFormattedValue
;
783 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
785 if (pFormatter
->IsTextFormat(nFmt
))
788 ((SwValueFieldType
*)GetTyp())->DoubleToString(sValue
, GetValue(), nFmt
);
789 pFormatter
->GetOutputString(sValue
, nFmt
, sFormattedValue
, &pCol
);
792 pFormatter
->GetOutputString(GetValue(), nFmt
, sFormattedValue
, &pCol
);
794 return sFormattedValue
;
800 String
SwField::GetDescription() const
802 return SW_RES(STR_FIELD
);