Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with &m_rSwdoc work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #include <DocumentFieldsManager.hxx>
20 : #include <config_features.h>
21 : #include <doc.hxx>
22 : #include <IDocumentUndoRedo.hxx>
23 : #include <IDocumentState.hxx>
24 : #include <IDocumentLayoutAccess.hxx>
25 : #include <dbmgr.hxx>
26 : #include <chpfld.hxx>
27 : #include <dbfld.hxx>
28 : #include <reffld.hxx>
29 : #include <flddropdown.hxx>
30 : #include <poolfmt.hrc>
31 : #include <SwUndoField.hxx>
32 : #include <flddat.hxx>
33 : #include <cntfrm.hxx>
34 : #include <section.hxx>
35 : #include <docufld.hxx>
36 : #include <switerator.hxx>
37 : #include <cellatr.hxx>
38 : #include <swtable.hxx>
39 : #include <frmfmt.hxx>
40 : #include <fmtfld.hxx>
41 : #include <ndtxt.hxx>
42 : #include <txtfld.hxx>
43 : #include <docfld.hxx>
44 : #include <hints.hxx>
45 : #include <docary.hxx>
46 : #include <fldbas.hxx>
47 : #include <expfld.hxx>
48 : #include <ddefld.hxx>
49 : #include <authfld.hxx>
50 : #include <usrfld.hxx>
51 : #include <unotools/transliterationwrapper.hxx>
52 : #include <com/sun/star/uno/Any.hxx>
53 :
54 : using namespace ::com::sun::star::uno;
55 :
56 : namespace
57 : {
58 : #if HAVE_FEATURE_DBCONNECTIVITY
59 :
60 0 : static OUString lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBFld )
61 : {
62 0 : SwDBData aDBData( rDBFld.GetDBData( &rDoc ));
63 0 : OUString sDBNumNm;
64 0 : SwDBData aDocData = rDoc.GetDBData();
65 :
66 0 : if( aDBData != aDocData )
67 : {
68 0 : sDBNumNm = aDBData.sDataSource;
69 0 : sDBNumNm += OUString(DB_DELIM);
70 0 : sDBNumNm += aDBData.sCommand;
71 0 : sDBNumNm += OUString(DB_DELIM);
72 : }
73 0 : sDBNumNm += SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD);
74 :
75 0 : return sDBNumNm;
76 : }
77 :
78 : #endif
79 :
80 12 : static void lcl_CalcFld( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpFld& rSGEFld,
81 : SwDBManager* pMgr )
82 : {
83 12 : const SwTxtFld* pTxtFld = rSGEFld.GetTxtFld();
84 12 : if( !pTxtFld )
85 22 : return ;
86 :
87 2 : const SwField* pFld = pTxtFld->GetFmtFld().GetField();
88 2 : const sal_uInt16 nFldWhich = pFld->GetTyp()->Which();
89 :
90 2 : if( RES_SETEXPFLD == nFldWhich )
91 : {
92 2 : SwSbxValue aValue;
93 2 : if( nsSwGetSetExpType::GSE_EXPR & pFld->GetSubType() )
94 2 : aValue.PutDouble( ((SwSetExpField*)pFld)->GetValue() );
95 : else
96 : // Extension to calculate with Strings
97 0 : aValue.PutString( ((SwSetExpField*)pFld)->GetExpStr() );
98 :
99 : // set the new value in Calculator
100 2 : rCalc.VarChange( pFld->GetTyp()->GetName(), aValue );
101 : }
102 0 : else if( pMgr )
103 : {
104 : #if !HAVE_FEATURE_DBCONNECTIVITY
105 : (void) rDoc;
106 : #else
107 0 : switch( nFldWhich )
108 : {
109 : case RES_DBNUMSETFLD:
110 : {
111 0 : SwDBNumSetField* pDBFld = (SwDBNumSetField*)pFld;
112 :
113 0 : SwDBData aDBData(pDBFld->GetDBData(&rDoc));
114 :
115 0 : if( pDBFld->IsCondValid() &&
116 0 : pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
117 : rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBFld),
118 0 : pDBFld->GetFormat() );
119 : }
120 0 : break;
121 : case RES_DBNEXTSETFLD:
122 : {
123 0 : SwDBNextSetField* pDBFld = (SwDBNextSetField*)pFld;
124 0 : SwDBData aDBData(pDBFld->GetDBData(&rDoc));
125 0 : if( !pDBFld->IsCondValid() ||
126 0 : !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
127 0 : break;
128 :
129 0 : OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBFld));
130 0 : SwCalcExp* pExp = rCalc.VarLook( sDBNumNm );
131 0 : if( pExp )
132 0 : rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 );
133 : }
134 0 : break;
135 :
136 : }
137 : #endif
138 : }
139 : }
140 : }
141 :
142 : namespace sw
143 : {
144 :
145 5052 : DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rSwdoc( i_rSwdoc ),
146 : mbNewFldLst(true),
147 5052 : mpUpdtFlds( new SwDocUpdtFld( &m_rSwdoc ) ),
148 : mpFldTypes( new SwFldTypes() ),
149 10104 : mnLockExpFld( 0 )
150 : {
151 5052 : }
152 :
153 37452 : const SwFldTypes* DocumentFieldsManager::GetFldTypes() const
154 : {
155 37452 : return mpFldTypes;
156 : }
157 :
158 : /** Insert field types
159 : *
160 : * @param rFldTyp ???
161 : * @return Always returns a pointer to the type, if it's new or already added.
162 : */
163 280 : SwFieldType* DocumentFieldsManager::InsertFldType(const SwFieldType &rFldTyp)
164 : {
165 280 : sal_uInt16 nSize = mpFldTypes->size(),
166 280 : nFldWhich = rFldTyp.Which();
167 :
168 280 : sal_uInt16 i = INIT_FLDTYPES;
169 :
170 280 : switch( nFldWhich )
171 : {
172 : case RES_SETEXPFLD:
173 : //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
174 : // Or we get doubble number circles!!
175 : //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
176 : //constructing string pools and when reading SetExp fields
177 126 : if( nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() )
178 88 : i -= INIT_SEQ_FLDTYPES;
179 : // no break;
180 : case RES_DBFLD:
181 : case RES_USERFLD:
182 : case RES_DDEFLD:
183 : {
184 234 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
185 234 : OUString sFldNm( rFldTyp.GetName() );
186 858 : for( ; i < nSize; ++i )
187 2840 : if( nFldWhich == (*mpFldTypes)[i]->Which() &&
188 2776 : rSCmp.isEqual( sFldNm, (*mpFldTypes)[i]->GetName() ))
189 234 : return (*mpFldTypes)[i];
190 : }
191 140 : break;
192 :
193 : case RES_AUTHORITY:
194 46 : for( ; i < nSize; ++i )
195 6 : if( nFldWhich == (*mpFldTypes)[i]->Which() )
196 6 : return (*mpFldTypes)[i];
197 40 : break;
198 :
199 : default:
200 0 : for( i = 0; i < nSize; ++i )
201 0 : if( nFldWhich == (*mpFldTypes)[i]->Which() )
202 0 : return (*mpFldTypes)[i];
203 : }
204 :
205 180 : SwFieldType* pNew = rFldTyp.Copy();
206 180 : switch( nFldWhich )
207 : {
208 : case RES_DDEFLD:
209 0 : ((SwDDEFieldType*)pNew)->SetDoc( &m_rSwdoc );
210 0 : break;
211 :
212 : case RES_DBFLD:
213 : case RES_TABLEFLD:
214 : case RES_DATETIMEFLD:
215 : case RES_GETEXPFLD:
216 52 : ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
217 52 : break;
218 :
219 : case RES_USERFLD:
220 : case RES_SETEXPFLD:
221 88 : ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
222 : // JP 29.07.96: Optionally prepare FieldList for Calculator:
223 88 : mpUpdtFlds->InsertFldType( *pNew );
224 88 : break;
225 : case RES_AUTHORITY :
226 40 : ((SwAuthorityFieldType*)pNew)->SetDoc( &m_rSwdoc );
227 40 : break;
228 : }
229 :
230 180 : mpFldTypes->insert( mpFldTypes->begin() + nSize, pNew );
231 180 : m_rSwdoc.getIDocumentState().SetModified();
232 :
233 180 : return (*mpFldTypes)[ nSize ];
234 : }
235 :
236 : /// @returns the field type of the Doc
237 42514 : SwFieldType *DocumentFieldsManager::GetSysFldType( const sal_uInt16 eWhich ) const
238 : {
239 368007 : for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
240 368007 : if( eWhich == (*mpFldTypes)[i]->Which() )
241 42514 : return (*mpFldTypes)[i];
242 0 : return 0;
243 : }
244 :
245 : /// Find first type with ResId and name
246 8418 : SwFieldType* DocumentFieldsManager::GetFldType(
247 : sal_uInt16 nResId,
248 : const OUString& rName,
249 : bool bDbFieldMatching // used in some UNO calls for RES_DBFLD to use different string matching code #i51815#
250 : ) const
251 : {
252 8418 : sal_uInt16 nSize = mpFldTypes->size(), i = 0;
253 8418 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
254 :
255 8418 : switch( nResId )
256 : {
257 : case RES_SETEXPFLD:
258 : //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
259 : // Or we get doubble number circles!!
260 : //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
261 : //constructing string pools and when reading SetExp fields
262 3346 : i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES;
263 3346 : break;
264 :
265 : case RES_DBFLD:
266 : case RES_USERFLD:
267 : case RES_DDEFLD:
268 : case RES_AUTHORITY:
269 276 : i = INIT_FLDTYPES;
270 276 : break;
271 : }
272 :
273 8418 : SwFieldType* pRet = 0;
274 58256 : for( ; i < nSize; ++i )
275 : {
276 57904 : SwFieldType* pFldType = (*mpFldTypes)[i];
277 :
278 57904 : OUString aFldName( pFldType->GetName() );
279 57904 : if (bDbFieldMatching && nResId == RES_DBFLD) // #i51815#
280 4 : aFldName = aFldName.replace(DB_DELIM, '.');
281 :
282 72258 : if( nResId == pFldType->Which() &&
283 14354 : rSCmp.isEqual( rName, aFldName ))
284 : {
285 8066 : pRet = pFldType;
286 8066 : break;
287 : }
288 49838 : }
289 8418 : return pRet;
290 : }
291 :
292 : /// Remove field type
293 50 : void DocumentFieldsManager::RemoveFldType(sal_uInt16 nFld)
294 : {
295 : OSL_ENSURE( INIT_FLDTYPES <= nFld, "don't remove InitFlds" );
296 : /*
297 : * Dependent fields present -> ErrRaise
298 : */
299 50 : sal_uInt16 nSize = mpFldTypes->size();
300 50 : if(nFld < nSize)
301 : {
302 50 : SwFieldType* pTmp = (*mpFldTypes)[nFld];
303 :
304 : // JP 29.07.96: Optionally prepare FldLst for Calculator
305 50 : sal_uInt16 nWhich = pTmp->Which();
306 50 : switch( nWhich )
307 : {
308 : case RES_SETEXPFLD:
309 : case RES_USERFLD:
310 0 : mpUpdtFlds->RemoveFldType( *pTmp );
311 : // no break;
312 : case RES_DDEFLD:
313 0 : if( pTmp->GetDepends() && !m_rSwdoc.IsUsed( *pTmp ) )
314 : {
315 0 : if( RES_SETEXPFLD == nWhich )
316 0 : ((SwSetExpFieldType*)pTmp)->SetDeleted( true );
317 0 : else if( RES_USERFLD == nWhich )
318 0 : ((SwUserFieldType*)pTmp)->SetDeleted( true );
319 : else
320 0 : ((SwDDEFieldType*)pTmp)->SetDeleted( true );
321 0 : nWhich = 0;
322 : }
323 0 : break;
324 : }
325 :
326 50 : if( nWhich )
327 : {
328 : OSL_ENSURE( !pTmp->GetDepends(), "Dependent fields present!" );
329 : // delete field type
330 0 : delete pTmp;
331 : }
332 50 : mpFldTypes->erase( mpFldTypes->begin() + nFld );
333 50 : m_rSwdoc.getIDocumentState().SetModified();
334 : }
335 50 : }
336 :
337 : // All have to be re-evaluated.
338 154 : void DocumentFieldsManager::UpdateFlds( SfxPoolItem *pNewHt, bool bCloseDB )
339 : {
340 : // Call Modify() for every field type,
341 : // dependent SwTxtFld get notified ...
342 :
343 5134 : for( sal_uInt16 i=0; i < mpFldTypes->size(); ++i)
344 : {
345 4980 : switch( (*mpFldTypes)[i]->Which() )
346 : {
347 : // Update table fields second to last
348 : // Update references last
349 : case RES_GETREFFLD:
350 : case RES_TABLEFLD:
351 : case RES_DBFLD:
352 : case RES_JUMPEDITFLD:
353 : case RES_REFPAGESETFLD: // are never expanded!
354 658 : break;
355 :
356 : case RES_DDEFLD:
357 : {
358 0 : if( !pNewHt )
359 : {
360 0 : SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
361 0 : (*mpFldTypes)[i]->ModifyNotification( 0, &aUpdateDDE );
362 : }
363 : else
364 0 : (*mpFldTypes)[i]->ModifyNotification( 0, pNewHt );
365 0 : break;
366 : }
367 : case RES_GETEXPFLD:
368 : case RES_SETEXPFLD:
369 : case RES_HIDDENTXTFLD:
370 : case RES_HIDDENPARAFLD:
371 : // Expression fields are treated separately
372 1084 : if( !pNewHt )
373 1084 : break;
374 : default:
375 3238 : (*mpFldTypes)[i]->ModifyNotification ( 0, pNewHt );
376 : }
377 : }
378 :
379 154 : if( !IsExpFldsLocked() )
380 154 : UpdateExpFlds( 0, false ); // update expression fields
381 :
382 : // Tables
383 154 : UpdateTblFlds(pNewHt);
384 :
385 : // References
386 154 : UpdateRefFlds(pNewHt);
387 154 : if( bCloseDB )
388 : {
389 : #if HAVE_FEATURE_DBCONNECTIVITY
390 0 : m_rSwdoc.GetDBManager()->CloseAll();
391 : #endif
392 : }
393 : // Only evaluate on full update
394 154 : m_rSwdoc.getIDocumentState().SetModified();
395 154 : }
396 :
397 0 : void DocumentFieldsManager::InsDeletedFldType( SwFieldType& rFldTyp )
398 : {
399 : // The FldType was marked as deleted and removed from the array.
400 : // One has to look &m_rSwdoc up again, now.
401 : // - If it's not present, it can be re-inserted.
402 : // - If the same type is found, the deleted one has to be renamed.
403 :
404 0 : sal_uInt16 nSize = mpFldTypes->size(), nFldWhich = rFldTyp.Which();
405 0 : sal_uInt16 i = INIT_FLDTYPES;
406 :
407 : OSL_ENSURE( RES_SETEXPFLD == nFldWhich ||
408 : RES_USERFLD == nFldWhich ||
409 : RES_DDEFLD == nFldWhich, "Wrong FldType" );
410 :
411 0 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
412 0 : const OUString& rFldNm = rFldTyp.GetName();
413 : SwFieldType* pFnd;
414 :
415 0 : for( ; i < nSize; ++i )
416 0 : if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
417 0 : rSCmp.isEqual( rFldNm, pFnd->GetName() ) )
418 : {
419 : // find new name
420 0 : sal_uInt16 nNum = 1;
421 : do {
422 0 : OUString sSrch = rFldNm + OUString::number( nNum );
423 0 : for( i = INIT_FLDTYPES; i < nSize; ++i )
424 0 : if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
425 0 : rSCmp.isEqual( sSrch, pFnd->GetName() ) )
426 0 : break;
427 :
428 0 : if( i >= nSize ) // not found
429 : {
430 0 : ((OUString&)rFldNm) = sSrch;
431 0 : break; // exit while loop
432 : }
433 0 : ++nNum;
434 : } while( true );
435 0 : break;
436 : }
437 :
438 : // not found, so insert and delete flag
439 0 : mpFldTypes->insert( mpFldTypes->begin() + nSize, &rFldTyp );
440 0 : switch( nFldWhich )
441 : {
442 : case RES_SETEXPFLD:
443 0 : ((SwSetExpFieldType&)rFldTyp).SetDeleted( false );
444 0 : break;
445 : case RES_USERFLD:
446 0 : ((SwUserFieldType&)rFldTyp).SetDeleted( false );
447 0 : break;
448 : case RES_DDEFLD:
449 0 : ((SwDDEFieldType&)rFldTyp).SetDeleted( false );
450 0 : break;
451 0 : }
452 0 : }
453 :
454 236 : bool DocumentFieldsManager::PutValueToField(const SwPosition & rPos,
455 : const Any& rVal, sal_uInt16 nWhich)
456 : {
457 236 : Any aOldVal;
458 236 : SwField * pField = GetFieldAtPos(rPos);
459 :
460 340 : if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo() &&
461 104 : pField->QueryValue(aOldVal, nWhich))
462 : {
463 104 : SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich));
464 104 : m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
465 : }
466 :
467 236 : return pField->PutValue(rVal, nWhich);
468 : }
469 :
470 0 : bool DocumentFieldsManager::UpdateFld(SwTxtFld * pDstTxtFld, SwField & rSrcFld,
471 : SwMsgPoolItem * pMsgHnt,
472 : bool bUpdateFlds)
473 : {
474 : OSL_ENSURE(pDstTxtFld, "no field to update!");
475 :
476 0 : bool bTblSelBreak = false;
477 :
478 0 : SwFmtFld * pDstFmtFld = (SwFmtFld*)&pDstTxtFld->GetFmtFld();
479 0 : SwField * pDstFld = pDstFmtFld->GetField();
480 0 : sal_uInt16 nFldWhich = rSrcFld.GetTyp()->Which();
481 0 : SwNodeIndex aTblNdIdx(pDstTxtFld->GetTxtNode());
482 :
483 0 : if (pDstFld->GetTyp()->Which() ==
484 0 : rSrcFld.GetTyp()->Which())
485 : {
486 0 : if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
487 : {
488 0 : SwPosition aPosition( pDstTxtFld->GetTxtNode() );
489 0 : aPosition.nContent = pDstTxtFld->GetStart();
490 :
491 0 : SwUndo *const pUndo( new SwUndoFieldFromDoc( aPosition, *pDstFld, rSrcFld, pMsgHnt, bUpdateFlds) );
492 0 : m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
493 : }
494 :
495 0 : SwField * pNewFld = rSrcFld.CopyField();
496 0 : pDstFmtFld->SetField(pNewFld);
497 :
498 0 : switch( nFldWhich )
499 : {
500 : case RES_SETEXPFLD:
501 : case RES_GETEXPFLD:
502 : case RES_HIDDENTXTFLD:
503 : case RES_HIDDENPARAFLD:
504 0 : UpdateExpFlds( pDstTxtFld, true );
505 0 : break;
506 :
507 : case RES_TABLEFLD:
508 : {
509 : const SwTableNode* pTblNd =
510 0 : m_rSwdoc.IsIdxInTbl(aTblNdIdx);
511 0 : if( pTblNd )
512 : {
513 : SwTableFmlUpdate aTblUpdate( &pTblNd->
514 0 : GetTable() );
515 0 : if (bUpdateFlds)
516 0 : UpdateTblFlds( &aTblUpdate );
517 : else
518 0 : pNewFld->GetTyp()->ModifyNotification(0, &aTblUpdate);
519 :
520 0 : if (! bUpdateFlds)
521 0 : bTblSelBreak = true;
522 : }
523 : }
524 0 : break;
525 :
526 : case RES_MACROFLD:
527 0 : if( bUpdateFlds && pDstTxtFld->GetpTxtNode() )
528 0 : (pDstTxtFld->GetpTxtNode())->
529 0 : ModifyNotification( 0, pDstFmtFld );
530 0 : break;
531 :
532 : case RES_DBNAMEFLD:
533 : case RES_DBNEXTSETFLD:
534 : case RES_DBNUMSETFLD:
535 : case RES_DBSETNUMBERFLD:
536 0 : m_rSwdoc.ChgDBData(((SwDBNameInfField*) pNewFld)->GetRealDBData());
537 0 : pNewFld->GetTyp()->UpdateFlds();
538 :
539 0 : break;
540 :
541 : case RES_DBFLD:
542 : #if HAVE_FEATURE_DBCONNECTIVITY
543 : {
544 : // JP 10.02.96: call ChgValue, so that the style change sets the
545 : // ContentString correctly
546 0 : SwDBField* pDBFld = (SwDBField*)pNewFld;
547 0 : if (pDBFld->IsInitialized())
548 0 : pDBFld->ChgValue( pDBFld->GetValue(), true );
549 :
550 0 : pDBFld->ClearInitialized();
551 0 : pDBFld->InitContent();
552 : }
553 : #endif
554 : // no break;
555 :
556 : default:
557 0 : pDstFmtFld->ModifyNotification( 0, pMsgHnt );
558 : }
559 :
560 : // The fields we can calculate here are being triggered for an update
561 : // here explicitly.
562 0 : if( nFldWhich == RES_USERFLD )
563 0 : UpdateUsrFlds();
564 : }
565 :
566 0 : return bTblSelBreak;
567 : }
568 :
569 : /// Update reference and table fields
570 402 : void DocumentFieldsManager::UpdateRefFlds( SfxPoolItem* pHt )
571 : {
572 : SwFieldType* pFldType;
573 13336 : for( sal_uInt16 i = 0; i < mpFldTypes->size(); ++i )
574 12934 : if( RES_GETREFFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
575 402 : pFldType->ModifyNotification( 0, pHt );
576 402 : }
577 :
578 1892 : void DocumentFieldsManager::UpdateTblFlds( SfxPoolItem* pHt )
579 : {
580 : OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE == pHt->Which(),
581 : "What MessageItem is &m_rSwdoc?" );
582 :
583 1892 : SwFieldType* pFldType(0);
584 :
585 26488 : for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
586 : {
587 26488 : if( RES_TABLEFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
588 : {
589 1892 : SwTableFmlUpdate* pUpdtFld = 0;
590 1892 : if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
591 1738 : pUpdtFld = (SwTableFmlUpdate*)pHt;
592 :
593 1892 : SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
594 1892 : for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
595 : {
596 0 : if( pFmtFld->GetTxtFld() )
597 : {
598 0 : SwTblField* pFld = (SwTblField*)pFmtFld->GetField();
599 :
600 0 : if( pUpdtFld )
601 : {
602 : // table where &m_rSwdoc field is located
603 : const SwTableNode* pTblNd;
604 0 : const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
605 0 : if( !rTxtNd.GetNodes().IsDocNodes() ||
606 0 : 0 == ( pTblNd = rTxtNd.FindTableNode() ) )
607 0 : continue;
608 :
609 0 : switch( pUpdtFld->eFlags )
610 : {
611 : case TBL_CALC:
612 : // re-set the value flag
613 : // JP 17.06.96: internal representation of all formulas
614 : // (reference to other table!!!)
615 0 : if( nsSwExtendedSubType::SUB_CMD & pFld->GetSubType() )
616 0 : pFld->PtrToBoxNm( pUpdtFld->pTbl );
617 : else
618 0 : pFld->ChgValid( false );
619 0 : break;
620 : case TBL_BOXNAME:
621 : // is &m_rSwdoc the wanted table?
622 0 : if( &pTblNd->GetTable() == pUpdtFld->pTbl )
623 : // to the external representation
624 0 : pFld->PtrToBoxNm( pUpdtFld->pTbl );
625 0 : break;
626 : case TBL_BOXPTR:
627 : // to the internal representation
628 : // JP 17.06.96: internal representation on all formulas
629 : // (reference to other table!!!)
630 0 : pFld->BoxNmToPtr( pUpdtFld->pTbl );
631 0 : break;
632 : case TBL_RELBOXNAME:
633 : // is &m_rSwdoc the wanted table?
634 0 : if( &pTblNd->GetTable() == pUpdtFld->pTbl )
635 : // to the relative representation
636 0 : pFld->ToRelBoxNm( pUpdtFld->pTbl );
637 0 : break;
638 : default:
639 0 : break;
640 : }
641 : }
642 : else
643 : // reset the value flag for all
644 0 : pFld->ChgValid( false );
645 : }
646 : }
647 :
648 1892 : break;
649 : }
650 24596 : pFldType = 0;
651 : }
652 :
653 : // process all table box formulas
654 : const SfxPoolItem* pItem;
655 1892 : sal_uInt32 nMaxItems = m_rSwdoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
656 1892 : for (sal_uInt32 i = 0; i < nMaxItems; ++i)
657 : {
658 0 : if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
659 0 : ((SwTblBoxFormula*)pItem)->GetDefinedIn() )
660 : {
661 0 : ((SwTblBoxFormula*)pItem)->ChangeState( pHt );
662 : }
663 : }
664 :
665 : // all fields/boxes are now invalid, so we can start to calculate
666 3630 : if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
667 1738 : TBL_CALC != ((SwTableFmlUpdate*)pHt)->eFlags ))
668 3088 : return ;
669 :
670 696 : SwCalc* pCalc = 0;
671 :
672 696 : if( pFldType )
673 : {
674 696 : SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
675 696 : for( SwFmtFld* pFmtFld = aIter.Last(); pFmtFld; pFmtFld = aIter.Previous() )
676 : {
677 : // start calculation at the end
678 : // new fields are inserted at the beginning of the modify chain
679 : // that gives faster calculation on import
680 : // mba: do we really need &m_rSwdoc "optimization"? Is it still valid?
681 : SwTblField* pFld;
682 0 : if( !pFmtFld->GetTxtFld() || (nsSwExtendedSubType::SUB_CMD &
683 0 : (pFld = (SwTblField*)pFmtFld->GetField())->GetSubType() ))
684 0 : continue;
685 :
686 : // needs to be recalculated
687 0 : if( !pFld->IsValid() )
688 : {
689 : // table where &m_rSwdoc field is located
690 0 : const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
691 0 : if( !rTxtNd.GetNodes().IsDocNodes() )
692 0 : continue;
693 0 : const SwTableNode* pTblNd = rTxtNd.FindTableNode();
694 0 : if( !pTblNd )
695 0 : continue;
696 :
697 : // if &m_rSwdoc field is not in the to-be-updated table, skip it
698 0 : if( pHt && &pTblNd->GetTable() !=
699 : ((SwTableFmlUpdate*)pHt)->pTbl )
700 0 : continue;
701 :
702 0 : if( !pCalc )
703 0 : pCalc = new SwCalc( m_rSwdoc );
704 :
705 : // get the values of all SetExpression fields that are valid
706 : // until the table
707 0 : SwFrm* pFrm = 0;
708 0 : if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
709 : {
710 : // is in the special section, that's expensive!
711 0 : Point aPt; // return the first frame of the layout - Tab.Headline!!
712 0 : pFrm = rTxtNd.getLayoutFrm( m_rSwdoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt );
713 0 : if( pFrm )
714 : {
715 0 : SwPosition aPos( *pTblNd );
716 0 : if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
717 : FldsToCalc( *pCalc, _SetGetExpFld(
718 0 : aPos.nNode, pFmtFld->GetTxtFld(),
719 0 : &aPos.nContent ));
720 : else
721 0 : pFrm = 0;
722 : }
723 : }
724 0 : if( !pFrm )
725 : {
726 : // create index to determine the TextNode
727 0 : SwNodeIndex aIdx( rTxtNd );
728 : FldsToCalc( *pCalc,
729 0 : _SetGetExpFld( aIdx, pFmtFld->GetTxtFld() ));
730 : }
731 :
732 0 : SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
733 0 : pFld->CalcField( aPara );
734 0 : if( aPara.IsStackOverflow() )
735 : {
736 0 : bool const bResult = aPara.CalcWithStackOverflow();
737 0 : if (bResult)
738 : {
739 0 : pFld->CalcField( aPara );
740 : }
741 : OSL_ENSURE(bResult,
742 : "the chained formula could no be calculated");
743 : }
744 0 : pCalc->SetCalcError( CALC_NOERR );
745 : }
746 0 : pFmtFld->ModifyNotification( 0, pHt );
747 696 : }
748 : }
749 :
750 : // calculate the formula at the boxes
751 696 : for (sal_uInt32 i = 0; i < nMaxItems; ++i )
752 : {
753 0 : if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
754 0 : ((SwTblBoxFormula*)pItem)->GetDefinedIn() &&
755 0 : !((SwTblBoxFormula*)pItem)->IsValid() )
756 : {
757 0 : SwTblBoxFormula* pFml = (SwTblBoxFormula*)pItem;
758 0 : SwTableBox* pBox = pFml->GetTableBox();
759 0 : if( pBox && pBox->GetSttNd() &&
760 0 : pBox->GetSttNd()->GetNodes().IsDocNodes() )
761 : {
762 0 : const SwTableNode* pTblNd = pBox->GetSttNd()->FindTableNode();
763 0 : if( !pHt || &pTblNd->GetTable() ==
764 : ((SwTableFmlUpdate*)pHt)->pTbl )
765 : {
766 : double nValue;
767 0 : if( !pCalc )
768 0 : pCalc = new SwCalc( m_rSwdoc );
769 :
770 : // get the values of all SetExpression fields that are valid
771 : // until the table
772 0 : SwFrm* pFrm = 0;
773 0 : if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
774 : {
775 : // is in the special section, that's expensive!
776 0 : Point aPt; // return the first frame of the layout - Tab.Headline!!
777 0 : SwNodeIndex aCNdIdx( *pTblNd, +2 );
778 0 : SwCntntNode* pCNd = aCNdIdx.GetNode().GetCntntNode();
779 0 : if( !pCNd )
780 0 : pCNd = m_rSwdoc.GetNodes().GoNext( &aCNdIdx );
781 :
782 0 : if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( m_rSwdoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt )) )
783 : {
784 0 : SwPosition aPos( *pCNd );
785 0 : if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
786 0 : FldsToCalc( *pCalc, _SetGetExpFld( aPos.nNode ));
787 : else
788 0 : pFrm = 0;
789 0 : }
790 : }
791 0 : if( !pFrm )
792 : {
793 : // create index to determine the TextNode
794 0 : SwNodeIndex aIdx( *pTblNd );
795 0 : FldsToCalc( *pCalc, _SetGetExpFld( aIdx ));
796 : }
797 :
798 0 : SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
799 0 : pFml->Calc( aPara, nValue );
800 :
801 0 : if( aPara.IsStackOverflow() )
802 : {
803 0 : bool const bResult = aPara.CalcWithStackOverflow();
804 0 : if (bResult)
805 : {
806 0 : pFml->Calc( aPara, nValue );
807 : }
808 : OSL_ENSURE(bResult,
809 : "the chained formula could no be calculated");
810 : }
811 :
812 0 : SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
813 0 : SfxItemSet aTmp( m_rSwdoc.GetAttrPool(),
814 0 : RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
815 :
816 0 : if( pCalc->IsCalcError() )
817 0 : nValue = DBL_MAX;
818 0 : aTmp.Put( SwTblBoxValue( nValue ));
819 0 : if( SfxItemState::SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
820 0 : aTmp.Put( SwTblBoxNumFormat( 0 ));
821 0 : pFmt->SetFmtAttr( aTmp );
822 :
823 0 : pCalc->SetCalcError( CALC_NOERR );
824 : }
825 : }
826 : }
827 : }
828 :
829 696 : delete pCalc;
830 : }
831 :
832 8164 : void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds )
833 : {
834 8164 : if( IsExpFldsLocked() || m_rSwdoc.IsInReading() )
835 15944 : return;
836 :
837 362 : bool bOldInUpdateFlds = mpUpdtFlds->IsInUpdateFlds();
838 362 : mpUpdtFlds->SetInUpdateFlds( true );
839 :
840 362 : mpUpdtFlds->MakeFldList( m_rSwdoc, true, GETFLD_ALL );
841 362 : mbNewFldLst = false;
842 :
843 362 : if( mpUpdtFlds->GetSortLst()->empty() )
844 : {
845 340 : if( bUpdRefFlds )
846 200 : UpdateRefFlds(NULL);
847 :
848 340 : mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
849 340 : mpUpdtFlds->SetFieldsDirty( false );
850 340 : return ;
851 : }
852 :
853 : sal_uInt16 nWhich, n;
854 :
855 : // Hash table for all string replacements is filled on-the-fly.
856 : // Try to fabricate an uneven number.
857 22 : sal_uInt16 nStrFmtCnt = (( mpFldTypes->size() / 7 ) + 1 ) * 7;
858 22 : SwHash** pHashStrTbl = new SwHash*[ nStrFmtCnt ];
859 22 : memset( pHashStrTbl, 0, sizeof( _HashStr* ) * nStrFmtCnt );
860 :
861 : {
862 : const SwFieldType* pFldType;
863 : // process separately:
864 816 : for( n = mpFldTypes->size(); n; )
865 772 : switch( ( pFldType = (*mpFldTypes)[ --n ] )->Which() )
866 : {
867 : case RES_USERFLD:
868 : {
869 : // Entry present?
870 : sal_uInt16 nPos;
871 6 : const OUString& rNm = pFldType->GetName();
872 12 : OUString sExpand(((SwUserFieldType*)pFldType)->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0));
873 6 : SwHash* pFnd = Find( rNm, pHashStrTbl, nStrFmtCnt, &nPos );
874 6 : if( pFnd )
875 : // modify entry in the hash table
876 0 : ((_HashStr*)pFnd)->aSetStr = sExpand;
877 : else
878 : // insert the new entry
879 6 : *(pHashStrTbl + nPos ) = new _HashStr( rNm, sExpand,
880 18 : (_HashStr*)*(pHashStrTbl + nPos) );
881 : }
882 6 : break;
883 : case RES_SETEXPFLD:
884 94 : ((SwSetExpFieldType*)pFldType)->SetOutlineChgNd( 0 );
885 94 : break;
886 : }
887 : }
888 :
889 : // The array is filled with all fields; start calculation.
890 22 : SwCalc aCalc( m_rSwdoc );
891 :
892 : #if HAVE_FEATURE_DBCONNECTIVITY
893 44 : OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
894 :
895 : // already set the current record number
896 22 : SwDBManager* pMgr = m_rSwdoc.GetDBManager();
897 22 : pMgr->CloseAll( false );
898 :
899 44 : SvtSysLocale aSysLocale;
900 22 : const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
901 22 : const long nLang = pLclData->getLanguageTag().getLanguageType();
902 22 : bool bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
903 : #endif
904 :
905 : // Make sure we don't hide all sections, which would lead to a crash. First, count how many of them do we have.
906 22 : int nShownSections = 0;
907 92 : for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
908 : {
909 70 : SwSection* pSect = (SwSection*)(*it)->GetSection();
910 70 : if ( pSect && !pSect->IsCondHidden())
911 14 : nShownSections++;
912 : }
913 :
914 44 : OUString aNew;
915 92 : for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
916 : {
917 70 : SwSection* pSect = (SwSection*)(*it)->GetSection();
918 70 : if( pSect )
919 : {
920 :
921 : SwSbxValue aValue = aCalc.Calculate(
922 14 : pSect->GetCondition() );
923 14 : if(!aValue.IsVoidValue())
924 : {
925 : // Do we want to hide this one?
926 8 : bool bHide = aValue.GetBool();
927 8 : if (bHide && !pSect->IsCondHidden())
928 : {
929 : // This section will be hidden, but it wasn't before
930 6 : if (nShownSections == 1)
931 : {
932 : // Is the last node part of a section?
933 6 : SwPaM aPam(m_rSwdoc.GetNodes());
934 6 : aPam.Move(fnMoveForward, fnGoDoc);
935 6 : if (aPam.Start()->nNode.GetNode().StartOfSectionNode()->IsSectionNode())
936 : {
937 : // This would be the last section, so set its condition to false, and avoid hiding it.
938 4 : OUString aCond("0");
939 4 : pSect->SetCondition(aCond);
940 4 : bHide = false;
941 6 : }
942 : }
943 6 : nShownSections--;
944 : }
945 8 : pSect->SetCondHidden( bHide );
946 : }
947 14 : continue;
948 : }
949 :
950 56 : SwTxtFld* pTxtFld = (SwTxtFld*)(*it)->GetTxtFld();
951 56 : if( !pTxtFld )
952 : {
953 : OSL_ENSURE( false, "what's wrong now'" );
954 0 : continue;
955 : }
956 :
957 56 : SwFmtFld* pFmtFld = (SwFmtFld*)&pTxtFld->GetFmtFld();
958 56 : const SwField* pFld = pFmtFld->GetField();
959 :
960 56 : switch( nWhich = pFld->GetTyp()->Which() )
961 : {
962 : case RES_HIDDENTXTFLD:
963 : {
964 0 : SwHiddenTxtField* pHFld = (SwHiddenTxtField*)pFld;
965 0 : SwSbxValue aValue = aCalc.Calculate( pHFld->GetPar1() );
966 0 : bool bValue = !aValue.GetBool();
967 0 : if(!aValue.IsVoidValue())
968 : {
969 0 : pHFld->SetValue( bValue );
970 : // evaluate field
971 0 : pHFld->Evaluate(&m_rSwdoc);
972 0 : }
973 : }
974 0 : break;
975 : case RES_HIDDENPARAFLD:
976 : {
977 0 : SwHiddenParaField* pHPFld = (SwHiddenParaField*)pFld;
978 0 : SwSbxValue aValue = aCalc.Calculate( pHPFld->GetPar1() );
979 0 : bool bValue = aValue.GetBool();
980 0 : if(!aValue.IsVoidValue())
981 0 : pHPFld->SetHidden( bValue );
982 : }
983 0 : break;
984 : case RES_DBSETNUMBERFLD:
985 : #if HAVE_FEATURE_DBCONNECTIVITY
986 : {
987 0 : ((SwDBSetNumberField*)pFld)->Evaluate(&m_rSwdoc);
988 0 : aCalc.VarChange( sDBNumNm, ((SwDBSetNumberField*)pFld)->GetSetNumber());
989 : }
990 : #endif
991 0 : break;
992 : case RES_DBNEXTSETFLD:
993 : case RES_DBNUMSETFLD:
994 : #if HAVE_FEATURE_DBCONNECTIVITY
995 : {
996 0 : UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc );
997 0 : if( bCanFill )
998 0 : bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
999 : }
1000 : #endif
1001 0 : break;
1002 : case RES_DBFLD:
1003 : {
1004 : #if HAVE_FEATURE_DBCONNECTIVITY
1005 : // evaluate field
1006 50 : ((SwDBField*)pFld)->Evaluate();
1007 :
1008 50 : SwDBData aTmpDBData(((SwDBField*)pFld)->GetDBData());
1009 :
1010 50 : if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
1011 0 : aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
1012 :
1013 100 : const OUString& rName = pFld->GetTyp()->GetName();
1014 :
1015 : // Add entry to hash table
1016 : // Entry present?
1017 : sal_uInt16 nPos;
1018 50 : SwHash* pFnd = Find( rName, pHashStrTbl, nStrFmtCnt, &nPos );
1019 100 : OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
1020 50 : if( pFnd )
1021 : {
1022 : // Modify entry in the hash table
1023 6 : static_cast<_HashStr*>(pFnd)->aSetStr = value;
1024 : }
1025 : else
1026 : {
1027 : // insert new entry
1028 44 : *(pHashStrTbl + nPos ) = new _HashStr( rName,
1029 88 : value, static_cast<_HashStr *>(*(pHashStrTbl + nPos)));
1030 50 : }
1031 : #endif
1032 : }
1033 50 : break;
1034 : case RES_GETEXPFLD:
1035 : case RES_SETEXPFLD:
1036 : {
1037 6 : if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() ) // replace String
1038 : {
1039 2 : if( RES_GETEXPFLD == nWhich )
1040 : {
1041 0 : SwGetExpField* pGFld = (SwGetExpField*)pFld;
1042 :
1043 0 : if( (!pUpdtFld || pUpdtFld == pTxtFld )
1044 0 : && pGFld->IsInBodyTxt() )
1045 : {
1046 0 : aNew = LookString( pHashStrTbl, nStrFmtCnt,
1047 0 : pGFld->GetFormula() );
1048 0 : pGFld->ChgExpStr( aNew );
1049 : }
1050 : }
1051 : else
1052 : {
1053 2 : SwSetExpField* pSFld = (SwSetExpField*)pFld;
1054 : // is the "formula" a field?
1055 6 : aNew = LookString( pHashStrTbl, nStrFmtCnt,
1056 4 : pSFld->GetFormula() );
1057 :
1058 2 : if( aNew.isEmpty() ) // nothing found then the formula is the new value
1059 2 : aNew = pSFld->GetFormula();
1060 :
1061 : // only update one field
1062 2 : if( !pUpdtFld || pUpdtFld == pTxtFld )
1063 2 : pSFld->ChgExpStr( aNew );
1064 :
1065 : // lookup the field's name
1066 2 : aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
1067 : // Entry present?
1068 : sal_uInt16 nPos;
1069 2 : SwHash* pFnd = Find( aNew, pHashStrTbl, nStrFmtCnt, &nPos );
1070 2 : if( pFnd )
1071 : // Modify entry in the hash table
1072 0 : ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
1073 : else
1074 : // insert new entry
1075 2 : *(pHashStrTbl + nPos ) = pFnd = new _HashStr( aNew,
1076 : pSFld->GetExpStr(),
1077 2 : (_HashStr*)*(pHashStrTbl + nPos) );
1078 :
1079 : // Extension for calculation with Strings
1080 2 : SwSbxValue aValue;
1081 2 : aValue.PutString( ((_HashStr*)pFnd)->aSetStr );
1082 2 : aCalc.VarChange( aNew, aValue );
1083 : }
1084 : }
1085 : else // recalculate formula
1086 : {
1087 4 : if( RES_GETEXPFLD == nWhich )
1088 : {
1089 0 : SwGetExpField* pGFld = (SwGetExpField*)pFld;
1090 :
1091 0 : if( (!pUpdtFld || pUpdtFld == pTxtFld )
1092 0 : && pGFld->IsInBodyTxt() )
1093 : {
1094 : SwSbxValue aValue = aCalc.Calculate(
1095 0 : pGFld->GetFormula());
1096 0 : if(!aValue.IsVoidValue())
1097 0 : pGFld->SetValue(aValue.GetDouble() );
1098 : }
1099 : }
1100 : else
1101 : {
1102 4 : SwSetExpField* pSFld = (SwSetExpField*)pFld;
1103 4 : SwSetExpFieldType* pSFldTyp = (SwSetExpFieldType*)pFld->GetTyp();
1104 4 : aNew = pSFldTyp->GetName();
1105 :
1106 4 : SwNode* pSeqNd = 0;
1107 :
1108 4 : if( pSFld->IsSequenceFld() )
1109 : {
1110 0 : const sal_uInt8 nLvl = pSFldTyp->GetOutlineLvl();
1111 0 : if( MAXLEVEL > nLvl )
1112 : {
1113 : // test if the Number needs to be updated
1114 0 : pSeqNd = m_rSwdoc.GetNodes()[ (*it)->GetNode() ];
1115 :
1116 : const SwTxtNode* pOutlNd = pSeqNd->
1117 0 : FindOutlineNodeOfLevel( nLvl );
1118 0 : if( pSFldTyp->GetOutlineChgNd() != pOutlNd )
1119 : {
1120 0 : pSFldTyp->SetOutlineChgNd( pOutlNd );
1121 0 : aCalc.VarChange( aNew, 0 );
1122 : }
1123 : }
1124 : }
1125 :
1126 4 : aNew += "=";
1127 4 : aNew += pSFld->GetFormula();
1128 :
1129 4 : SwSbxValue aValue = aCalc.Calculate( aNew );
1130 4 : double nErg = aValue.GetDouble();
1131 : // only update one field
1132 4 : if( !aValue.IsVoidValue() && (!pUpdtFld || pUpdtFld == pTxtFld) )
1133 : {
1134 4 : pSFld->SetValue( nErg );
1135 :
1136 4 : if( pSeqNd )
1137 0 : pSFldTyp->SetChapter( *pSFld, *pSeqNd );
1138 4 : }
1139 : }
1140 : }
1141 : }
1142 : } // switch
1143 :
1144 56 : pFmtFld->ModifyNotification( 0, 0 ); // trigger formatting
1145 :
1146 56 : if( pUpdtFld == pTxtFld ) // if only &m_rSwdoc one is updated
1147 : {
1148 0 : if( RES_GETEXPFLD == nWhich || // only GetField or
1149 0 : RES_HIDDENTXTFLD == nWhich || // HiddenTxt?
1150 : RES_HIDDENPARAFLD == nWhich) // HiddenParaFld?
1151 : break; // quit
1152 0 : pUpdtFld = 0; // update all from here on
1153 : }
1154 : }
1155 :
1156 : #if HAVE_FEATURE_DBCONNECTIVITY
1157 22 : pMgr->CloseAll(false);
1158 : #endif
1159 : // delete hash table
1160 22 : ::DeleteHashTable( pHashStrTbl, nStrFmtCnt );
1161 :
1162 : // update reference fields
1163 22 : if( bUpdRefFlds )
1164 8 : UpdateRefFlds(NULL);
1165 :
1166 22 : mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
1167 44 : mpUpdtFlds->SetFieldsDirty( false );
1168 : }
1169 :
1170 : /// Insert field type that was marked as deleted
1171 0 : void DocumentFieldsManager::UpdateUsrFlds()
1172 : {
1173 0 : SwCalc* pCalc = 0;
1174 : const SwFieldType* pFldType;
1175 0 : for( sal_uInt16 i = INIT_FLDTYPES; i < mpFldTypes->size(); ++i )
1176 0 : if( RES_USERFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
1177 : {
1178 0 : if( !pCalc )
1179 0 : pCalc = new SwCalc( m_rSwdoc );
1180 0 : ((SwUserFieldType*)pFldType)->GetValue( *pCalc );
1181 : }
1182 :
1183 0 : if( pCalc )
1184 : {
1185 0 : delete pCalc;
1186 0 : m_rSwdoc.getIDocumentState().SetModified();
1187 : }
1188 0 : }
1189 :
1190 6956 : void DocumentFieldsManager::UpdatePageFlds( SfxPoolItem* pMsgHnt )
1191 : {
1192 : SwFieldType* pFldType;
1193 229548 : for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
1194 222592 : switch( ( pFldType = (*mpFldTypes)[ i ] )->Which() )
1195 : {
1196 : case RES_PAGENUMBERFLD:
1197 : case RES_CHAPTERFLD:
1198 : case RES_GETEXPFLD:
1199 : case RES_REFPAGEGETFLD:
1200 27824 : pFldType->ModifyNotification( 0, pMsgHnt );
1201 27824 : break;
1202 : case RES_DOCSTATFLD:
1203 6956 : pFldType->ModifyNotification( 0, 0 );
1204 6956 : break;
1205 : }
1206 6956 : SetNewFldLst(true);
1207 6956 : }
1208 :
1209 4810 : void DocumentFieldsManager::LockExpFlds()
1210 : {
1211 4810 : ++mnLockExpFld;
1212 4810 : }
1213 :
1214 4808 : void DocumentFieldsManager::UnlockExpFlds()
1215 : {
1216 : assert(mnLockExpFld != 0);
1217 4808 : if( mnLockExpFld )
1218 4808 : --mnLockExpFld;
1219 4808 : }
1220 :
1221 8354 : bool DocumentFieldsManager::IsExpFldsLocked() const
1222 : {
1223 8354 : return 0 != mnLockExpFld;
1224 : }
1225 :
1226 48828 : SwDocUpdtFld& DocumentFieldsManager::GetUpdtFlds() const
1227 : {
1228 48828 : return *mpUpdtFlds;
1229 : }
1230 :
1231 25502 : bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
1232 : {
1233 : // See if the supplied nodes actually contain fields.
1234 : // If they don't, the flag doesn't need to be changed.
1235 25502 : bool bFldsFnd = false;
1236 25502 : if( b && pChk && !GetUpdtFlds().IsFieldsDirty() && !m_rSwdoc.IsInDtor()
1237 : // ?? what's up with Undo, this is also wanted there!
1238 : /*&& &pChk->GetNodes() == &GetNodes()*/ )
1239 : {
1240 18304 : b = false;
1241 18304 : if( !nLen )
1242 0 : ++nLen;
1243 18304 : sal_uLong nStt = pChk->GetIndex();
1244 18304 : const SwNodes& rNds = pChk->GetNodes();
1245 54806 : while( nLen-- )
1246 : {
1247 18324 : const SwTxtNode* pTNd = rNds[ nStt++ ]->GetTxtNode();
1248 18324 : if( pTNd )
1249 : {
1250 18318 : if( pTNd->GetAttrOutlineLevel() != 0 )
1251 : // update chapter fields
1252 0 : b = true;
1253 18318 : else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
1254 : {
1255 1014 : const size_t nEnd = pTNd->GetSwpHints().Count();
1256 2368 : for( size_t n = 0 ; n < nEnd; ++n )
1257 : {
1258 1480 : const SwTxtAttr* pAttr = pTNd->GetSwpHints()[ n ];
1259 1480 : if ( pAttr->Which() == RES_TXTATR_FIELD )
1260 : {
1261 126 : b = true;
1262 126 : break;
1263 : }
1264 : }
1265 : }
1266 :
1267 18318 : if( b )
1268 126 : break;
1269 : }
1270 : }
1271 18304 : bFldsFnd = b;
1272 : }
1273 25502 : GetUpdtFlds().SetFieldsDirty( b );
1274 25502 : return bFldsFnd;
1275 : }
1276 :
1277 76 : void DocumentFieldsManager::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
1278 : {
1279 76 : bool bIsModified = m_rSwdoc.getIDocumentState().IsModified();
1280 :
1281 : sal_Int32 nDate;
1282 : sal_Int64 nTime;
1283 76 : if( pNewDateTime )
1284 : {
1285 0 : nDate = pNewDateTime->GetDate();
1286 0 : nTime = pNewDateTime->GetTime();
1287 : }
1288 : else
1289 : {
1290 76 : nDate = Date( Date::SYSTEM ).GetDate();
1291 76 : nTime = tools::Time( tools::Time::SYSTEM ).GetTime();
1292 : }
1293 :
1294 : sal_uInt16 aTypes[5] = {
1295 : /*0*/ RES_DOCINFOFLD,
1296 : /*1*/ RES_AUTHORFLD,
1297 : /*2*/ RES_EXTUSERFLD,
1298 : /*3*/ RES_FILENAMEFLD,
1299 76 : /*4*/ RES_DATETIMEFLD }; // MUST be at the end!
1300 :
1301 76 : sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0;
1302 :
1303 456 : for( ; nStt < 5; ++nStt )
1304 : {
1305 380 : SwFieldType* pFldType = GetSysFldType( aTypes[ nStt ] );
1306 380 : SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
1307 388 : for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
1308 : {
1309 8 : if( pFmtFld && pFmtFld->GetTxtFld() )
1310 : {
1311 8 : bool bChgd = false;
1312 8 : switch( aTypes[ nStt ] )
1313 : {
1314 : case RES_DOCINFOFLD:
1315 0 : if( ((SwDocInfoField*)pFmtFld->GetField())->IsFixed() )
1316 : {
1317 0 : bChgd = true;
1318 0 : SwDocInfoField* pDocInfFld = (SwDocInfoField*)pFmtFld->GetField();
1319 : pDocInfFld->SetExpansion( ((SwDocInfoFieldType*)
1320 0 : pDocInfFld->GetTyp())->Expand(
1321 0 : pDocInfFld->GetSubType(),
1322 : pDocInfFld->GetFormat(),
1323 0 : pDocInfFld->GetLanguage(),
1324 0 : pDocInfFld->GetName() ) );
1325 : }
1326 0 : break;
1327 :
1328 : case RES_AUTHORFLD:
1329 0 : if( ((SwAuthorField*)pFmtFld->GetField())->IsFixed() )
1330 : {
1331 0 : bChgd = true;
1332 0 : SwAuthorField* pAuthorFld = (SwAuthorField*)pFmtFld->GetField();
1333 : pAuthorFld->SetExpansion( ((SwAuthorFieldType*)
1334 0 : pAuthorFld->GetTyp())->Expand(
1335 0 : pAuthorFld->GetFormat() ) );
1336 : }
1337 0 : break;
1338 :
1339 : case RES_EXTUSERFLD:
1340 0 : if( ((SwExtUserField*)pFmtFld->GetField())->IsFixed() )
1341 : {
1342 0 : bChgd = true;
1343 0 : SwExtUserField* pExtUserFld = (SwExtUserField*)pFmtFld->GetField();
1344 : pExtUserFld->SetExpansion( ((SwExtUserFieldType*)
1345 0 : pExtUserFld->GetTyp())->Expand(
1346 0 : pExtUserFld->GetSubType(),
1347 0 : pExtUserFld->GetFormat()));
1348 : }
1349 0 : break;
1350 :
1351 : case RES_DATETIMEFLD:
1352 8 : if( ((SwDateTimeField*)pFmtFld->GetField())->IsFixed() )
1353 : {
1354 0 : bChgd = true;
1355 0 : ((SwDateTimeField*)pFmtFld->GetField())->SetDateTime(
1356 0 : DateTime(Date(nDate), tools::Time(nTime)) );
1357 : }
1358 8 : break;
1359 :
1360 : case RES_FILENAMEFLD:
1361 0 : if( ((SwFileNameField*)pFmtFld->GetField())->IsFixed() )
1362 : {
1363 0 : bChgd = true;
1364 : SwFileNameField* pFileNameFld =
1365 0 : (SwFileNameField*)pFmtFld->GetField();
1366 : pFileNameFld->SetExpansion( ((SwFileNameFieldType*)
1367 0 : pFileNameFld->GetTyp())->Expand(
1368 0 : pFileNameFld->GetFormat() ) );
1369 : }
1370 0 : break;
1371 : }
1372 :
1373 : // Trigger formatting
1374 8 : if( bChgd )
1375 0 : pFmtFld->ModifyNotification( 0, 0 );
1376 : }
1377 : }
1378 380 : }
1379 :
1380 76 : if( !bIsModified )
1381 44 : m_rSwdoc.getIDocumentState().ResetModified();
1382 76 : }
1383 :
1384 0 : void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, const _SetGetExpFld& rToThisFld )
1385 : {
1386 : // create the sorted list of all SetFields
1387 0 : mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
1388 0 : mbNewFldLst = false;
1389 :
1390 : #if !HAVE_FEATURE_DBCONNECTIVITY
1391 : SwDBManager* pMgr = NULL;
1392 : #else
1393 0 : SwDBManager* pMgr = m_rSwdoc.GetDBManager();
1394 0 : pMgr->CloseAll(false);
1395 : #endif
1396 :
1397 0 : if( !mpUpdtFlds->GetSortLst()->empty() )
1398 : {
1399 : _SetGetExpFlds::const_iterator const itLast =
1400 0 : mpUpdtFlds->GetSortLst()->upper_bound(
1401 0 : const_cast<_SetGetExpFld*>(&rToThisFld));
1402 0 : for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
1403 0 : lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
1404 : }
1405 : #if HAVE_FEATURE_DBCONNECTIVITY
1406 0 : pMgr->CloseAll(false);
1407 : #endif
1408 0 : }
1409 :
1410 16 : void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
1411 : {
1412 : // create the sorted list of all SetFields
1413 16 : mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
1414 16 : mbNewFldLst = false;
1415 :
1416 : #if !HAVE_FEATURE_DBCONNECTIVITY
1417 : SwDBManager* pMgr = NULL;
1418 : #else
1419 16 : SwDBManager* pMgr = m_rSwdoc.GetDBManager();
1420 16 : pMgr->CloseAll(false);
1421 : #endif
1422 :
1423 84 : for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin();
1424 108 : it != mpUpdtFlds->GetSortLst()->end() &&
1425 22 : ( (*it)->GetNode() < nLastNd ||
1426 20 : ( (*it)->GetNode() == nLastNd && (*it)->GetCntnt() <= nLastCnt )
1427 : );
1428 : ++it )
1429 : {
1430 12 : lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
1431 : }
1432 :
1433 : #if HAVE_FEATURE_DBCONNECTIVITY
1434 16 : pMgr->CloseAll(false);
1435 : #endif
1436 16 : }
1437 :
1438 0 : void DocumentFieldsManager::FldsToExpand( SwHash**& ppHashTbl, sal_uInt16& rTblSize,
1439 : const _SetGetExpFld& rToThisFld )
1440 : {
1441 : // create the sorted list of all SetFields
1442 0 : mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_EXPAND );
1443 0 : mbNewFldLst = false;
1444 :
1445 : // Hash table for all string replacements is filled on-the-fly.
1446 : // Try to fabricate an uneven number.
1447 0 : rTblSize = (( mpUpdtFlds->GetSortLst()->size() / 7 ) + 1 ) * 7;
1448 0 : ppHashTbl = new SwHash*[ rTblSize ];
1449 0 : memset( ppHashTbl, 0, sizeof( _HashStr* ) * rTblSize );
1450 :
1451 : _SetGetExpFlds::const_iterator const itLast =
1452 0 : mpUpdtFlds->GetSortLst()->upper_bound(
1453 0 : const_cast<_SetGetExpFld*>(&rToThisFld));
1454 :
1455 0 : for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
1456 : {
1457 0 : const SwTxtFld* pTxtFld = (*it)->GetTxtFld();
1458 0 : if( !pTxtFld )
1459 0 : continue;
1460 :
1461 0 : const SwField* pFld = pTxtFld->GetFmtFld().GetField();
1462 0 : switch( pFld->GetTyp()->Which() )
1463 : {
1464 : case RES_SETEXPFLD:
1465 0 : if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() )
1466 : {
1467 : // set the new value in the hash table
1468 : // is the formula a field?
1469 0 : SwSetExpField* pSFld = (SwSetExpField*)pFld;
1470 0 : OUString aNew = LookString( ppHashTbl, rTblSize, pSFld->GetFormula() );
1471 :
1472 0 : if( aNew.isEmpty() ) // nothing found, then the formula is
1473 0 : aNew = pSFld->GetFormula(); // the new value
1474 :
1475 : // #i3141# - update expression of field as in method
1476 : // <SwDoc::UpdateExpFlds(..)> for string/text fields
1477 0 : pSFld->ChgExpStr( aNew );
1478 :
1479 : // look up the field's name
1480 0 : aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
1481 : // Entry present?
1482 : sal_uInt16 nPos;
1483 0 : SwHash* pFnd = Find( aNew, ppHashTbl, rTblSize, &nPos );
1484 0 : if( pFnd )
1485 : // modify entry in the hash table
1486 0 : ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
1487 : else
1488 : // insert the new entry
1489 0 : *(ppHashTbl + nPos ) = new _HashStr( aNew,
1490 0 : pSFld->GetExpStr(), (_HashStr*)*(ppHashTbl + nPos) );
1491 : }
1492 0 : break;
1493 : case RES_DBFLD:
1494 : {
1495 0 : const OUString& rName = pFld->GetTyp()->GetName();
1496 :
1497 : // Insert entry in the hash table
1498 : // Entry present?
1499 : sal_uInt16 nPos;
1500 0 : SwHash* pFnd = Find( rName, ppHashTbl, rTblSize, &nPos );
1501 0 : OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
1502 0 : if( pFnd )
1503 : {
1504 : // modify entry in the hash table
1505 0 : static_cast<_HashStr*>(pFnd)->aSetStr = value;
1506 : }
1507 : else
1508 : {
1509 : // insert the new entry
1510 0 : *(ppHashTbl + nPos ) = new _HashStr( rName,
1511 0 : value, static_cast<_HashStr *>(*(ppHashTbl + nPos)));
1512 0 : }
1513 : }
1514 0 : break;
1515 : }
1516 : }
1517 0 : }
1518 :
1519 :
1520 2980 : bool DocumentFieldsManager::IsNewFldLst() const
1521 : {
1522 2980 : return mbNewFldLst;
1523 : }
1524 :
1525 9924 : void DocumentFieldsManager::SetNewFldLst(bool bFlag)
1526 : {
1527 9924 : mbNewFldLst = bFlag;
1528 9924 : }
1529 :
1530 16 : void DocumentFieldsManager::InsDelFldInFldLst( bool bIns, const SwTxtFld& rFld )
1531 : {
1532 16 : if( !mbNewFldLst || !m_rSwdoc.IsInDtor() )
1533 16 : mpUpdtFlds->InsDelFldInFldLst( bIns, rFld );
1534 16 : }
1535 :
1536 236 : SwField * DocumentFieldsManager::GetFieldAtPos(const SwPosition & rPos)
1537 : {
1538 236 : SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
1539 :
1540 236 : return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
1541 : }
1542 :
1543 264 : SwTxtFld * DocumentFieldsManager::GetTxtFldAtPos(const SwPosition & rPos)
1544 : {
1545 264 : SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
1546 :
1547 : return (pNode != NULL)
1548 264 : ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
1549 528 : : 0;
1550 : }
1551 :
1552 : /// @note For simplicity assume that all field types have updatable contents so
1553 : /// optimization currently only available when no fields exist.
1554 132 : bool DocumentFieldsManager::containsUpdatableFields()
1555 : {
1556 3928 : for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
1557 : {
1558 3814 : SwFieldType* pFldType = (*mpFldTypes)[i];
1559 3814 : SwIterator<SwFmtFld,SwFieldType> aIter(*pFldType);
1560 3814 : if (aIter.First())
1561 18 : return true;
1562 3796 : }
1563 114 : return false;
1564 : }
1565 :
1566 : /// Remove all unreferenced field types of a document
1567 6 : void DocumentFieldsManager::GCFieldTypes()
1568 : {
1569 12 : for( sal_uInt16 n = mpFldTypes->size(); n > INIT_FLDTYPES; )
1570 0 : if( !(*mpFldTypes)[ --n ]->GetDepends() )
1571 0 : RemoveFldType( n );
1572 6 : }
1573 :
1574 5052 : void DocumentFieldsManager::_InitFieldTypes() // is being called by the CTOR
1575 : {
1576 : // Field types
1577 5052 : mpFldTypes->push_back( new SwDateTimeFieldType(&m_rSwdoc) );
1578 5052 : mpFldTypes->push_back( new SwChapterFieldType );
1579 5052 : mpFldTypes->push_back( new SwPageNumberFieldType );
1580 5052 : mpFldTypes->push_back( new SwAuthorFieldType );
1581 5052 : mpFldTypes->push_back( new SwFileNameFieldType(&m_rSwdoc) );
1582 5052 : mpFldTypes->push_back( new SwDBNameFieldType(&m_rSwdoc) );
1583 5052 : mpFldTypes->push_back( new SwGetExpFieldType(&m_rSwdoc) );
1584 5052 : mpFldTypes->push_back( new SwGetRefFieldType( &m_rSwdoc ) );
1585 5052 : mpFldTypes->push_back( new SwHiddenTxtFieldType );
1586 5052 : mpFldTypes->push_back( new SwPostItFieldType(&m_rSwdoc) );
1587 5052 : mpFldTypes->push_back( new SwDocStatFieldType(&m_rSwdoc) );
1588 5052 : mpFldTypes->push_back( new SwDocInfoFieldType(&m_rSwdoc) );
1589 5052 : mpFldTypes->push_back( new SwInputFieldType( &m_rSwdoc ) );
1590 5052 : mpFldTypes->push_back( new SwTblFieldType( &m_rSwdoc ) );
1591 5052 : mpFldTypes->push_back( new SwMacroFieldType(&m_rSwdoc) );
1592 5052 : mpFldTypes->push_back( new SwHiddenParaFieldType );
1593 5052 : mpFldTypes->push_back( new SwDBNextSetFieldType );
1594 5052 : mpFldTypes->push_back( new SwDBNumSetFieldType );
1595 5052 : mpFldTypes->push_back( new SwDBSetNumberFieldType );
1596 5052 : mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
1597 5052 : mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
1598 5052 : mpFldTypes->push_back( new SwExtUserFieldType );
1599 5052 : mpFldTypes->push_back( new SwRefPageSetFieldType );
1600 5052 : mpFldTypes->push_back( new SwRefPageGetFieldType( &m_rSwdoc ) );
1601 5052 : mpFldTypes->push_back( new SwJumpEditFieldType( &m_rSwdoc ) );
1602 5052 : mpFldTypes->push_back( new SwScriptFieldType( &m_rSwdoc ) );
1603 5052 : mpFldTypes->push_back( new SwCombinedCharFieldType );
1604 5052 : mpFldTypes->push_back( new SwDropDownFieldType );
1605 :
1606 : // Types have to be at the end!
1607 : // We expect &m_rSwdoc in the InsertFldType!
1608 : // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
1609 : // lcl_sw3io_InSetExpField (sw3field.cxx) now also
1610 : mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
1611 5052 : SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
1612 : mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
1613 5052 : SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
1614 : mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
1615 5052 : SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
1616 : mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
1617 5052 : SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
1618 :
1619 : assert( mpFldTypes->size() == INIT_FLDTYPES );
1620 5052 : }
1621 :
1622 38 : void DocumentFieldsManager::ClearFieldTypes()
1623 : {
1624 114 : for(SwFldTypes::const_iterator it = mpFldTypes->begin() + INIT_FLDTYPES;
1625 76 : it != mpFldTypes->end(); ++it)
1626 0 : delete *it;
1627 38 : mpFldTypes->erase( mpFldTypes->begin() + INIT_FLDTYPES, mpFldTypes->end() );
1628 38 : }
1629 :
1630 0 : void DocumentFieldsManager::UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc )
1631 : {
1632 : #if !HAVE_FEATURE_DBCONNECTIVITY
1633 : (void) rDBFld;
1634 : (void) rCalc;
1635 : #else
1636 0 : SwDBManager* pMgr = m_rSwdoc.GetDBManager();
1637 :
1638 0 : sal_uInt16 nFldType = rDBFld.Which();
1639 :
1640 0 : bool bPar1 = rCalc.Calculate( rDBFld.GetPar1() ).GetBool();
1641 :
1642 0 : if( RES_DBNEXTSETFLD == nFldType )
1643 0 : ((SwDBNextSetField&)rDBFld).SetCondValid( bPar1 );
1644 : else
1645 0 : ((SwDBNumSetField&)rDBFld).SetCondValid( bPar1 );
1646 :
1647 0 : if( !rDBFld.GetRealDBData().sDataSource.isEmpty() )
1648 : {
1649 : // Edit a certain database
1650 0 : if( RES_DBNEXTSETFLD == nFldType )
1651 0 : ((SwDBNextSetField&)rDBFld).Evaluate(&m_rSwdoc);
1652 : else
1653 0 : ((SwDBNumSetField&)rDBFld).Evaluate(&m_rSwdoc);
1654 :
1655 0 : SwDBData aTmpDBData( rDBFld.GetDBData(&m_rSwdoc) );
1656 :
1657 0 : if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false ))
1658 : rCalc.VarChange( lcl_GetDBVarName( m_rSwdoc, rDBFld),
1659 0 : pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
1660 : }
1661 : else
1662 : {
1663 : OSL_FAIL("TODO: what should happen with unnamed DBFields?");
1664 : }
1665 : #endif
1666 0 : }
1667 :
1668 15135 : DocumentFieldsManager::~DocumentFieldsManager()
1669 : {
1670 5045 : delete mpUpdtFlds;
1671 5045 : delete mpFldTypes;
1672 10090 : }
1673 :
1674 270 : }
1675 :
1676 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|