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: expfld.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"
35 #include <hintids.hxx>
36 #include <unotools/collatorwrapper.hxx>
37 #include <unotools/charclass.hxx>
38 #include <svx/unolingu.hxx>
39 #include <svx/pageitem.hxx>
40 #include <svx/langitem.hxx>
41 #include <svx/fontitem.hxx>
42 #include <com/sun/star/text/SetVariableType.hpp>
43 #include <unofield.hxx>
46 #include <fmtanchr.hxx>
50 #include <pagefrm.hxx>
52 #include <rootfrm.hxx>
63 #include <swcache.hxx>
64 #include <swtable.hxx>
65 #include <breakit.hxx>
66 #include <SwStyleNameMapper.hxx>
68 #include <unofldmid.h>
70 #include <numrule.hxx>
72 using namespace ::com::sun::star
;
73 using namespace ::com::sun::star::text
;
74 using ::rtl::OUString
;
76 SV_IMPL_PTRARR( _SwSeqFldList
, _SeqFldLstElem
* )
78 //-----------------------------------------------------------------------------
79 sal_Int16
lcl_SubTypeToAPI(USHORT nSubType
)
84 case nsSwGetSetExpType::GSE_EXPR
: nRet
= SetVariableType::VAR
/*0*/; break;
85 case nsSwGetSetExpType::GSE_SEQ
: nRet
= SetVariableType::SEQUENCE
/*1*/; break;
86 case nsSwGetSetExpType::GSE_FORMULA
: nRet
= SetVariableType::FORMULA
/*2*/; break;
87 case nsSwGetSetExpType::GSE_STRING
: nRet
= SetVariableType::STRING
/*3*/; break;
91 //-----------------------------------------------------------------------------
92 sal_Int32
lcl_APIToSubType(const uno::Any
& rAny
)
99 case SetVariableType::VAR
: nSet
= nsSwGetSetExpType::GSE_EXPR
; break;
100 case SetVariableType::SEQUENCE
: nSet
= nsSwGetSetExpType::GSE_SEQ
; break;
101 case SetVariableType::FORMULA
: nSet
= nsSwGetSetExpType::GSE_FORMULA
; break;
102 case SetVariableType::STRING
: nSet
= nsSwGetSetExpType::GSE_STRING
; break;
104 DBG_ERROR("wrong value");
110 //-----------------------------------------------------------------------------
112 void ReplacePoint( String
& rTmpName
, BOOL bWithCommandType
)
114 // replace first and last (if bWithCommandType: last two) dot Ersten und letzten Punkt ersetzen, da in Tabellennamen Punkte erlaubt sind
115 // since table names may contain dots
117 xub_StrLen nLen
= rTmpName
.Len();
118 sal_Unicode
*pStr
= rTmpName
.GetBufferAccess(), *pBackStr
= pStr
+ nLen
;
120 long nBackCount
= bWithCommandType
? 2 : 1;
123 for( i
= nLen
; i
; --i
, pBackStr
-- )
124 if( '.' == *pBackStr
)
126 *pBackStr
= DB_DELIM
;
130 for( i
= 0; i
< nLen
; ++i
, ++pStr
)
138 SwTxtNode
* GetFirstTxtNode( const SwDoc
& rDoc
, SwPosition
& rPos
,
139 const SwCntntFrm
*pCFrm
, Point
&rPt
)
141 SwTxtNode
* pTxtNode
= 0;
144 const SwNodes
& rNodes
= rDoc
.GetNodes();
145 rPos
.nNode
= *rNodes
.GetEndOfContent().StartOfSectionNode();
147 while( 0 != (pCNd
= rNodes
.GoNext( &rPos
.nNode
) ) &&
148 0 == ( pTxtNode
= pCNd
->GetTxtNode() ) )
150 ASSERT( pTxtNode
, "wo ist der 1.TextNode" );
151 rPos
.nContent
.Assign( pTxtNode
, 0 );
153 else if ( !pCFrm
->IsValid() )
155 pTxtNode
= (SwTxtNode
*)pCFrm
->GetNode();
156 rPos
.nNode
= *pTxtNode
;
157 rPos
.nContent
.Assign( pTxtNode
, 0 );
161 pCFrm
->GetCrsrOfst( &rPos
, rPt
);
162 pTxtNode
= rPos
.nNode
.GetNode().GetTxtNode();
167 const SwTxtNode
* GetBodyTxtNode( const SwDoc
& rDoc
, SwPosition
& rPos
,
170 const SwLayoutFrm
* pLayout
= (SwLayoutFrm
*)rFrm
.GetUpper();
171 const SwTxtNode
* pTxtNode
= 0;
175 if( pLayout
->IsFlyFrm() )
177 // hole das FlyFormat
178 SwFrmFmt
* pFlyFmt
= ((SwFlyFrm
*)pLayout
)->GetFmt();
179 ASSERT( pFlyFmt
, "kein FlyFormat gefunden, wo steht das Feld" );
181 const SwFmtAnchor
&rAnchor
= pFlyFmt
->GetAnchor();
183 if( FLY_AT_FLY
== rAnchor
.GetAnchorId() )
185 // und der Fly muss irgendwo angehaengt sein, also
187 pLayout
= (SwLayoutFrm
*)((SwFlyFrm
*)pLayout
)->GetAnchorFrm();
190 else if( FLY_AT_CNTNT
== rAnchor
.GetAnchorId() ||
191 FLY_AUTO_CNTNT
== rAnchor
.GetAnchorId() ||
192 FLY_IN_CNTNT
== rAnchor
.GetAnchorId() )
194 ASSERT( rAnchor
.GetCntntAnchor(), "keine gueltige Position" );
195 rPos
= *rAnchor
.GetCntntAnchor();
196 pTxtNode
= rPos
.nNode
.GetNode().GetTxtNode();
197 if( FLY_AT_CNTNT
== rAnchor
.GetAnchorId() )
198 ((SwTxtNode
*)pTxtNode
)->MakeStartIndex( &rPos
.nContent
);
199 // oder doch besser das Ende vom (Anker-)TextNode nehmen ??
200 // ((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent );
202 // noch nicht abbrechen, kann ja auch noch im
203 // Header/Footer/Footnote/Fly stehen !!
204 pLayout
= ((SwFlyFrm
*)pLayout
)->GetAnchorFrm()
205 ? ((SwFlyFrm
*)pLayout
)->GetAnchorFrm()->GetUpper() : 0;
210 pLayout
->FindPageFrm()->GetCntntPosition(
211 pLayout
->Frm().Pos(), rPos
);
212 pTxtNode
= rPos
.nNode
.GetNode().GetTxtNode();
215 else if( pLayout
->IsFtnFrm() )
217 // hole den Node vom Anker
218 const SwTxtFtn
* pFtn
= ((SwFtnFrm
*)pLayout
)->GetAttr();
219 pTxtNode
= &pFtn
->GetTxtNode();
220 rPos
.nNode
= *pTxtNode
;
221 rPos
.nContent
= *pFtn
->GetStart();
223 else if( pLayout
->IsHeaderFrm() || pLayout
->IsFooterFrm() )
225 const SwCntntFrm
* pCntFrm
;
226 const SwPageFrm
* pPgFrm
= pLayout
->FindPageFrm();
227 if( pLayout
->IsHeaderFrm() )
229 const SwTabFrm
*pTab
;
230 if( 0 != ( pCntFrm
= pPgFrm
->FindFirstBodyCntnt()) &&
231 0 != (pTab
= pCntFrm
->FindTabFrm()) && pTab
->IsFollow() &&
232 pTab
->GetTable()->GetRowsToRepeat() > 0 &&
233 pTab
->IsInHeadline( *pCntFrm
) )
235 // take the next line
236 const SwLayoutFrm
* pRow
= pTab
->GetFirstNonHeadlineRow();
237 pCntFrm
= pRow
->ContainsCntnt();
241 pCntFrm
= pPgFrm
->FindLastBodyCntnt();
245 pTxtNode
= pCntFrm
->GetNode()->GetTxtNode();
246 rPos
.nNode
= *pTxtNode
;
247 ((SwTxtNode
*)pTxtNode
)->MakeEndIndex( &rPos
.nContent
);
251 Point
aPt( pLayout
->Frm().Pos() );
252 aPt
.Y()++; // aus dem Header raus
253 pCntFrm
= pPgFrm
->GetCntntPos( aPt
, FALSE
, TRUE
, FALSE
);
254 pTxtNode
= GetFirstTxtNode( rDoc
, rPos
, pCntFrm
, aPt
);
259 pLayout
= pLayout
->GetUpper();
262 break; // gefunden und beende die Schleife
267 /*--------------------------------------------------------------------
268 Beschreibung: SwSetExpFieldType by JP
269 --------------------------------------------------------------------*/
271 SwGetExpFieldType::SwGetExpFieldType(SwDoc
* pDc
)
272 : SwValueFieldType( pDc
, RES_GETEXPFLD
)
276 SwFieldType
* SwGetExpFieldType::Copy() const
278 return new SwGetExpFieldType(GetDoc());
281 void SwGetExpFieldType::Modify( SfxPoolItem
*, SfxPoolItem
* pNew
)
283 if( pNew
&& RES_DOCPOS_UPDATE
== pNew
->Which() )
284 SwModify::Modify( 0, pNew
);
285 // sonst nichts weiter expandieren
288 /*--------------------------------------------------------------------
289 Beschreibung: SwGetExpField by JP
290 --------------------------------------------------------------------*/
292 SwGetExpField::SwGetExpField(SwGetExpFieldType
* pTyp
, const String
& rFormel
,
293 USHORT nSub
, ULONG nFmt
)
294 : SwFormulaField( pTyp
, nFmt
, 0.0 ),
295 bIsInBodyTxt( TRUE
),
297 bLateInitialization( false )
299 SetFormula( rFormel
);
302 String
SwGetExpField::Expand() const
304 if(nSubType
& nsSwExtendedSubType::SUB_CMD
)
310 String
SwGetExpField::GetCntnt(BOOL bName
) const
314 String
aStr( SwFieldType::GetTypeStr( static_cast<USHORT
>(nsSwGetSetExpType::GSE_FORMULA
& nSubType
318 aStr
+= GetFormula();
324 SwField
* SwGetExpField::Copy() const
326 SwGetExpField
*pTmp
= new SwGetExpField((SwGetExpFieldType
*)GetTyp(),
327 GetFormula(), nSubType
, GetFormat());
328 pTmp
->SetLanguage(GetLanguage());
329 pTmp
->SwValueField::SetValue(GetValue());
330 pTmp
->sExpand
= sExpand
;
331 pTmp
->bIsInBodyTxt
= bIsInBodyTxt
;
332 pTmp
->SetAutomaticLanguage(IsAutomaticLanguage());
333 if( bLateInitialization
)
334 pTmp
->SetLateInitialization();
339 void SwGetExpField::ChangeExpansion( const SwFrm
& rFrm
, const SwTxtFld
& rFld
)
341 if( bIsInBodyTxt
) // nur Felder in Footer, Header, FootNote, Flys
344 ASSERT( !rFrm
.IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" );
346 // bestimme mal das Dokument (oder geht es noch einfacher?)
347 const SwTxtNode
* pTxtNode
= &rFld
.GetTxtNode();
348 SwDoc
& rDoc
= *(SwDoc
*)pTxtNode
->GetDoc();
350 // einen Index fuers bestimmen vom TextNode anlegen
351 SwPosition
aPos( SwNodeIndex( rDoc
.GetNodes() ) );
352 pTxtNode
= GetBodyTxtNode( rDoc
, aPos
, rFrm
);
354 // Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu
355 // das ChnageExpansion uebers Layout-Formatieren aufgerufen wird
356 // aber kein TxtNode vorhanden ist
361 if( bLateInitialization
)
363 SwFieldType
* pSetExpFld
= rDoc
.GetFldType(RES_SETEXPFLD
, GetFormula(), sal_False
);
366 bLateInitialization
= false;
367 if( !(GetSubType() & nsSwGetSetExpType::GSE_STRING
) &&
368 static_cast< SwSetExpFieldType
* >(pSetExpFld
)->GetType() == nsSwGetSetExpType::GSE_STRING
)
369 SetSubType( nsSwGetSetExpType::GSE_STRING
);
373 _SetGetExpFld
aEndFld( aPos
.nNode
, &rFld
, &aPos
.nContent
);
374 if(GetSubType() & nsSwGetSetExpType::GSE_STRING
)
378 rDoc
.FldsToExpand( ppHashTbl
, nSize
, aEndFld
);
379 LookString( ppHashTbl
, nSize
, GetFormula(), sExpand
);
380 ::DeleteHashTable( ppHashTbl
, nSize
); // HashTabelle loeschen
384 // fuelle den Calculator mit den Werten
385 SwCalc
aCalc( rDoc
);
386 rDoc
.FldsToCalc(aCalc
, aEndFld
);
389 SetValue(aCalc
.Calculate(GetFormula()).GetDouble());
391 // Auswertung nach Format
392 sExpand
= ((SwValueFieldType
*)GetTyp())->ExpandValue(
393 GetValue(), GetFormat(), GetLanguage());
397 String
SwGetExpField::GetPar2() const
402 void SwGetExpField::SetPar2(const String
& rStr
)
407 USHORT
SwGetExpField::GetSubType() const
412 void SwGetExpField::SetSubType(USHORT nType
)
417 void SwGetExpField::SetLanguage(USHORT nLng
)
419 if (nSubType
& nsSwExtendedSubType::SUB_CMD
)
420 SwField::SetLanguage(nLng
);
422 SwValueField::SetLanguage(nLng
);
425 /*-----------------07.03.98 16:08-------------------
427 --------------------------------------------------*/
428 BOOL
SwGetExpField::QueryValue( uno::Any
& rAny
, USHORT nWhichId
) const
432 case FIELD_PROP_DOUBLE
:
435 case FIELD_PROP_FORMAT
:
436 rAny
<<= (sal_Int32
)GetFormat();
438 case FIELD_PROP_USHORT1
:
439 rAny
<<= (sal_Int16
)nSubType
;
441 case FIELD_PROP_PAR1
:
442 rAny
<<= OUString( GetFormula() );
444 case FIELD_PROP_SUBTYPE
:
446 sal_Int16 nRet
= lcl_SubTypeToAPI(GetSubType() & 0xff);
450 case FIELD_PROP_BOOL2
:
452 BOOL bTmp
= 0 != (nSubType
& nsSwExtendedSubType::SUB_CMD
);
453 rAny
.setValue(&bTmp
, ::getBooleanCppuType());
456 case FIELD_PROP_PAR4
:
457 rAny
<<= rtl::OUString(GetExpStr());
460 return SwField::QueryValue(rAny
, nWhichId
);
464 /*-----------------07.03.98 16:08-------------------
466 --------------------------------------------------*/
467 BOOL
SwGetExpField::PutValue( const uno::Any
& rAny
, USHORT nWhichId
)
473 case FIELD_PROP_DOUBLE
:
474 SwValueField::SetValue(*(double*) rAny
.getValue());
476 case FIELD_PROP_FORMAT
:
480 case FIELD_PROP_USHORT1
:
482 nSubType
= static_cast<USHORT
>(nTmp
);
484 case FIELD_PROP_PAR1
:
485 SetFormula( ::GetString( rAny
, sTmp
));
487 case FIELD_PROP_SUBTYPE
:
488 nTmp
= lcl_APIToSubType(rAny
);
490 SetSubType( static_cast<USHORT
>((GetSubType() & 0xff00) | nTmp
));
492 case FIELD_PROP_BOOL2
:
493 if(*(sal_Bool
*) rAny
.getValue())
494 nSubType
|= nsSwExtendedSubType::SUB_CMD
;
496 nSubType
&= (~nsSwExtendedSubType::SUB_CMD
);
498 case FIELD_PROP_PAR4
:
499 ChgExpStr(::GetString( rAny
, sTmp
));
502 return SwField::PutValue(rAny
, nWhichId
);
507 /*-----------------JP: 17.06.93 -------------------
509 --------------------------------------------------*/
511 SwSetExpFieldType::SwSetExpFieldType( SwDoc
* pDc
, const String
& rName
, USHORT nTyp
)
512 : SwValueFieldType( pDc
, RES_SETEXPFLD
),
515 sDelim( String::CreateFromAscii( "." ) ),
516 nType(nTyp
), nLevel( UCHAR_MAX
),
519 if( ( nsSwGetSetExpType::GSE_SEQ
| nsSwGetSetExpType::GSE_STRING
) & nType
)
520 EnableFormat(FALSE
); // Numberformatter nicht einsetzen
523 SwFieldType
* SwSetExpFieldType::Copy() const
525 SwSetExpFieldType
* pNew
= new SwSetExpFieldType(GetDoc(), sName
, nType
);
526 pNew
->bDeleted
= bDeleted
;
527 pNew
->sDelim
= sDelim
;
528 pNew
->nLevel
= nLevel
;
533 const String
& SwSetExpFieldType::GetName() const
538 void SwSetExpFieldType::Modify( SfxPoolItem
*, SfxPoolItem
* )
540 return; // nicht weiter expandieren
543 void SwSetExpFieldType::SetSeqFormat(ULONG nFmt
)
545 SwClientIter
aIter(*this);
546 for( SwFmtFld
* pFld
= (SwFmtFld
*)aIter
.First( TYPE(SwFmtFld
) );
547 pFld
; pFld
= (SwFmtFld
*)aIter
.Next() )
548 pFld
->GetFld()->ChangeFormat( nFmt
);
551 ULONG
SwSetExpFieldType::GetSeqFormat()
554 return SVX_NUM_ARABIC
;
556 SwField
*pFld
= ((SwFmtFld
*)GetDepends())->GetFld();
557 return pFld
->GetFormat();
560 USHORT
SwSetExpFieldType::SetSeqRefNo( SwSetExpField
& rFld
)
562 if( !GetDepends() || !(nsSwGetSetExpType::GSE_SEQ
& nType
) )
565 extern void InsertSort( SvUShorts
& rArr
, USHORT nIdx
, USHORT
* pInsPos
= 0 );
566 SvUShorts
aArr( 64 );
570 // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue
571 // bestimmt werden muss.
572 SwClientIter
aIter( *this );
573 const SwTxtNode
* pNd
;
574 for( SwFmtFld
* pF
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
)); pF
;
575 pF
= (SwFmtFld
*)aIter
.Next() )
576 if( pF
->GetFld() != &rFld
&& pF
->GetTxtFld() &&
577 0 != ( pNd
= pF
->GetTxtFld()->GetpTxtNode() ) &&
578 pNd
->GetNodes().IsDocNodes() )
579 InsertSort( aArr
, ((SwSetExpField
*)pF
->GetFld())->GetSeqNumber() );
582 // teste erstmal ob die Nummer schon vorhanden ist:
583 USHORT nNum
= rFld
.GetSeqNumber();
584 if( USHRT_MAX
!= nNum
)
586 for( n
= 0; n
< aArr
.Count(); ++n
)
587 if( aArr
[ n
] > nNum
)
588 return nNum
; // nicht vorhanden -> also benutzen
589 else if( aArr
[ n
] == nNum
)
590 break; // schon vorhanden -> neue erzeugen
592 if( n
== aArr
.Count() )
593 return nNum
; // nicht vorhanden -> also benutzen
596 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
597 for( n
= 0; n
< aArr
.Count(); ++n
)
601 rFld
.SetSeqNumber( n
);
605 USHORT
SwSetExpFieldType::GetSeqFldList( SwSeqFldList
& rList
)
608 rList
.Remove( 0, rList
.Count() );
610 SwClientIter
aIter( *this );
611 const SwTxtNode
* pNd
;
612 for( SwFmtFld
* pF
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
)); pF
;
613 pF
= (SwFmtFld
*)aIter
.Next() )
614 if( pF
->GetTxtFld() &&
615 0 != ( pNd
= pF
->GetTxtFld()->GetpTxtNode() ) &&
616 pNd
->GetNodes().IsDocNodes() )
618 _SeqFldLstElem
* pNew
= new _SeqFldLstElem(
619 pNd
->GetExpandTxt( 0, (*pF
->GetTxtFld()->GetStart()) + 1 ),
620 ((SwSetExpField
*)pF
->GetFld())->GetSeqNumber() );
621 rList
.InsertSort( pNew
);
624 return rList
.Count();
628 void SwSetExpFieldType::SetChapter( SwSetExpField
& rFld
, const SwNode
& rNd
)
630 const SwTxtNode
* pTxtNd
= rNd
.FindOutlineNodeOfLevel( nLevel
);
633 SwNumRule
* pRule
= pTxtNd
->GetNumRule();
637 // --> OD 2005-11-02 #i51089 - TUNING#
638 if ( pTxtNd
->GetNum() )
640 const SwNodeNum
& aNum
= *(pTxtNd
->GetNum());
642 // nur die Nummer besorgen, ohne Pre-/Post-fixstrings
643 String
sNumber( pRule
->MakeNumString(aNum
, FALSE
));
646 rFld
.ChgExpStr( ( sNumber
+= sDelim
) += rFld
.GetExpStr() );
651 "<SwSetExpFieldType::SetChapter(..)> - text node with numbering rule, but without number. This is a serious defect -> inform OD" );
657 /* -----------------24.03.99 09:44-------------------
659 * --------------------------------------------------*/
660 BOOL
SwSetExpFieldType::QueryValue( uno::Any
& rAny
, USHORT nWhichId
) const
664 case FIELD_PROP_SUBTYPE
:
666 sal_Int16 nRet
= lcl_SubTypeToAPI(GetType());
670 case FIELD_PROP_PAR2
:
671 rAny
<<= OUString(GetDelimiter());
673 case FIELD_PROP_SHORT1
:
675 sal_Int8 nRet
= nLevel
< MAXLEVEL
? nLevel
: -1;
680 DBG_ERROR("illegal property");
685 BOOL
SwSetExpFieldType::PutValue( const uno::Any
& rAny
, USHORT nWhichId
)
689 case FIELD_PROP_SUBTYPE
:
691 sal_Int32 nSet
= lcl_APIToSubType(rAny
);
693 SetType(static_cast<USHORT
>(nSet
));
696 case FIELD_PROP_PAR2
:
699 if( ::GetString( rAny
, sTmp
).Len() )
700 // SetDelimiter( sTmp.GetChar( 0 ));
701 SetDelimiter( sTmp
);
703 SetDelimiter(String::CreateFromAscii( " "));
706 case FIELD_PROP_SHORT1
:
710 if(nLvl
< 0 || nLvl
>= MAXLEVEL
)
711 SetOutlineLvl(UCHAR_MAX
);
717 DBG_ERROR("illegal property");
722 BOOL
SwSeqFldList::InsertSort( _SeqFldLstElem
* pNew
)
724 sal_Unicode
* p
= pNew
->sDlgEntry
.GetBufferAccess();
733 BOOL bRet
= SeekEntry( *pNew
, &nPos
);
735 C40_INSERT( _SeqFldLstElem
, pNew
, nPos
);
739 BOOL
SwSeqFldList::SeekEntry( const _SeqFldLstElem
& rNew
, USHORT
* pP
)
741 USHORT nO
= Count(), nM
, nU
= 0;
744 CollatorWrapper
& rCaseColl
= ::GetAppCaseCollator(),
745 & rColl
= ::GetAppCollator();
746 const CharClass
& rCC
= GetAppCharClass();
748 //#59900# Die Sortierung soll die Nummer korrekt einordnen
749 //also "10" nach "9" und nicht "10" nach "1"
750 const String
& rTmp2
= rNew
.sDlgEntry
;
751 xub_StrLen nFndPos2
= 0;
752 String
sNum2( rTmp2
.GetToken( 0, ' ', nFndPos2
));
753 BOOL bIsNum2IsNumeric
= rCC
.isAsciiNumeric( sNum2
);
754 sal_Int32 nNum2
= bIsNum2IsNumeric
? sNum2
.ToInt32() : 0;
759 nM
= nU
+ ( nO
- nU
) / 2;
761 //#59900# Die Sortierung soll die Nummer korrekt einordnen
762 //also "10" nach "9" und nicht "10" nach "1"
763 const String
& rTmp1
= (*((_SeqFldLstElem
**)pData
+ nM
))->sDlgEntry
;
764 xub_StrLen nFndPos1
= 0;
765 String
sNum1( rTmp1
.GetToken( 0, ' ', nFndPos1
));
768 if( bIsNum2IsNumeric
&& rCC
.isNumeric( sNum1
) )
770 sal_Int32 nNum1
= sNum1
.ToInt32();
771 nCmp
= nNum2
- nNum1
;
773 nCmp
= rCaseColl
.compareString( rTmp2
.Copy( nFndPos2
),
774 rTmp1
.Copy( nFndPos1
));
777 nCmp
= rColl
.compareString( rTmp2
, rTmp1
);
796 /*--------------------------------------------------------------------
797 Beschreibung: SwSetExpField by JP
798 --------------------------------------------------------------------*/
800 SwSetExpField::SwSetExpField(SwSetExpFieldType
* pTyp
, const String
& rFormel
,
802 : SwFormulaField( pTyp
, nFmt
, 0.0 ), nSeqNo( USHRT_MAX
),
806 // SubType ignorieren !!!
808 if( IsSequenceFld() )
810 SwValueField::SetValue(1.0);
813 String
sFormel(rFormel
);
814 sFormel
+= pTyp
->GetName();
822 String
SwSetExpField::Expand() const
825 if (nSubType
& nsSwExtendedSubType::SUB_CMD
)
826 { // Der CommandString ist gefragt
827 aStr
= GetTyp()->GetName();
828 aStr
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ));
829 aStr
+= GetFormula();
831 else if(!(nSubType
& nsSwExtendedSubType::SUB_INVISIBLE
))
832 { // Der Wert ist sichtbar
838 /*--------------------------------------------------------------------
839 Beschreibung: liefert den Namen oder den Inhalt
840 --------------------------------------------------------------------*/
842 String
SwSetExpField::GetCntnt(BOOL bName
) const
848 if( IsSequenceFld() )
849 nStrType
= TYP_SEQFLD
;
851 nStrType
= TYP_SETINPFLD
;
853 nStrType
= TYP_SETFLD
;
855 String
aStr( SwFieldType::GetTypeStr( nStrType
) );
857 aStr
+= GetTyp()->GetName();
859 if( TYP_SEQFLD
!= nStrType
)
861 // Sequence nicht die Formel ausgeben
862 aStr
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ));
863 aStr
+= GetFormula();
870 SwField
* SwSetExpField::Copy() const
872 SwSetExpField
*pTmp
= new SwSetExpField((SwSetExpFieldType
*)GetTyp(),
873 GetFormula(), GetFormat());
874 pTmp
->SwValueField::SetValue(GetValue());
875 pTmp
->sExpand
= sExpand
;
876 pTmp
->SetAutomaticLanguage(IsAutomaticLanguage());
877 pTmp
->SetLanguage(GetLanguage());
878 pTmp
->aPText
= aPText
;
879 pTmp
->bInput
= bInput
;
880 pTmp
->nSeqNo
= nSeqNo
;
881 pTmp
->SetSubType(GetSubType());
886 void SwSetExpField::SetSubType(USHORT nSub
)
888 ((SwSetExpFieldType
*)GetTyp())->SetType(nSub
& 0xff);
889 nSubType
= nSub
& 0xff00;
891 DBG_ASSERT( (nSub
& 0xff) != 3, "SubType ist illegal!" );
894 USHORT
SwSetExpField::GetSubType() const
896 return ((SwSetExpFieldType
*)GetTyp())->GetType() | nSubType
;
899 void SwSetExpField::SetValue( const double& rAny
)
901 SwValueField::SetValue(rAny
);
903 if( IsSequenceFld() )
904 sExpand
= FormatNumber( (USHORT
)GetValue(), GetFormat() );
906 sExpand
= ((SwValueFieldType
*)GetTyp())->ExpandValue( rAny
,
907 GetFormat(), GetLanguage());
910 void SwGetExpField::SetValue( const double& rAny
)
912 SwValueField::SetValue(rAny
);
913 sExpand
= ((SwValueFieldType
*)GetTyp())->ExpandValue( rAny
, GetFormat(),
916 /* -----------------14.07.99 12:21-------------------
917 Description: Find the index of the reference text
918 following the current field
919 --------------------------------------------------*/
920 xub_StrLen
SwGetExpField::GetReferenceTextPos( const SwFmtFld
& rFmt
, SwDoc
& rDoc
)
923 const SwTxtFld
* pTxtFld
= rFmt
.GetTxtFld();
924 const SwTxtNode
& rTxtNode
= pTxtFld
->GetTxtNode();
926 xub_StrLen nRet
= *pTxtFld
->GetStart() + 1;
927 String sNodeText
= rTxtNode
.GetTxt();
928 sNodeText
.Erase(0, nRet
);
931 //now check if sNodeText starts with a non-alphanumeric character plus a blank
932 USHORT nSrcpt
= pBreakIt
->GetRealScriptOfText( sNodeText
, 0 );
934 static USHORT nIds
[] =
936 RES_CHRATR_LANGUAGE
, RES_CHRATR_LANGUAGE
,
937 RES_CHRATR_FONT
, RES_CHRATR_FONT
,
938 RES_CHRATR_CJK_LANGUAGE
, RES_CHRATR_CJK_LANGUAGE
,
939 RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONT
,
940 RES_CHRATR_CTL_LANGUAGE
, RES_CHRATR_CTL_LANGUAGE
,
941 RES_CHRATR_CTL_FONT
, RES_CHRATR_CTL_FONT
,
944 SwAttrSet
aSet(rDoc
.GetAttrPool(), nIds
);
945 rTxtNode
.GetAttr(aSet
, nRet
, nRet
+1);
947 if( RTL_TEXTENCODING_SYMBOL
!= ((SvxFontItem
&)aSet
.Get(
948 GetWhichOfScript( RES_CHRATR_FONT
, nSrcpt
)) ).GetCharSet() )
950 LanguageType eLang
= ((SvxLanguageItem
&)aSet
.Get(
951 GetWhichOfScript( RES_CHRATR_LANGUAGE
, nSrcpt
)) ).GetLanguage();
952 CharClass
aCC( SvxCreateLocale( eLang
));
953 sal_Unicode c0
= sNodeText
.GetChar(0);
954 BOOL bIsAlphaNum
= aCC
.isAlphaNumeric( sNodeText
, 0 );
956 (c0
== ' ' || c0
== '\t'))
959 if( sNodeText
.Len() > 1 &&
960 (sNodeText
.GetChar(1) == ' ' ||
961 sNodeText
.GetChar(1) == '\t'))
970 /*--------------------------------------------------------------------
971 Beschreibung: Parameter setzen
972 --------------------------------------------------------------------*/
974 const String
& SwSetExpField::GetPar1() const
976 return ((SwSetExpFieldType
*)GetTyp())->GetName();
979 String
SwSetExpField::GetPar2() const
981 USHORT nType
= ((SwSetExpFieldType
*)GetTyp())->GetType();
983 if (nType
& nsSwGetSetExpType::GSE_STRING
)
985 return GetExpandedFormula();
988 void SwSetExpField::SetPar2(const String
& rStr
)
990 USHORT nType
= ((SwSetExpFieldType
*)GetTyp())->GetType();
992 if( !(nType
& nsSwGetSetExpType::GSE_SEQ
) || rStr
.Len() )
994 if (nType
& nsSwGetSetExpType::GSE_STRING
)
997 SetExpandedFormula(rStr
);
1001 /*--------------------------------------------------------------------
1002 Beschreibung: Eingabefeld Type
1003 ---------------------------------------------------------------------*/
1005 SwInputFieldType::SwInputFieldType( SwDoc
* pD
)
1006 : SwFieldType( RES_INPUTFLD
), pDoc( pD
)
1010 SwFieldType
* SwInputFieldType::Copy() const
1012 SwInputFieldType
* pType
= new SwInputFieldType( pDoc
);
1016 /*--------------------------------------------------------------------
1017 Beschreibung: Eingabefeld
1018 --------------------------------------------------------------------*/
1020 SwInputField::SwInputField(SwInputFieldType
* pTyp
, const String
& rContent
,
1021 const String
& rPrompt
, USHORT nSub
, ULONG nFmt
) :
1022 SwField(pTyp
, nFmt
), aContent(rContent
), aPText(rPrompt
), nSubType(nSub
)
1026 String
SwInputField::GetCntnt(BOOL bName
) const
1030 String
aStr(SwField::GetCntnt(bName
));
1031 if ((nSubType
& 0x00ff) == INP_USR
)
1033 aStr
+= GetTyp()->GetName();
1042 SwField
* SwInputField::Copy() const
1044 SwInputField
* pFld
= new SwInputField((SwInputFieldType
*)GetTyp(), aContent
,
1045 aPText
, GetSubType(), GetFormat());
1047 pFld
->SetHelp(aHelp
);
1048 pFld
->SetToolTip(aToolTip
);
1050 pFld
->SetAutomaticLanguage(IsAutomaticLanguage());
1054 String
SwInputField::Expand() const
1057 if((nSubType
& 0x00ff) == INP_TXT
)
1060 else if( (nSubType
& 0x00ff) == INP_USR
)
1062 SwUserFieldType
* pUserTyp
= (SwUserFieldType
*)
1063 ((SwInputFieldType
*)GetTyp())->GetDoc()->
1064 GetFldType( RES_USERFLD
, aContent
, false );
1066 sRet
= pUserTyp
->GetContent();
1071 /*-----------------06.03.98 11:12-------------------
1073 --------------------------------------------------*/
1074 BOOL
SwInputField::QueryValue( uno::Any
& rAny
, USHORT nWhichId
) const
1078 case FIELD_PROP_PAR1
:
1079 rAny
<<= OUString( aContent
);
1081 case FIELD_PROP_PAR2
:
1082 rAny
<<= OUString( aPText
);
1084 case FIELD_PROP_PAR3
:
1085 rAny
<<= OUString( aHelp
);
1087 case FIELD_PROP_PAR4
:
1088 rAny
<<= OUString( aToolTip
);
1091 DBG_ERROR("illegal property");
1095 /*-----------------06.03.98 11:12-------------------
1097 --------------------------------------------------*/
1098 BOOL
SwInputField::PutValue( const uno::Any
& rAny
, USHORT nWhichId
)
1102 case FIELD_PROP_PAR1
:
1103 ::GetString( rAny
, aContent
);
1105 case FIELD_PROP_PAR2
:
1106 ::GetString( rAny
, aPText
);
1108 case FIELD_PROP_PAR3
:
1109 ::GetString( rAny
, aHelp
);
1111 case FIELD_PROP_PAR4
:
1112 ::GetString( rAny
, aToolTip
);
1115 DBG_ERROR("illegal property");
1119 /*--------------------------------------------------------------------
1120 Beschreibung: Bedingung setzen
1121 --------------------------------------------------------------------*/
1123 void SwInputField::SetPar1(const String
& rStr
)
1128 const String
& SwInputField::GetPar1() const
1133 /*--------------------------------------------------------------------
1134 Beschreibung: True/False Text
1135 --------------------------------------------------------------------*/
1137 void SwInputField::SetPar2(const String
& rStr
)
1142 String
SwInputField::GetPar2() const
1147 void SwInputField::SetHelp(const String
& rStr
)
1152 String
SwInputField::GetHelp() const
1157 void SwInputField::SetToolTip(const String
& rStr
)
1162 String
SwInputField::GetToolTip() const
1167 BOOL
SwInputField::isFormField() const
1169 return aHelp
.Len() > 0 || aToolTip
.Len() > 0;
1172 USHORT
SwInputField::GetSubType() const
1177 void SwInputField::SetSubType(USHORT nSub
)
1181 /*-----------------05.03.98 17:22-------------------
1183 --------------------------------------------------*/
1184 BOOL
SwSetExpField::QueryValue( uno::Any
& rAny
, USHORT nWhichId
) const
1188 case FIELD_PROP_BOOL2
:
1190 sal_Bool bVal
= 0 == (nSubType
& nsSwExtendedSubType::SUB_INVISIBLE
);
1191 rAny
.setValue(&bVal
, ::getBooleanCppuType());
1194 case FIELD_PROP_FORMAT
:
1195 rAny
<<= (sal_Int32
)GetFormat();
1197 case FIELD_PROP_USHORT2
:
1198 rAny
<<= (sal_Int16
)GetFormat();
1200 case FIELD_PROP_USHORT1
:
1201 rAny
<<= (sal_Int16
)nSeqNo
;
1203 case FIELD_PROP_PAR1
:
1204 rAny
<<= OUString ( SwStyleNameMapper::GetProgName(GetPar1(), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL
) );
1206 case FIELD_PROP_PAR2
:
1208 //I18N - if the formula contains only "TypeName+1"
1209 //and it's one of the initially created sequence fields
1210 //then the localized names has to be replaced by a programmatic name
1211 OUString sMyFormula
= SwXFieldMaster::LocalizeFormula(*this, GetFormula(), TRUE
);
1212 rAny
<<= OUString( sMyFormula
);
1215 case FIELD_PROP_DOUBLE
:
1216 rAny
<<= (double)GetValue();
1218 case FIELD_PROP_SUBTYPE
:
1221 nRet
= lcl_SubTypeToAPI(GetSubType() & 0xff);
1225 case FIELD_PROP_PAR3
:
1226 rAny
<<= OUString( aPText
);
1228 case FIELD_PROP_BOOL3
:
1230 BOOL bTmp
= 0 != (nSubType
& nsSwExtendedSubType::SUB_CMD
);
1231 rAny
.setValue(&bTmp
, ::getBooleanCppuType());
1234 case FIELD_PROP_BOOL1
:
1236 BOOL bTmp
= GetInputFlag();
1237 rAny
.setValue(&bTmp
, ::getBooleanCppuType());
1240 case FIELD_PROP_PAR4
:
1241 rAny
<<= rtl::OUString(GetExpStr());
1244 return SwField::QueryValue(rAny
, nWhichId
);
1248 /*-----------------05.03.98 17:22-------------------
1250 --------------------------------------------------*/
1251 BOOL
SwSetExpField::PutValue( const uno::Any
& rAny
, USHORT nWhichId
)
1253 sal_Int32 nTmp32
= 0;
1254 sal_Int16 nTmp16
= 0;
1258 case FIELD_PROP_BOOL2
:
1259 if(*(sal_Bool
*)rAny
.getValue())
1260 nSubType
&= ~nsSwExtendedSubType::SUB_INVISIBLE
;
1262 nSubType
|= nsSwExtendedSubType::SUB_INVISIBLE
;
1264 case FIELD_PROP_FORMAT
:
1268 case FIELD_PROP_USHORT2
:
1271 if(nTmp16
<= SVX_NUMBER_NONE
)
1274 //exception(wrong_value)
1279 case FIELD_PROP_USHORT1
:
1283 case FIELD_PROP_PAR1
:
1284 SetPar1( SwStyleNameMapper::GetUIName(
1285 ::GetString( rAny
, sTmp
), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL
) );
1287 case FIELD_PROP_PAR2
:
1291 //I18N - if the formula contains only "TypeName+1"
1292 //and it's one of the initially created sequence fields
1293 //then the localized names has to be replaced by a programmatic name
1294 OUString sMyFormula
= SwXFieldMaster::LocalizeFormula(*this, uTmp
, FALSE
);
1295 SetFormula( sMyFormula
);
1298 case FIELD_PROP_DOUBLE
:
1305 case FIELD_PROP_SUBTYPE
:
1306 nTmp32
= lcl_APIToSubType(rAny
);
1308 SetSubType(static_cast<USHORT
>((GetSubType() & 0xff00) | nTmp32
));
1310 case FIELD_PROP_PAR3
:
1311 ::GetString( rAny
, aPText
);
1313 case FIELD_PROP_BOOL3
:
1314 if(*(sal_Bool
*) rAny
.getValue())
1315 nSubType
|= nsSwExtendedSubType::SUB_CMD
;
1317 nSubType
&= (~nsSwExtendedSubType::SUB_CMD
);
1319 case FIELD_PROP_BOOL1
:
1320 SetInputFlag(*(sal_Bool
*) rAny
.getValue());
1322 case FIELD_PROP_PAR4
:
1323 ChgExpStr( ::GetString( rAny
, sTmp
));
1326 return SwField::PutValue(rAny
, nWhichId
);