xref: /trunk/main/sw/source/core/fields/expfld.cxx (revision 721f84f2)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 
25 #include <hintids.hxx>
26 #include <unotools/collatorwrapper.hxx>
27 #include <unotools/charclass.hxx>
28 #include <editeng/unolingu.hxx>
29 #include <svx/pageitem.hxx>
30 #include <editeng/langitem.hxx>
31 #include <editeng/fontitem.hxx>
32 #include <com/sun/star/text/SetVariableType.hpp>
33 #include <unofield.hxx>
34 #include <frmfmt.hxx>
35 #include <fmtfld.hxx>
36 #include <txtfld.hxx>
37 #include <fmtanchr.hxx>
38 #include <txtftn.hxx>
39 #include <doc.hxx>
40 #include <layfrm.hxx>
41 #include <pagefrm.hxx>
42 #include <cntfrm.hxx>
43 #include <rootfrm.hxx>
44 #include <tabfrm.hxx>
45 #include <flyfrm.hxx>
46 #include <ftnfrm.hxx>
47 #include <rowfrm.hxx>
48 #include <expfld.hxx>
49 #include <usrfld.hxx>
50 #include <ndtxt.hxx>
51 #include <calc.hxx>
52 #include <pam.hxx>
53 #include <docfld.hxx>
54 #include <swcache.hxx>
55 #include <swtable.hxx>
56 #include <breakit.hxx>
57 #include <SwStyleNameMapper.hxx>
58 #include <unofldmid.h>
59 #include <numrule.hxx>
60 #include <switerator.hxx>
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::text;
64 using ::rtl::OUString;
65 
SV_IMPL_PTRARR(_SwSeqFldList,_SeqFldLstElem *)66 SV_IMPL_PTRARR( _SwSeqFldList, _SeqFldLstElem* )
67 
68 //-----------------------------------------------------------------------------
69 sal_Int16 lcl_SubTypeToAPI(sal_uInt16 nSubType)
70 {
71 		sal_Int16 nRet = 0;
72 		switch(nSubType)
73 		{
74 			case nsSwGetSetExpType::GSE_EXPR:
75                 nRet = SetVariableType::VAR;      // 0
76                 break;
77 			case nsSwGetSetExpType::GSE_SEQ:
78                 nRet = SetVariableType::SEQUENCE; // 1
79                 break;
80 			case nsSwGetSetExpType::GSE_FORMULA:
81                 nRet = SetVariableType::FORMULA;  // 2
82                 break;
83 			case nsSwGetSetExpType::GSE_STRING:
84                 nRet = SetVariableType::STRING;   // 3
85                 break;
86 		}
87 		return nRet;
88 }
89 //-----------------------------------------------------------------------------
lcl_APIToSubType(const uno::Any & rAny)90 sal_Int32 lcl_APIToSubType(const uno::Any& rAny)
91 {
92 		sal_Int16 nVal = 0;
93 		rAny >>= nVal;
94 		sal_Int32 nSet = 0;
95 		switch(nVal)
96 		{
97 			case SetVariableType::VAR:		nSet = nsSwGetSetExpType::GSE_EXPR;  break;
98 			case SetVariableType::SEQUENCE: nSet = nsSwGetSetExpType::GSE_SEQ;  break;
99 			case SetVariableType::FORMULA:  nSet = nsSwGetSetExpType::GSE_FORMULA; break;
100 			case SetVariableType::STRING:	nSet = nsSwGetSetExpType::GSE_STRING;	break;
101 			default:
102 				DBG_ERROR("wrong value");
103 				nSet = -1;
104 		}
105 		return nSet;
106 }
107 
108 //-----------------------------------------------------------------------------
109 
ReplacePoint(String & rTmpName,sal_Bool bWithCommandType)110 void ReplacePoint( String& rTmpName, sal_Bool bWithCommandType )
111 {
112     // replace first and last (if bWithCommandType: last two) dot Ersten und letzten Punkt ersetzen, da in Tabellennamen Punkte erlaubt sind
113     // since table names may contain dots
114 
115 	xub_StrLen nLen = rTmpName.Len();
116 	sal_Unicode *pStr = rTmpName.GetBufferAccess(), *pBackStr = pStr + nLen;
117 
118     long nBackCount = bWithCommandType ? 2 : 1;
119     xub_StrLen i;
120 
121     for( i = nLen; i; --i, pBackStr-- )
122 		if( '.' == *pBackStr )
123 		{
124 			*pBackStr = DB_DELIM;
125             if(!--nBackCount)
126                 break;
127 		}
128 	for( i = 0; i < nLen; ++i, ++pStr )
129 		if( '.' == *pStr )
130 		{
131 			*pStr = DB_DELIM;
132 			break;
133 		}
134 }
135 
GetFirstTxtNode(const SwDoc & rDoc,SwPosition & rPos,const SwCntntFrm * pCFrm,Point & rPt)136 SwTxtNode* GetFirstTxtNode( const SwDoc& rDoc, SwPosition& rPos,
137 							const SwCntntFrm *pCFrm, Point &rPt )
138 {
139 	SwTxtNode* pTxtNode = 0;
140 	if ( !pCFrm )
141 	{
142         const SwNodes& rNodes = rDoc.GetNodes();
143         rPos.nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
144 		SwCntntNode* pCNd;
145         while( 0 != (pCNd = rNodes.GoNext( &rPos.nNode ) ) &&
146 				0 == ( pTxtNode = pCNd->GetTxtNode() ) )
147 						;
148 		ASSERT( pTxtNode, "wo ist der 1.TextNode" );
149 		rPos.nContent.Assign( pTxtNode, 0 );
150 	}
151 	else if ( !pCFrm->IsValid() )
152 	{
153 		pTxtNode = (SwTxtNode*)pCFrm->GetNode();
154 		rPos.nNode = *pTxtNode;
155 		rPos.nContent.Assign( pTxtNode, 0 );
156 	}
157 	else
158 	{
159 		pCFrm->GetCrsrOfst( &rPos, rPt );
160 		pTxtNode = rPos.nNode.GetNode().GetTxtNode();
161 	}
162 	return pTxtNode;
163 }
164 
GetBodyTxtNode(const SwDoc & rDoc,SwPosition & rPos,const SwFrm & rFrm)165 const SwTxtNode* GetBodyTxtNode( const SwDoc& rDoc, SwPosition& rPos,
166 								const SwFrm& rFrm )
167 {
168 	const SwLayoutFrm* pLayout = (SwLayoutFrm*)rFrm.GetUpper();
169 	const SwTxtNode* pTxtNode = 0;
170 
171 	while( pLayout )
172 	{
173 		if( pLayout->IsFlyFrm() )
174 		{
175 			// hole das FlyFormat
176 			SwFrmFmt* pFlyFmt = ((SwFlyFrm*)pLayout)->GetFmt();
177 			ASSERT( pFlyFmt, "kein FlyFormat gefunden, wo steht das Feld" );
178 
179 			const SwFmtAnchor &rAnchor = pFlyFmt->GetAnchor();
180 
181 			if( FLY_AT_FLY == rAnchor.GetAnchorId() )
182 			{
183 				// und der Fly muss irgendwo angehaengt sein, also
184 				// den befragen
185                 pLayout = (SwLayoutFrm*)((SwFlyFrm*)pLayout)->GetAnchorFrm();
186 				continue;
187 			}
188             else if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
189                      (FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
190                      (FLY_AS_CHAR == rAnchor.GetAnchorId()))
191 			{
192 				ASSERT( rAnchor.GetCntntAnchor(), "keine gueltige Position" );
193 				rPos = *rAnchor.GetCntntAnchor();
194 				pTxtNode = rPos.nNode.GetNode().GetTxtNode();
195                 if ( FLY_AT_PARA == rAnchor.GetAnchorId() )
196                 {
197                     const_cast<SwTxtNode*>(pTxtNode)->MakeStartIndex(
198                             &rPos.nContent );
199 // oder doch besser das Ende vom (Anker-)TextNode nehmen ??
200 //					((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent );
201                 }
202 
203 				// noch nicht abbrechen, kann ja auch noch im
204 				// Header/Footer/Footnote/Fly stehen !!
205                 pLayout = ((SwFlyFrm*)pLayout)->GetAnchorFrm()
206                             ? ((SwFlyFrm*)pLayout)->GetAnchorFrm()->GetUpper() : 0;
207 				continue;
208 			}
209 			else
210 			{
211 				pLayout->FindPageFrm()->GetCntntPosition(
212 												pLayout->Frm().Pos(), rPos );
213 				pTxtNode = rPos.nNode.GetNode().GetTxtNode();
214 			}
215 		}
216 		else if( pLayout->IsFtnFrm() )
217 		{
218 			// hole den Node vom Anker
219 			const SwTxtFtn* pFtn = ((SwFtnFrm*)pLayout)->GetAttr();
220 			pTxtNode = &pFtn->GetTxtNode();
221 			rPos.nNode = *pTxtNode;
222 			rPos.nContent = *pFtn->GetStart();
223 		}
224 		else if( pLayout->IsHeaderFrm() || pLayout->IsFooterFrm() )
225 		{
226 			const SwCntntFrm* pCntFrm;
227 			const SwPageFrm* pPgFrm = pLayout->FindPageFrm();
228 			if( pLayout->IsHeaderFrm() )
229 			{
230 				const SwTabFrm *pTab;
231 				if( 0 != ( pCntFrm = pPgFrm->FindFirstBodyCntnt()) &&
232 					0 != (pTab = pCntFrm->FindTabFrm()) && pTab->IsFollow() &&
233                     pTab->GetTable()->GetRowsToRepeat() > 0 &&
234                     pTab->IsInHeadline( *pCntFrm ) )
235                 {
236 					// take the next line
237                     const SwLayoutFrm* pRow = pTab->GetFirstNonHeadlineRow();
238                     pCntFrm = pRow->ContainsCntnt();
239 				}
240 			}
241 			else
242 				pCntFrm = pPgFrm->FindLastBodyCntnt();
243 
244 			if( pCntFrm )
245 			{
246 				pTxtNode = pCntFrm->GetNode()->GetTxtNode();
247 				rPos.nNode = *pTxtNode;
248 				((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent );
249 			}
250 			else
251 			{
252 				Point aPt( pLayout->Frm().Pos() );
253 				aPt.Y()++;		// aus dem Header raus
254 				pCntFrm = pPgFrm->GetCntntPos( aPt, sal_False, sal_True, sal_False );
255 				pTxtNode = GetFirstTxtNode( rDoc, rPos, pCntFrm, aPt );
256 			}
257 		}
258 		else
259 		{
260 			pLayout = pLayout->GetUpper();
261 			continue;
262 		}
263 		break;		// gefunden und beende die Schleife
264 	}
265 	return pTxtNode;
266 }
267 
268 /*--------------------------------------------------------------------
269 	Beschreibung: SwSetExpFieldType by JP
270  --------------------------------------------------------------------*/
271 
SwGetExpFieldType(SwDoc * pDc)272 SwGetExpFieldType::SwGetExpFieldType(SwDoc* pDc)
273 	: SwValueFieldType( pDc, RES_GETEXPFLD )
274 {
275 }
276 
Copy() const277 SwFieldType* SwGetExpFieldType::Copy() const
278 {
279 	return new SwGetExpFieldType(GetDoc());
280 }
281 
Modify(const SfxPoolItem *,const SfxPoolItem * pNew)282 void SwGetExpFieldType::Modify( const SfxPoolItem*, const SfxPoolItem* pNew )
283 {
284 	if( pNew && RES_DOCPOS_UPDATE == pNew->Which() )
285 		NotifyClients( 0, pNew );
286 	// sonst nichts weiter expandieren
287 }
288 
289 /*--------------------------------------------------------------------
290 	Beschreibung: SwGetExpField by JP
291  --------------------------------------------------------------------*/
292 
SwGetExpField(SwGetExpFieldType * pTyp,const String & rFormel,sal_uInt16 nSub,sal_uLong nFmt)293 SwGetExpField::SwGetExpField(SwGetExpFieldType* pTyp, const String& rFormel,
294 							sal_uInt16 nSub, sal_uLong nFmt)
295 	: SwFormulaField( pTyp, nFmt, 0.0 ),
296 	bIsInBodyTxt( sal_True ),
297 	nSubType(nSub),
298 	bLateInitialization( false )
299 {
300 	SetFormula( rFormel );
301 }
302 
Expand() const303 String SwGetExpField::Expand() const
304 {
305 	if(nSubType & nsSwExtendedSubType::SUB_CMD)
306 		return GetFormula();
307 	else
308 		return sExpand;
309 }
310 
GetFieldName() const311 String SwGetExpField::GetFieldName() const
312 {
313     String aStr( SwFieldType::GetTypeStr(
314         static_cast<sal_uInt16>(((nsSwGetSetExpType::GSE_FORMULA & nSubType) != 0)
315                                             ? TYP_FORMELFLD
316                                             : TYP_GETFLD ) ));
317     aStr += ' ';
318     aStr += GetFormula();
319     return aStr;
320 }
321 
Copy() const322 SwField* SwGetExpField::Copy() const
323 {
324 	SwGetExpField *pTmp = new SwGetExpField((SwGetExpFieldType*)GetTyp(),
325 											GetFormula(), nSubType, GetFormat());
326 	pTmp->SetLanguage(GetLanguage());
327 	pTmp->SwValueField::SetValue(GetValue());
328 	pTmp->sExpand 		= sExpand;
329 	pTmp->bIsInBodyTxt 	= bIsInBodyTxt;
330 	pTmp->SetAutomaticLanguage(IsAutomaticLanguage());
331 	if( bLateInitialization )
332 		pTmp->SetLateInitialization();
333 
334 	return pTmp;
335 }
336 
ChangeExpansion(const SwFrm & rFrm,const SwTxtFld & rFld)337 void SwGetExpField::ChangeExpansion( const SwFrm& rFrm, const SwTxtFld& rFld )
338 {
339 	if( bIsInBodyTxt )		// nur Felder in Footer, Header, FootNote, Flys
340 		return;
341 
342 	ASSERT( !rFrm.IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" );
343 
344 	// bestimme mal das Dokument (oder geht es noch einfacher?)
345 	const SwTxtNode* pTxtNode = &rFld.GetTxtNode();
346 	SwDoc& rDoc = *(SwDoc*)pTxtNode->GetDoc();
347 
348 	// einen Index fuers bestimmen vom TextNode anlegen
349 	SwPosition aPos( SwNodeIndex( rDoc.GetNodes() ) );
350 	pTxtNode = GetBodyTxtNode( rDoc, aPos, rFrm );
351 
352 	// Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu
353 	// das ChangeExpansion uebers Layout-Formatieren aufgerufen wird
354 	// aber kein TxtNode vorhanden ist
355 	//
356 	if(!pTxtNode)
357 		return;
358 	// #i82544#
359 	if( bLateInitialization )
360 	{
361 		SwFieldType* pSetExpFld = rDoc.GetFldType(RES_SETEXPFLD, GetFormula(), sal_False);
362 		if( pSetExpFld )
363 		{
364 			bLateInitialization = false;
365 			if( !(GetSubType() & nsSwGetSetExpType::GSE_STRING) &&
366 				static_cast< SwSetExpFieldType* >(pSetExpFld)->GetType() == nsSwGetSetExpType::GSE_STRING )
367 			SetSubType( nsSwGetSetExpType::GSE_STRING );
368 		}
369 	}
370 
371 	_SetGetExpFld aEndFld( aPos.nNode, &rFld, &aPos.nContent );
372 	if(GetSubType() & nsSwGetSetExpType::GSE_STRING)
373 	{
374 		SwHash** ppHashTbl;
375 		sal_uInt16 nSize;
376 		rDoc.FldsToExpand( ppHashTbl, nSize, aEndFld );
377 		LookString( ppHashTbl, nSize, GetFormula(), sExpand );
378 		::DeleteHashTable( ppHashTbl, nSize );		// HashTabelle loeschen
379 	}
380 	else
381 	{
382 		// fuelle den Calculator mit den Werten
383 		SwCalc aCalc( rDoc );
384 		rDoc.FldsToCalc(aCalc, aEndFld);
385 
386 		// Wert berechnen
387 		SetValue(aCalc.Calculate(GetFormula()).GetDouble());
388 
389 		// Auswertung nach Format
390 		sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue(
391 								GetValue(), GetFormat(), GetLanguage());
392 	}
393 }
394 
GetPar2() const395 String SwGetExpField::GetPar2() const
396 {
397 	return GetFormula();
398 }
399 
SetPar2(const String & rStr)400 void SwGetExpField::SetPar2(const String& rStr)
401 {
402 	SetFormula(rStr);
403 }
404 
GetSubType() const405 sal_uInt16 SwGetExpField::GetSubType() const
406 {
407 	return nSubType;
408 }
409 
SetSubType(sal_uInt16 nType)410 void SwGetExpField::SetSubType(sal_uInt16 nType)
411 {
412 	nSubType = nType;
413 }
414 
SetLanguage(sal_uInt16 nLng)415 void SwGetExpField::SetLanguage(sal_uInt16 nLng)
416 {
417 	if (nSubType & nsSwExtendedSubType::SUB_CMD)
418 		SwField::SetLanguage(nLng);
419 	else
420 		SwValueField::SetLanguage(nLng);
421 }
422 
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const423 sal_Bool SwGetExpField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
424 {
425 	switch( nWhichId )
426 	{
427 	case FIELD_PROP_DOUBLE:
428 		rAny <<= GetValue();
429 		break;
430 	case FIELD_PROP_FORMAT:
431 		rAny <<= (sal_Int32)GetFormat();
432 		break;
433 	case FIELD_PROP_USHORT1:
434 		 rAny <<= (sal_Int16)nSubType;
435 		break;
436 	case FIELD_PROP_PAR1:
437 	 	rAny <<= OUString( GetFormula() );
438 		break;
439 	case FIELD_PROP_SUBTYPE:
440 		{
441 			sal_Int16 nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
442 			rAny <<= nRet;
443 		}
444 		break;
445 	case FIELD_PROP_BOOL2:
446 		{
447 			sal_Bool bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD);
448 			rAny.setValue(&bTmp, ::getBooleanCppuType());
449 		}
450 		break;
451 	case FIELD_PROP_PAR4:
452 		rAny <<= rtl::OUString(GetExpStr());
453 		break;
454 	default:
455 		return SwField::QueryValue(rAny, nWhichId);
456 	}
457 	return sal_True;
458 }
459 
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)460 sal_Bool SwGetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
461 {
462 	sal_Int32 nTmp = 0;
463 	String sTmp;
464 	switch( nWhichId )
465 	{
466 	case FIELD_PROP_DOUBLE:
467 		SwValueField::SetValue(*(double*) rAny.getValue());
468 		break;
469 	case FIELD_PROP_FORMAT:
470 		rAny >>= nTmp;
471 		SetFormat(nTmp);
472 		break;
473 	case FIELD_PROP_USHORT1:
474 		 rAny >>= nTmp;
475 		 nSubType = static_cast<sal_uInt16>(nTmp);
476 		break;
477 	case FIELD_PROP_PAR1:
478 	 	SetFormula( ::GetString( rAny, sTmp ));
479 		break;
480 	case FIELD_PROP_SUBTYPE:
481 		nTmp = lcl_APIToSubType(rAny);
482 		if( nTmp >=0 )
483 			SetSubType( static_cast<sal_uInt16>((GetSubType() & 0xff00) | nTmp));
484 		break;
485 	case FIELD_PROP_BOOL2:
486 		if(*(sal_Bool*) rAny.getValue())
487 			nSubType |= nsSwExtendedSubType::SUB_CMD;
488 		else
489 			nSubType &= (~nsSwExtendedSubType::SUB_CMD);
490 		break;
491 	case FIELD_PROP_PAR4:
492 		ChgExpStr(::GetString( rAny, sTmp ));
493 		break;
494 	default:
495 		return SwField::PutValue(rAny, nWhichId);
496 	}
497 	return sal_True;
498 }
499 
SwSetExpFieldType(SwDoc * pDc,const String & rName,sal_uInt16 nTyp)500 SwSetExpFieldType::SwSetExpFieldType( SwDoc* pDc, const String& rName, sal_uInt16 nTyp )
501 	: SwValueFieldType( pDc, RES_SETEXPFLD ),
502 	sName( rName ),
503 	pOutlChgNd( 0 ),
504 	sDelim( String::CreateFromAscii( "." ) ),
505 	nType(nTyp), nLevel( UCHAR_MAX ),
506 	bDeleted( sal_False )
507 {
508 	if( ( nsSwGetSetExpType::GSE_SEQ | nsSwGetSetExpType::GSE_STRING ) & nType )
509 		EnableFormat(sal_False);	// Numberformatter nicht einsetzen
510 }
511 
Copy() const512 SwFieldType* SwSetExpFieldType::Copy() const
513 {
514 	SwSetExpFieldType* pNew = new SwSetExpFieldType(GetDoc(), sName, nType);
515 	pNew->bDeleted = bDeleted;
516 	pNew->sDelim = sDelim;
517 	pNew->nLevel = nLevel;
518 
519 	return pNew;
520 }
521 
GetName() const522 const String& SwSetExpFieldType::GetName() const
523 {
524 	return sName;
525 }
526 
Modify(const SfxPoolItem *,const SfxPoolItem *)527 void SwSetExpFieldType::Modify( const SfxPoolItem*, const SfxPoolItem* )
528 {
529 	return;		// nicht weiter expandieren
530 }
531 
SetSeqFormat(sal_uLong nFmt)532 void SwSetExpFieldType::SetSeqFormat(sal_uLong nFmt)
533 {
534 	SwIterator<SwFmtFld,SwFieldType> aIter(*this);
535 	for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
536 		pFmtFld->GetField()->ChangeFormat( nFmt );
537 }
538 
GetSeqFormat()539 sal_uLong SwSetExpFieldType::GetSeqFormat()
540 {
541 	if( !GetDepends() )
542 		return SVX_NUM_ARABIC;
543 
544 	SwField *pFld = ((SwFmtFld*)GetDepends())->GetField();
545 	return pFld->GetFormat();
546 }
547 
SetSeqRefNo(SwSetExpField & rFld)548 sal_uInt16 SwSetExpFieldType::SetSeqRefNo( SwSetExpField& rFld )
549 {
550 	if( !GetDepends() || !(nsSwGetSetExpType::GSE_SEQ & nType) )
551 		return USHRT_MAX;
552 
553 extern void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos = 0 );
554 	SvUShorts aArr( 64 );
555 
556 	sal_uInt16 n;
557 
558 	// dann testmal, ob die Nummer schon vergeben ist oder ob eine neue
559 	// bestimmt werden muss.
560 	SwIterator<SwFmtFld,SwFieldType> aIter( *this );
561 	const SwTxtNode* pNd;
562 	for( SwFmtFld* pF = aIter.First(); pF; pF = aIter.Next() )
563 		if( pF->GetField() != &rFld && pF->GetTxtFld() &&
564 			0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
565 			pNd->GetNodes().IsDocNodes() )
566 			InsertSort( aArr, ((SwSetExpField*)pF->GetField())->GetSeqNumber() );
567 
568 
569 	// teste erstmal ob die Nummer schon vorhanden ist:
570 	sal_uInt16 nNum = rFld.GetSeqNumber();
571 	if( USHRT_MAX != nNum )
572 	{
573 		for( n = 0; n < aArr.Count(); ++n )
574 			if( aArr[ n ] > nNum )
575 				return nNum;			// nicht vorhanden -> also benutzen
576 			else if( aArr[ n ] == nNum )
577 				break;					// schon vorhanden -> neue erzeugen
578 
579 		if( n == aArr.Count() )
580 			return nNum;			// nicht vorhanden -> also benutzen
581 	}
582 
583 	// alle Nummern entsprechend geflag, also bestimme die richtige Nummer
584 	for( n = 0; n < aArr.Count(); ++n )
585 		if( n != aArr[ n ] )
586 			break;
587 
588 	rFld.SetSeqNumber( n );
589 	return n;
590 }
591 
GetSeqFldList(SwSeqFldList & rList)592 sal_uInt16 SwSetExpFieldType::GetSeqFldList( SwSeqFldList& rList )
593 {
594 	if( rList.Count() )
595 		rList.Remove( 0, rList.Count() );
596 
597 	SwIterator<SwFmtFld,SwFieldType> aIter( *this );
598 	const SwTxtNode* pNd;
599 	for( SwFmtFld* pF = aIter.First(); pF; pF = aIter.Next() )
600 		if( pF->GetTxtFld() &&
601 			0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
602 			pNd->GetNodes().IsDocNodes() )
603 		{
604             _SeqFldLstElem* pNew = new _SeqFldLstElem(
605                     pNd->GetExpandTxt( 0, (*pF->GetTxtFld()->GetStart()) + 1 ),
606                     ((SwSetExpField*)pF->GetField())->GetSeqNumber() );
607 			rList.InsertSort( pNew );
608 		}
609 
610 	return rList.Count();
611 }
612 
613 
SetChapter(SwSetExpField & rFld,const SwNode & rNd)614 void SwSetExpFieldType::SetChapter( SwSetExpField& rFld, const SwNode& rNd )
615 {
616 	const SwTxtNode* pTxtNd = rNd.FindOutlineNodeOfLevel( nLevel );
617 	if( pTxtNd )
618 	{
619         SwNumRule * pRule = pTxtNd->GetNumRule();
620 
621         if (pRule)
622         {
623             // --> OD 2005-11-02 #i51089 - TUNING#
624             if ( pTxtNd->GetNum() )
625             {
626                 const SwNodeNum & aNum = *(pTxtNd->GetNum());
627 
628                 // nur die Nummer besorgen, ohne Pre-/Post-fixstrings
629                 String sNumber( pRule->MakeNumString(aNum, sal_False ));
630 
631                 if( sNumber.Len() )
632                     rFld.ChgExpStr( ( sNumber += sDelim ) += rFld.GetExpStr() );
633             }
634             else
635             {
636                 ASSERT( false,
637                         "<SwSetExpFieldType::SetChapter(..)> - text node with numbering rule, but without number. This is a serious defect -> inform OD" );
638             }
639         }
640 	}
641 }
642 
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const643 sal_Bool SwSetExpFieldType::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
644 {
645 	switch( nWhichId )
646 	{
647 	case FIELD_PROP_SUBTYPE:
648 		{
649 			sal_Int16 nRet = lcl_SubTypeToAPI(GetType());
650 			rAny <<= nRet;
651 		}
652 		break;
653 	case FIELD_PROP_PAR2:
654 		rAny <<= OUString(GetDelimiter());
655 		break;
656 	case FIELD_PROP_SHORT1:
657 		{
658 			sal_Int8 nRet = nLevel < MAXLEVEL? nLevel : -1;
659 			rAny <<= nRet;
660 		}
661 		break;
662 	default:
663 		DBG_ERROR("illegal property");
664 	}
665 	return sal_True;
666 }
667 
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)668 sal_Bool SwSetExpFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
669 {
670 	switch( nWhichId )
671 	{
672 	case FIELD_PROP_SUBTYPE:
673 		{
674 			sal_Int32 nSet = lcl_APIToSubType(rAny);
675 			if(nSet >=0)
676 				SetType(static_cast<sal_uInt16>(nSet));
677 		}
678 		break;
679 	case FIELD_PROP_PAR2:
680 		{
681 			String sTmp;
682 			if( ::GetString( rAny, sTmp ).Len() )
683 //				SetDelimiter( sTmp.GetChar( 0 ));
684 				SetDelimiter( sTmp );
685 			else
686 				SetDelimiter(String::CreateFromAscii( " "));
687 		}
688 		break;
689 	case FIELD_PROP_SHORT1:
690 		{
691 			sal_Int8 nLvl = 0;
692 			rAny >>= nLvl;
693 			if(nLvl < 0 || nLvl >= MAXLEVEL)
694 				SetOutlineLvl(UCHAR_MAX);
695 			else
696 				SetOutlineLvl(nLvl);
697 		}
698 		break;
699 	default:
700 		DBG_ERROR("illegal property");
701 	}
702 	return sal_True;
703 }
704 
InsertSort(_SeqFldLstElem * pNew)705 sal_Bool SwSeqFldList::InsertSort( _SeqFldLstElem* pNew )
706 {
707 	sal_Unicode* p = pNew->sDlgEntry.GetBufferAccess();
708 	while( *p )
709 	{
710 		if( *p < 0x20 )
711 			*p = 0x20;
712 		++p;
713 	}
714 
715 	sal_uInt16 nPos;
716 	sal_Bool bRet = SeekEntry( *pNew, &nPos );
717 	if( !bRet )
718 		C40_INSERT( _SeqFldLstElem, pNew, nPos );
719 	return bRet;
720 }
721 
SeekEntry(const _SeqFldLstElem & rNew,sal_uInt16 * pP)722 sal_Bool SwSeqFldList::SeekEntry( const _SeqFldLstElem& rNew, sal_uInt16* pP )
723 {
724 	sal_uInt16 nO = Count(), nM, nU = 0;
725 	if( nO > 0 )
726 	{
727 		CollatorWrapper & rCaseColl = ::GetAppCaseCollator(),
728 						& rColl = ::GetAppCollator();
729 		const CharClass& rCC = GetAppCharClass();
730 
731 		//#59900# Die Sortierung soll die Nummer korrekt einordnen
732 		//also "10" nach "9" und nicht "10" nach "1"
733 		const String& rTmp2 = rNew.sDlgEntry;
734 		xub_StrLen nFndPos2 = 0;
735 		String sNum2( rTmp2.GetToken( 0, ' ', nFndPos2 ));
736 		sal_Bool bIsNum2IsNumeric = rCC.isAsciiNumeric( sNum2 );
737 		sal_Int32 nNum2 = bIsNum2IsNumeric ? sNum2.ToInt32() : 0;
738 
739 		nO--;
740 		while( nU <= nO )
741 		{
742 			nM = nU + ( nO - nU ) / 2;
743 
744 			//#59900# Die Sortierung soll die Nummer korrekt einordnen
745 			//also "10" nach "9" und nicht "10" nach "1"
746 			const String& rTmp1 = (*((_SeqFldLstElem**)pData + nM))->sDlgEntry;
747 			xub_StrLen nFndPos1 = 0;
748 			String sNum1( rTmp1.GetToken( 0, ' ', nFndPos1 ));
749 			sal_Int32 nCmp;
750 
751 			if( bIsNum2IsNumeric && rCC.isNumeric( sNum1 ) )
752 			{
753 				sal_Int32 nNum1 = sNum1.ToInt32();
754 				nCmp = nNum2 - nNum1;
755 				if( 0 == nCmp )
756 					nCmp = rCaseColl.compareString( rTmp2.Copy( nFndPos2 ),
757 										 			  rTmp1.Copy( nFndPos1 ));
758 			}
759 			else
760 				nCmp = rColl.compareString( rTmp2, rTmp1 );
761 
762 			if( 0 == nCmp )
763 			{
764 				if( pP ) *pP = nM;
765 				return sal_True;
766 			}
767 			else if( 0 < nCmp )
768 				nU = nM + 1;
769 			else if( nM == 0 )
770 				break;
771 			else
772 				nO = nM - 1;
773 		}
774 	}
775 	if( pP ) *pP = nU;
776 	return sal_False;
777 }
778 
779 /*--------------------------------------------------------------------
780 	Beschreibung: SwSetExpField by JP
781  --------------------------------------------------------------------*/
782 
SwSetExpField(SwSetExpFieldType * pTyp,const String & rFormel,sal_uLong nFmt)783 SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const String& rFormel,
784 										sal_uLong nFmt)
785 	: SwFormulaField( pTyp, nFmt, 0.0 ), nSeqNo( USHRT_MAX ),
786 	nSubType(0)
787 {
788 	SetFormula(rFormel);
789 	// SubType ignorieren !!!
790 	bInput = sal_False;
791 	if( IsSequenceFld() )
792 	{
793 		SwValueField::SetValue(1.0);
794 		if( !rFormel.Len() )
795 		{
796 			String sFormel(rFormel);
797 			sFormel += pTyp->GetName();
798 			sFormel += '+';
799 			sFormel += '1';
800 			SetFormula(sFormel);
801 		}
802 	}
803 }
804 
Expand() const805 String SwSetExpField::Expand() const
806 {
807 	String aStr;
808 	if (nSubType & nsSwExtendedSubType::SUB_CMD)
809 	{	// Der CommandString ist gefragt
810 		aStr = GetTyp()->GetName();
811 		aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ));
812 		aStr += GetFormula();
813 	}
814 	else if(!(nSubType & nsSwExtendedSubType::SUB_INVISIBLE))
815 	{   // Der Wert ist sichtbar
816 		aStr = sExpand;
817 	}
818 	return aStr;
819 }
820 
821 /*--------------------------------------------------------------------
822 	@return the field name
823  --------------------------------------------------------------------*/
824 
GetFieldName() const825 String SwSetExpField::GetFieldName() const
826 {
827     SwFldTypesEnum const nStrType( (IsSequenceFld())
828                             ? TYP_SEQFLD
829                             : (bInput)
830                                 ? TYP_SETINPFLD
831                                 : TYP_SETFLD   );
832 
833     String aStr( SwFieldType::GetTypeStr( static_cast<sal_uInt16>(nStrType) ) );
834     aStr += ' ';
835     aStr += GetTyp()->GetName();
836 
837     // Sequence: without formula
838     if (TYP_SEQFLD != nStrType)
839     {
840         aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) );
841         aStr += GetFormula();
842     }
843     return aStr;
844 }
845 
Copy() const846 SwField* SwSetExpField::Copy() const
847 {
848 	SwSetExpField *pTmp = new SwSetExpField((SwSetExpFieldType*)GetTyp(),
849 											GetFormula(), GetFormat());
850 	pTmp->SwValueField::SetValue(GetValue());
851 	pTmp->sExpand   	= sExpand;
852 	pTmp->SetAutomaticLanguage(IsAutomaticLanguage());
853 	pTmp->SetLanguage(GetLanguage());
854 	pTmp->aPText		= aPText;
855 	pTmp->bInput		= bInput;
856 	pTmp->nSeqNo		= nSeqNo;
857 	pTmp->SetSubType(GetSubType());
858 
859 	return pTmp;
860 }
861 
SetSubType(sal_uInt16 nSub)862 void SwSetExpField::SetSubType(sal_uInt16 nSub)
863 {
864 	((SwSetExpFieldType*)GetTyp())->SetType(nSub & 0xff);
865 	nSubType = nSub & 0xff00;
866 
867 	DBG_ASSERT( (nSub & 0xff) != 3, "SubType ist illegal!" );
868 }
869 
GetSubType() const870 sal_uInt16 SwSetExpField::GetSubType() const
871 {
872 	return ((SwSetExpFieldType*)GetTyp())->GetType() | nSubType;
873 }
874 
SetValue(const double & rAny)875 void SwSetExpField::SetValue( const double& rAny )
876 {
877 	SwValueField::SetValue(rAny);
878 
879 	if( IsSequenceFld() )
880 		sExpand = FormatNumber( (sal_uInt16)GetValue(), GetFormat() );
881 	else
882 		sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny,
883 												GetFormat(), GetLanguage());
884 }
885 
SetValue(const double & rAny)886 void SwGetExpField::SetValue( const double& rAny )
887 {
888 	SwValueField::SetValue(rAny);
889 	sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny, GetFormat(),
890 															GetLanguage());
891 }
892 /* -------------------------------------------------
893 	Description: Find the index of the reference text
894 	following the current field
895  --------------------------------------------------*/
GetReferenceTextPos(const SwFmtFld & rFmt,SwDoc & rDoc)896 xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc)
897 {
898 	//
899 	const SwTxtFld* pTxtFld = rFmt.GetTxtFld();
900 	const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
901 	//
902 	xub_StrLen nRet = *pTxtFld->GetStart() + 1;
903 	String sNodeText = rTxtNode.GetTxt();
904 	sNodeText.Erase(0, nRet);
905 	if(sNodeText.Len())
906 	{
907 		// now check if sNodeText starts with a non-alphanumeric character plus a blank
908 		sal_uInt16 nSrcpt = pBreakIt->GetRealScriptOfText( sNodeText, 0 );
909 
910 		static sal_uInt16 nIds[] =
911 		{
912 			RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
913 			RES_CHRATR_FONT, RES_CHRATR_FONT,
914 			RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
915 			RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
916 			RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
917 			RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT,
918 			0, 0
919 		};
920 		SwAttrSet aSet(rDoc.GetAttrPool(), nIds);
921 		rTxtNode.GetAttr(aSet, nRet, nRet+1);
922 
923 		if( RTL_TEXTENCODING_SYMBOL != ((SvxFontItem&)aSet.Get(
924 				GetWhichOfScript( RES_CHRATR_FONT, nSrcpt )) ).GetCharSet() )
925 		{
926 			LanguageType eLang = ((SvxLanguageItem&)aSet.Get(
927 				GetWhichOfScript( RES_CHRATR_LANGUAGE, nSrcpt )) ).GetLanguage();
928 			CharClass aCC( SvxCreateLocale( eLang ));
929 			sal_Unicode c0 = sNodeText.GetChar(0);
930 			sal_Bool bIsAlphaNum = aCC.isAlphaNumeric( sNodeText, 0 );
931 			if( !bIsAlphaNum ||
932 				(c0 == ' ' || c0 == '\t'))
933 			{
934 				nRet++;
935 				if( sNodeText.Len() > 1 &&
936 					(sNodeText.GetChar(1) == ' ' ||
937 					 sNodeText.GetChar(1) == '\t'))
938 					nRet++;
939 			}
940 		}
941 	}
942 	return nRet;
943 }
944 
945 
946 /*--------------------------------------------------------------------
947 	Beschreibung: Parameter setzen
948  --------------------------------------------------------------------*/
949 
GetPar1() const950 const String& SwSetExpField::GetPar1() const
951 {
952 	return ((SwSetExpFieldType*)GetTyp())->GetName();
953 }
954 
GetPar2() const955 String SwSetExpField::GetPar2() const
956 {
957 	sal_uInt16 nType = ((SwSetExpFieldType*)GetTyp())->GetType();
958 
959 	if (nType & nsSwGetSetExpType::GSE_STRING)
960 		return GetFormula();
961 	return GetExpandedFormula();
962 }
963 
SetPar2(const String & rStr)964 void SwSetExpField::SetPar2(const String& rStr)
965 {
966 	sal_uInt16 nType = ((SwSetExpFieldType*)GetTyp())->GetType();
967 
968 	if( !(nType & nsSwGetSetExpType::GSE_SEQ) || rStr.Len() )
969 	{
970 		if (nType & nsSwGetSetExpType::GSE_STRING)
971 			SetFormula(rStr);
972 		else
973 			SetExpandedFormula(rStr);
974 	}
975 }
976 
977 
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)978 sal_Bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
979 {
980 	sal_Int32 nTmp32 = 0;
981 	sal_Int16 nTmp16 = 0;
982 	String sTmp;
983 	switch( nWhichId )
984 	{
985 	case FIELD_PROP_BOOL2:
986 		if(*(sal_Bool*)rAny.getValue())
987 			nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
988 		else
989 			nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
990 		break;
991 	case FIELD_PROP_FORMAT:
992 		rAny >>= nTmp32;
993 		SetFormat(nTmp32);
994 		break;
995 	case FIELD_PROP_USHORT2:
996 		{
997 			rAny >>= nTmp16;
998 			if(nTmp16 <= SVX_NUMBER_NONE )
999 				SetFormat(nTmp16);
1000 			else {
1001 				//exception(wrong_value)
1002 				;
1003             }
1004 		}
1005 		break;
1006 	case FIELD_PROP_USHORT1:
1007 		rAny >>= nTmp16;
1008 		nSeqNo = nTmp16;
1009 		break;
1010 	case FIELD_PROP_PAR1:
1011 		SetPar1( SwStyleNameMapper::GetUIName(
1012 							::GetString( rAny, sTmp ), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ) );
1013 		break;
1014 	case FIELD_PROP_PAR2:
1015 		{
1016 			OUString uTmp;
1017 			rAny >>= uTmp;
1018 			//I18N - if the formula contains only "TypeName+1"
1019 			//and it's one of the initially created sequence fields
1020 			//then the localized names has to be replaced by a programmatic name
1021 			OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, uTmp, sal_False);
1022 			SetFormula( sMyFormula );
1023 		}
1024 		break;
1025 	case FIELD_PROP_DOUBLE:
1026 		{
1027 			double fVal = 0.0;
1028 			rAny >>= fVal;
1029 			SetValue(fVal);
1030 		}
1031 		break;
1032 	case FIELD_PROP_SUBTYPE:
1033 		nTmp32 = lcl_APIToSubType(rAny);
1034 		if(nTmp32 >= 0)
1035 			SetSubType(static_cast<sal_uInt16>((GetSubType() & 0xff00) | nTmp32));
1036 		break;
1037 	case FIELD_PROP_PAR3:
1038 		::GetString( rAny, aPText );
1039 		break;
1040 	case FIELD_PROP_BOOL3:
1041 		if(*(sal_Bool*) rAny.getValue())
1042 			nSubType |= nsSwExtendedSubType::SUB_CMD;
1043 		else
1044 			nSubType &= (~nsSwExtendedSubType::SUB_CMD);
1045 		break;
1046 	case FIELD_PROP_BOOL1:
1047 		SetInputFlag(*(sal_Bool*) rAny.getValue());
1048 		break;
1049 	case FIELD_PROP_PAR4:
1050 		ChgExpStr( ::GetString( rAny, sTmp ));
1051 		break;
1052 	default:
1053         return SwField::PutValue(rAny, nWhichId);
1054     }
1055 	return sal_True;
1056 }
1057 
1058 
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1059 sal_Bool SwSetExpField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1060 {
1061     switch( nWhichId )
1062 	{
1063 	case FIELD_PROP_BOOL2:
1064 		{
1065 			sal_Bool bVal = 0 == (nSubType & nsSwExtendedSubType::SUB_INVISIBLE);
1066 			rAny.setValue(&bVal, ::getBooleanCppuType());
1067 		}
1068 		break;
1069 	case FIELD_PROP_FORMAT:
1070 		rAny <<= (sal_Int32)GetFormat();
1071 		break;
1072 	case FIELD_PROP_USHORT2:
1073 		rAny <<= (sal_Int16)GetFormat();
1074 		break;
1075 	case FIELD_PROP_USHORT1:
1076 		rAny <<= (sal_Int16)nSeqNo;
1077 		break;
1078 	case FIELD_PROP_PAR1:
1079 		rAny <<= OUString ( SwStyleNameMapper::GetProgName(GetPar1(), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ) );
1080 		break;
1081 	case FIELD_PROP_PAR2:
1082 		{
1083 			//I18N - if the formula contains only "TypeName+1"
1084 			//and it's one of the initially created sequence fields
1085 			//then the localized names has to be replaced by a programmatic name
1086 			OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, GetFormula(), sal_True);
1087 			rAny <<= OUString( sMyFormula );
1088 		}
1089 		break;
1090 	case FIELD_PROP_DOUBLE:
1091 		rAny <<= (double)GetValue();
1092 		break;
1093 	case FIELD_PROP_SUBTYPE:
1094 		{
1095 			sal_Int16 nRet = 0;
1096 				nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
1097 			rAny <<= nRet;
1098 		}
1099 		break;
1100 	case FIELD_PROP_PAR3:
1101 		rAny <<= OUString( aPText );
1102 		break;
1103 	case FIELD_PROP_BOOL3:
1104 		{
1105 			sal_Bool bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD);
1106 			rAny.setValue(&bTmp, ::getBooleanCppuType());
1107 		}
1108 		break;
1109 	case FIELD_PROP_BOOL1:
1110 		{
1111 			sal_Bool bTmp = GetInputFlag();
1112 			rAny.setValue(&bTmp, ::getBooleanCppuType());
1113 		}
1114 		break;
1115 	case FIELD_PROP_PAR4:
1116 		rAny <<= rtl::OUString(GetExpStr());
1117 		break;
1118 	default:
1119         return SwField::QueryValue(rAny, nWhichId);
1120     }
1121 	return sal_True;
1122 }
1123 
1124 
1125 
1126 /*--------------------------------------------------------------------
1127 	Beschreibung: Eingabefeld Type
1128  ---------------------------------------------------------------------*/
1129 
SwInputFieldType(SwDoc * pD)1130 SwInputFieldType::SwInputFieldType( SwDoc* pD )
1131     : SwFieldType( RES_INPUTFLD )
1132     , pDoc( pD )
1133 {
1134 }
1135 
Copy() const1136 SwFieldType* SwInputFieldType::Copy() const
1137 {
1138     SwInputFieldType* pType = new SwInputFieldType( pDoc );
1139     return pType;
1140 }
1141 
1142 /*--------------------------------------------------------------------
1143 	Beschreibung: Eingabefeld
1144  --------------------------------------------------------------------*/
1145 
SwInputField(SwInputFieldType * pFieldType,const String & rContent,const String & rPrompt,sal_uInt16 nSub,sal_uLong nFmt,bool bIsFormField)1146 SwInputField::SwInputField( SwInputFieldType* pFieldType,
1147                             const String& rContent,
1148                             const String& rPrompt,
1149                             sal_uInt16 nSub,
1150                             sal_uLong nFmt,
1151                             bool bIsFormField )
1152     : SwField( pFieldType, nFmt, LANGUAGE_SYSTEM, false )
1153     , aContent(rContent)
1154     , aPText(rPrompt)
1155     , nSubType(nSub)
1156     , mbIsFormField( bIsFormField )
1157     , mpFmtFld( NULL )
1158 {
1159 }
1160 
~SwInputField()1161 SwInputField::~SwInputField()
1162 {
1163 }
1164 
1165 
SetFmtFld(SwFmtFld & rFmtFld)1166 void SwInputField::SetFmtFld( SwFmtFld& rFmtFld )
1167 {
1168     mpFmtFld = &rFmtFld;
1169 }
1170 
GetFmtFld()1171 SwFmtFld* SwInputField::GetFmtFld()
1172 {
1173     return mpFmtFld;
1174 }
1175 
1176 
getContent() const1177 const String& SwInputField::getContent() const
1178 {
1179     return aContent;
1180 }
1181 
1182 
LockNotifyContentChange()1183 void SwInputField::LockNotifyContentChange()
1184 {
1185     if ( GetFmtFld() != NULL )
1186     {
1187         SwTxtInputFld* pTxtInputFld = dynamic_cast< SwTxtInputFld* >(GetFmtFld()->GetTxtFld());
1188         if ( pTxtInputFld != NULL )
1189         {
1190             pTxtInputFld->LockNotifyContentChange();
1191         }
1192     }
1193 }
1194 
1195 
UnlockNotifyContentChange()1196 void SwInputField::UnlockNotifyContentChange()
1197 {
1198     if ( GetFmtFld() != NULL )
1199     {
1200         SwTxtInputFld* pTxtInputFld = dynamic_cast< SwTxtInputFld* >(GetFmtFld()->GetTxtFld());
1201         if ( pTxtInputFld != NULL )
1202         {
1203             pTxtInputFld->UnlockNotifyContentChange();
1204         }
1205     }
1206 }
1207 
applyFieldContent(const String & rNewFieldContent)1208 void SwInputField::applyFieldContent( const String& rNewFieldContent )
1209 {
1210     if ( (nSubType & 0x00ff) == INP_TXT )
1211     {
1212         aContent = rNewFieldContent;
1213     }
1214     else if( (nSubType & 0x00ff) == INP_USR )
1215     {
1216         SwUserFieldType* pUserTyp = static_cast<SwUserFieldType*>(
1217             static_cast<SwInputFieldType*>(GetTyp())->GetDoc()->GetFldType( RES_USERFLD, getContent(), false ) );
1218         if( pUserTyp )
1219         {
1220             pUserTyp->SetContent( rNewFieldContent );
1221 
1222             // trigger update of the corresponding User Fields and other related Input Fields
1223             {
1224                 LockNotifyContentChange();
1225                 pUserTyp->UpdateFlds();
1226                 UnlockNotifyContentChange();
1227             }
1228         }
1229     }
1230 }
1231 
GetFieldName() const1232 String SwInputField::GetFieldName() const
1233 {
1234     String aStr(SwField::GetFieldName());
1235     if ((nSubType & 0x00ff) == INP_USR)
1236     {
1237         aStr += GetTyp()->GetName();
1238         aStr += ' ';
1239         aStr += getContent();
1240     }
1241     return aStr;
1242 }
1243 
Copy() const1244 SwField* SwInputField::Copy() const
1245 {
1246     SwInputField* pFld =
1247         new SwInputField(
1248             static_cast<SwInputFieldType*>(GetTyp()),
1249             getContent(),
1250             aPText,
1251             GetSubType(),
1252             GetFormat(),
1253             mbIsFormField );
1254 
1255     pFld->SetHelp( aHelp );
1256     pFld->SetToolTip( aToolTip );
1257 
1258     pFld->SetAutomaticLanguage(IsAutomaticLanguage());
1259     return pFld;
1260 }
1261 
Expand() const1262 String SwInputField::Expand() const
1263 {
1264     String sRet;
1265     if ( (nSubType & 0x00ff) == INP_TXT )
1266     {
1267         sRet = getContent();
1268     }
1269     else if( (nSubType & 0x00ff) == INP_USR )
1270     {
1271         SwUserFieldType* pUserTyp = static_cast<SwUserFieldType*>(
1272             static_cast<SwInputFieldType*>(GetTyp())->GetDoc()->GetFldType( RES_USERFLD, getContent(), false ) );
1273         if( pUserTyp )
1274             sRet = pUserTyp->GetContent();
1275     }
1276     return sRet;
1277 }
1278 
1279 
isFormField() const1280 bool SwInputField::isFormField() const
1281 {
1282     return mbIsFormField
1283            || aHelp.Len() > 0
1284            || aToolTip.Len() > 0;
1285 }
1286 
1287 
QueryValue(uno::Any & rAny,sal_uInt16 nWhichId) const1288 sal_Bool SwInputField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
1289 {
1290     switch( nWhichId )
1291     {
1292     case FIELD_PROP_PAR1:
1293         rAny <<= OUString( getContent() );
1294         break;
1295     case FIELD_PROP_PAR2:
1296         rAny <<= OUString( aPText );
1297         break;
1298     case FIELD_PROP_PAR3:
1299         rAny <<= OUString( aHelp );
1300         break;
1301     case FIELD_PROP_PAR4:
1302         rAny <<= OUString( aToolTip );
1303         break;
1304     default:
1305         DBG_ERROR("illegal property");
1306     }
1307     return sal_True;
1308 }
1309 
PutValue(const uno::Any & rAny,sal_uInt16 nWhichId)1310 sal_Bool SwInputField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
1311 {
1312     switch( nWhichId )
1313     {
1314     case FIELD_PROP_PAR1:
1315         {
1316             ::GetString( rAny, aContent );
1317         }
1318         break;
1319     case FIELD_PROP_PAR2:
1320         ::GetString( rAny, aPText );
1321         break;
1322     case FIELD_PROP_PAR3:
1323         ::GetString( rAny, aHelp );
1324         break;
1325     case FIELD_PROP_PAR4:
1326         ::GetString( rAny, aToolTip );
1327         break;
1328     default:
1329         DBG_ERROR("illegal property");
1330     }
1331     return sal_True;
1332 }
1333 
1334 
SetPar1(const String & rStr)1335 void SwInputField::SetPar1(const String& rStr)
1336 {
1337 	aContent = rStr;
1338 }
1339 
GetPar1() const1340 const String& SwInputField::GetPar1() const
1341 {
1342 	return getContent();
1343 }
1344 
1345 
SetPar2(const String & rStr)1346 void SwInputField::SetPar2(const String& rStr)
1347 {
1348 	aPText = rStr;
1349 }
1350 
GetPar2() const1351 String SwInputField::GetPar2() const
1352 {
1353 	return aPText;
1354 }
1355 
SetHelp(const String & rStr)1356 void SwInputField::SetHelp(const String & rStr)
1357 {
1358 	aHelp = rStr;
1359 }
1360 
GetHelp() const1361 String SwInputField::GetHelp() const
1362 {
1363 	return aHelp;
1364 }
1365 
SetToolTip(const String & rStr)1366 void SwInputField::SetToolTip(const String & rStr)
1367 {
1368 	aToolTip = rStr;
1369 }
1370 
GetToolTip() const1371 String SwInputField::GetToolTip() const
1372 {
1373 	return aToolTip;
1374 }
1375 
GetSubType() const1376 sal_uInt16 SwInputField::GetSubType() const
1377 {
1378 	return nSubType;
1379 }
1380 
SetSubType(sal_uInt16 nSub)1381 void SwInputField::SetSubType(sal_uInt16 nSub)
1382 {
1383 	nSubType = nSub;
1384 }
1385 
1386 /* vim: set noet sw=4 ts=4: */
1387