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_rDoc 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 <calbck.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& rDBField )
61 : {
62 0 : SwDBData aDBData( rDBField.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 1 : static void lcl_CalcField( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpField& rSGEField,
81 : SwDBManager* pMgr )
82 : {
83 1 : const SwTextField* pTextField = rSGEField.GetTextField();
84 1 : if( !pTextField )
85 1 : return ;
86 :
87 1 : const SwField* pField = pTextField->GetFormatField().GetField();
88 1 : const sal_uInt16 nFieldWhich = pField->GetTyp()->Which();
89 :
90 1 : if( RES_SETEXPFLD == nFieldWhich )
91 : {
92 1 : SwSbxValue aValue;
93 1 : if( nsSwGetSetExpType::GSE_EXPR & pField->GetSubType() )
94 1 : aValue.PutDouble( static_cast<const SwSetExpField*>(pField)->GetValue() );
95 : else
96 : // Extension to calculate with Strings
97 0 : aValue.PutString( static_cast<const SwSetExpField*>(pField)->GetExpStr() );
98 :
99 : // set the new value in Calculator
100 1 : rCalc.VarChange( pField->GetTyp()->GetName(), aValue );
101 : }
102 0 : else if( pMgr )
103 : {
104 : #if !HAVE_FEATURE_DBCONNECTIVITY
105 : (void) rDoc;
106 : #else
107 0 : switch( nFieldWhich )
108 : {
109 : case RES_DBNUMSETFLD:
110 : {
111 0 : SwDBNumSetField* pDBField = const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField));
112 :
113 0 : SwDBData aDBData(pDBField->GetDBData(&rDoc));
114 :
115 0 : if( pDBField->IsCondValid() &&
116 0 : pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
117 : rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBField),
118 0 : pDBField->GetFormat() );
119 : }
120 0 : break;
121 : case RES_DBNEXTSETFLD:
122 : {
123 0 : SwDBNextSetField* pDBField = const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField));
124 0 : SwDBData aDBData(pDBField->GetDBData(&rDoc));
125 0 : if( !pDBField->IsCondValid() ||
126 0 : !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
127 0 : break;
128 :
129 0 : OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBField));
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 2958 : DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
146 : mbNewFieldLst(true),
147 2958 : mpUpdateFields( new SwDocUpdateField( &m_rDoc ) ),
148 0 : mpFieldTypes( new SwFieldTypes() ),
149 5916 : mnLockExpField( 0 )
150 : {
151 2958 : }
152 :
153 30016 : const SwFieldTypes* DocumentFieldsManager::GetFieldTypes() const
154 : {
155 30016 : return mpFieldTypes;
156 : }
157 :
158 : /** Insert field types
159 : *
160 : * @param rFieldTyp ???
161 : * @return Always returns a pointer to the type, if it's new or already added.
162 : */
163 251 : SwFieldType* DocumentFieldsManager::InsertFieldType(const SwFieldType &rFieldTyp)
164 : {
165 251 : const SwFieldTypes::size_type nSize = mpFieldTypes->size();
166 251 : const sal_uInt16 nFieldWhich = rFieldTyp.Which();
167 :
168 251 : SwFieldTypes::size_type i = INIT_FLDTYPES;
169 :
170 251 : switch( nFieldWhich )
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_rDoc, when
176 : //constructing string pools and when reading SetExp fields
177 84 : if( nsSwGetSetExpType::GSE_SEQ & static_cast<const SwSetExpFieldType&>(rFieldTyp).GetType() )
178 54 : i -= INIT_SEQ_FLDTYPES;
179 : // no break;
180 : case RES_DBFLD:
181 : case RES_USERFLD:
182 : case RES_DDEFLD:
183 : {
184 225 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
185 225 : OUString sFieldNm( rFieldTyp.GetName() );
186 634 : for( ; i < nSize; ++i )
187 1846 : if( nFieldWhich == (*mpFieldTypes)[i]->Which() &&
188 1802 : rSCmp.isEqual( sFieldNm, (*mpFieldTypes)[i]->GetName() ))
189 225 : return (*mpFieldTypes)[i];
190 : }
191 167 : break;
192 :
193 : case RES_AUTHORITY:
194 26 : for( ; i < nSize; ++i )
195 3 : if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
196 3 : return (*mpFieldTypes)[i];
197 23 : break;
198 :
199 : default:
200 0 : for( i = 0; i < nSize; ++i )
201 0 : if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
202 0 : return (*mpFieldTypes)[i];
203 : }
204 :
205 190 : SwFieldType* pNew = rFieldTyp.Copy();
206 190 : switch( nFieldWhich )
207 : {
208 : case RES_DDEFLD:
209 0 : static_cast<SwDDEFieldType*>(pNew)->SetDoc( &m_rDoc );
210 0 : break;
211 :
212 : case RES_DBFLD:
213 : case RES_TABLEFLD:
214 : case RES_DATETIMEFLD:
215 : case RES_GETEXPFLD:
216 109 : static_cast<SwValueFieldType*>(pNew)->SetDoc( &m_rDoc );
217 109 : break;
218 :
219 : case RES_USERFLD:
220 : case RES_SETEXPFLD:
221 58 : static_cast<SwValueFieldType*>(pNew)->SetDoc( &m_rDoc );
222 : // JP 29.07.96: Optionally prepare FieldList for Calculator:
223 58 : mpUpdateFields->InsertFieldType( *pNew );
224 58 : break;
225 : case RES_AUTHORITY :
226 23 : static_cast<SwAuthorityFieldType*>(pNew)->SetDoc( &m_rDoc );
227 23 : break;
228 : }
229 :
230 190 : mpFieldTypes->insert( mpFieldTypes->begin() + nSize, pNew );
231 190 : m_rDoc.getIDocumentState().SetModified();
232 :
233 190 : return (*mpFieldTypes)[ nSize ];
234 : }
235 :
236 : /// @returns the field type of the Doc
237 26727 : SwFieldType *DocumentFieldsManager::GetSysFieldType( const sal_uInt16 eWhich ) const
238 : {
239 241916 : for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
240 241916 : if( eWhich == (*mpFieldTypes)[i]->Which() )
241 26727 : return (*mpFieldTypes)[i];
242 0 : return 0;
243 : }
244 :
245 : /// Find first type with ResId and name
246 6321 : SwFieldType* DocumentFieldsManager::GetFieldType(
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 6321 : const SwFieldTypes::size_type nSize = mpFieldTypes->size();
253 6321 : SwFieldTypes::size_type i {0};
254 6321 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
255 :
256 6321 : switch( nResId )
257 : {
258 : case RES_SETEXPFLD:
259 : //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
260 : // Or we get doubble number circles!!
261 : //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rDoc, when
262 : //constructing string pools and when reading SetExp fields
263 3153 : i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES;
264 3153 : break;
265 :
266 : case RES_DBFLD:
267 : case RES_USERFLD:
268 : case RES_DDEFLD:
269 : case RES_AUTHORITY:
270 252 : i = INIT_FLDTYPES;
271 252 : break;
272 : }
273 :
274 6321 : SwFieldType* pRet = 0;
275 38447 : for( ; i < nSize; ++i )
276 : {
277 38176 : SwFieldType* pFieldType = (*mpFieldTypes)[i];
278 :
279 38176 : OUString aFieldName( pFieldType->GetName() );
280 38176 : if (bDbFieldMatching && nResId == RES_DBFLD) // #i51815#
281 2 : aFieldName = aFieldName.replace(DB_DELIM, '.');
282 :
283 49802 : if( nResId == pFieldType->Which() &&
284 11626 : rSCmp.isEqual( rName, aFieldName ))
285 : {
286 6050 : pRet = pFieldType;
287 6050 : break;
288 : }
289 32126 : }
290 6321 : return pRet;
291 : }
292 :
293 : /// Remove field type
294 108 : void DocumentFieldsManager::RemoveFieldType(size_t nField)
295 : {
296 : OSL_ENSURE( INIT_FLDTYPES <= nField, "don't remove InitFields" );
297 : /*
298 : * Dependent fields present -> ErrRaise
299 : */
300 108 : if(nField < mpFieldTypes->size())
301 : {
302 108 : SwFieldType* pTmp = (*mpFieldTypes)[nField];
303 :
304 : // JP 29.07.96: Optionally prepare FieldLst for Calculator
305 108 : sal_uInt16 nWhich = pTmp->Which();
306 108 : switch( nWhich )
307 : {
308 : case RES_SETEXPFLD:
309 : case RES_USERFLD:
310 0 : mpUpdateFields->RemoveFieldType( *pTmp );
311 : // no break;
312 : case RES_DDEFLD:
313 0 : if( pTmp->HasWriterListeners() && !m_rDoc.IsUsed( *pTmp ) )
314 : {
315 0 : if( RES_SETEXPFLD == nWhich )
316 0 : static_cast<SwSetExpFieldType*>(pTmp)->SetDeleted( true );
317 0 : else if( RES_USERFLD == nWhich )
318 0 : static_cast<SwUserFieldType*>(pTmp)->SetDeleted( true );
319 : else
320 0 : static_cast<SwDDEFieldType*>(pTmp)->SetDeleted( true );
321 0 : nWhich = 0;
322 : }
323 0 : break;
324 : }
325 :
326 108 : if( nWhich )
327 : {
328 : OSL_ENSURE( !pTmp->HasWriterListeners(), "Dependent fields present!" );
329 : // delete field type
330 0 : delete pTmp;
331 : }
332 108 : mpFieldTypes->erase( mpFieldTypes->begin() + nField );
333 108 : m_rDoc.getIDocumentState().SetModified();
334 : }
335 108 : }
336 :
337 : // All have to be re-evaluated.
338 220 : void DocumentFieldsManager::UpdateFields( SfxPoolItem *pNewHt, bool bCloseDB )
339 : {
340 : // Call Modify() for every field type,
341 : // dependent SwTextField get notified ...
342 :
343 7371 : for( auto pFieldType : *mpFieldTypes )
344 : {
345 7151 : switch( pFieldType->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 987 : break;
355 :
356 : case RES_DDEFLD:
357 : {
358 0 : if( !pNewHt )
359 : {
360 0 : SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
361 0 : pFieldType->ModifyNotification( 0, &aUpdateDDE );
362 : }
363 : else
364 0 : pFieldType->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 1543 : if( !pNewHt )
373 1543 : break;
374 : default:
375 4621 : pFieldType->ModifyNotification ( 0, pNewHt );
376 : }
377 : }
378 :
379 220 : if( !IsExpFieldsLocked() )
380 220 : UpdateExpFields( 0, false ); // update expression fields
381 :
382 : // Tables
383 220 : UpdateTableFields(pNewHt);
384 :
385 : // References
386 220 : UpdateRefFields(pNewHt);
387 220 : if( bCloseDB )
388 : {
389 : #if HAVE_FEATURE_DBCONNECTIVITY
390 1 : m_rDoc.GetDBManager()->CloseAll();
391 : #endif
392 : }
393 : // Only evaluate on full update
394 220 : m_rDoc.getIDocumentState().SetModified();
395 220 : }
396 :
397 0 : void DocumentFieldsManager::InsDeletedFieldType( SwFieldType& rFieldTyp )
398 : {
399 : // The FieldType was marked as deleted and removed from the array.
400 : // One has to look &m_rDoc 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 : const SwFieldTypes::size_type nSize = mpFieldTypes->size();
405 0 : const sal_uInt16 nFieldWhich = rFieldTyp.Which();
406 :
407 : OSL_ENSURE( RES_SETEXPFLD == nFieldWhich ||
408 : RES_USERFLD == nFieldWhich ||
409 : RES_DDEFLD == nFieldWhich, "Wrong FieldType" );
410 :
411 0 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
412 0 : const OUString& rFieldNm = rFieldTyp.GetName();
413 : SwFieldType* pFnd;
414 :
415 0 : for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < nSize; ++i )
416 0 : if( nFieldWhich == (pFnd = (*mpFieldTypes)[i])->Which() &&
417 0 : rSCmp.isEqual( rFieldNm, pFnd->GetName() ) )
418 : {
419 : // find new name
420 0 : SwFieldTypes::size_type nNum = 1;
421 : do {
422 0 : OUString sSrch = rFieldNm + OUString::number( nNum );
423 0 : for( i = INIT_FLDTYPES; i < nSize; ++i )
424 0 : if( nFieldWhich == (pFnd = (*mpFieldTypes)[i])->Which() &&
425 0 : rSCmp.isEqual( sSrch, pFnd->GetName() ) )
426 0 : break;
427 :
428 0 : if( i >= nSize ) // not found
429 : {
430 0 : const_cast<OUString&>(rFieldNm) = 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 : mpFieldTypes->insert( mpFieldTypes->begin() + nSize, &rFieldTyp );
440 0 : switch( nFieldWhich )
441 : {
442 : case RES_SETEXPFLD:
443 0 : static_cast<SwSetExpFieldType&>(rFieldTyp).SetDeleted( false );
444 0 : break;
445 : case RES_USERFLD:
446 0 : static_cast<SwUserFieldType&>(rFieldTyp).SetDeleted( false );
447 0 : break;
448 : case RES_DDEFLD:
449 0 : static_cast<SwDDEFieldType&>(rFieldTyp).SetDeleted( false );
450 0 : break;
451 0 : }
452 0 : }
453 :
454 246 : bool DocumentFieldsManager::PutValueToField(const SwPosition & rPos,
455 : const Any& rVal, sal_uInt16 nWhich)
456 : {
457 246 : Any aOldVal;
458 246 : SwField * pField = GetFieldAtPos(rPos);
459 :
460 286 : if (m_rDoc.GetIDocumentUndoRedo().DoesUndo() &&
461 40 : pField->QueryValue(aOldVal, nWhich))
462 : {
463 40 : SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich));
464 40 : m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
465 : }
466 :
467 246 : return pField->PutValue(rVal, nWhich);
468 : }
469 :
470 0 : bool DocumentFieldsManager::UpdateField(SwTextField * pDstTextField, SwField & rSrcField,
471 : SwMsgPoolItem * pMsgHint,
472 : bool bUpdateFields)
473 : {
474 : OSL_ENSURE(pDstTextField, "no field to update!");
475 :
476 0 : bool bTableSelBreak = false;
477 :
478 0 : SwFormatField * pDstFormatField = const_cast<SwFormatField*>(&pDstTextField->GetFormatField());
479 0 : SwField * pDstField = pDstFormatField->GetField();
480 0 : sal_uInt16 nFieldWhich = rSrcField.GetTyp()->Which();
481 0 : SwNodeIndex aTableNdIdx(pDstTextField->GetTextNode());
482 :
483 0 : if (pDstField->GetTyp()->Which() ==
484 0 : rSrcField.GetTyp()->Which())
485 : {
486 0 : if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
487 : {
488 0 : SwPosition aPosition( pDstTextField->GetTextNode() );
489 0 : aPosition.nContent = pDstTextField->GetStart();
490 :
491 0 : SwUndo *const pUndo( new SwUndoFieldFromDoc( aPosition, *pDstField, rSrcField, pMsgHint, bUpdateFields) );
492 0 : m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
493 : }
494 :
495 0 : SwField * pNewField = rSrcField.CopyField();
496 0 : pDstFormatField->SetField(pNewField);
497 :
498 0 : switch( nFieldWhich )
499 : {
500 : case RES_SETEXPFLD:
501 : case RES_GETEXPFLD:
502 : case RES_HIDDENTXTFLD:
503 : case RES_HIDDENPARAFLD:
504 0 : UpdateExpFields( pDstTextField, true );
505 0 : break;
506 :
507 : case RES_TABLEFLD:
508 : {
509 : const SwTableNode* pTableNd =
510 0 : m_rDoc.IsIdxInTable(aTableNdIdx);
511 0 : if( pTableNd )
512 : {
513 : SwTableFormulaUpdate aTableUpdate( &pTableNd->
514 0 : GetTable() );
515 0 : if (bUpdateFields)
516 0 : UpdateTableFields( &aTableUpdate );
517 : else
518 0 : pNewField->GetTyp()->ModifyNotification(0, &aTableUpdate);
519 :
520 0 : if (! bUpdateFields)
521 0 : bTableSelBreak = true;
522 : }
523 : }
524 0 : break;
525 :
526 : case RES_MACROFLD:
527 0 : if( bUpdateFields && pDstTextField->GetpTextNode() )
528 0 : (pDstTextField->GetpTextNode())->
529 0 : ModifyNotification( 0, pDstFormatField );
530 0 : break;
531 :
532 : case RES_DBNAMEFLD:
533 : case RES_DBNEXTSETFLD:
534 : case RES_DBNUMSETFLD:
535 : case RES_DBSETNUMBERFLD:
536 0 : m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
537 0 : pNewField->GetTyp()->UpdateFields();
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* pDBField = static_cast<SwDBField*>(pNewField);
547 0 : if (pDBField->IsInitialized())
548 0 : pDBField->ChgValue( pDBField->GetValue(), true );
549 :
550 0 : pDBField->ClearInitialized();
551 0 : pDBField->InitContent();
552 : }
553 : #endif
554 : // no break;
555 :
556 : default:
557 0 : pDstFormatField->ModifyNotification( 0, pMsgHint );
558 : }
559 :
560 : // The fields we can calculate here are being triggered for an update
561 : // here explicitly.
562 0 : if( nFieldWhich == RES_USERFLD )
563 0 : UpdateUsrFields();
564 : }
565 :
566 0 : return bTableSelBreak;
567 : }
568 :
569 : /// Update reference and table fields
570 425 : void DocumentFieldsManager::UpdateRefFields( SfxPoolItem* pHt )
571 : {
572 14157 : for( auto pFieldType : *mpFieldTypes )
573 13732 : if( RES_GETREFFLD == pFieldType->Which() )
574 425 : pFieldType->ModifyNotification( 0, pHt );
575 425 : }
576 :
577 1320 : void DocumentFieldsManager::UpdateTableFields( SfxPoolItem* pHt )
578 : {
579 : OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE == pHt->Which(),
580 : "What MessageItem is &m_rDoc?" );
581 :
582 1320 : SwFieldType* pFieldType(0);
583 :
584 18480 : for (auto pFieldTypeTmp : *mpFieldTypes)
585 : {
586 18480 : if( RES_TABLEFLD == pFieldTypeTmp->Which() )
587 : {
588 1320 : SwTableFormulaUpdate* pUpdateField = 0;
589 1320 : if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
590 1013 : pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
591 :
592 1320 : SwIterator<SwFormatField,SwFieldType> aIter( *pFieldTypeTmp );
593 1320 : for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
594 : {
595 0 : if( pFormatField->GetTextField() )
596 : {
597 0 : SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField());
598 :
599 0 : if( pUpdateField )
600 : {
601 : // table where &m_rDoc field is located
602 : const SwTableNode* pTableNd;
603 0 : const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
604 0 : if( !rTextNd.GetNodes().IsDocNodes() ||
605 0 : 0 == ( pTableNd = rTextNd.FindTableNode() ) )
606 0 : continue;
607 :
608 0 : switch( pUpdateField->eFlags )
609 : {
610 : case TBL_CALC:
611 : // re-set the value flag
612 : // JP 17.06.96: internal representation of all formulas
613 : // (reference to other table!!!)
614 0 : if( nsSwExtendedSubType::SUB_CMD & pField->GetSubType() )
615 0 : pField->PtrToBoxNm( pUpdateField->pTable );
616 : else
617 0 : pField->ChgValid( false );
618 0 : break;
619 : case TBL_BOXNAME:
620 : // is &m_rDoc the wanted table?
621 0 : if( &pTableNd->GetTable() == pUpdateField->pTable )
622 : // to the external representation
623 0 : pField->PtrToBoxNm( pUpdateField->pTable );
624 0 : break;
625 : case TBL_BOXPTR:
626 : // to the internal representation
627 : // JP 17.06.96: internal representation on all formulas
628 : // (reference to other table!!!)
629 0 : pField->BoxNmToPtr( pUpdateField->pTable );
630 0 : break;
631 : case TBL_RELBOXNAME:
632 : // is &m_rDoc the wanted table?
633 0 : if( &pTableNd->GetTable() == pUpdateField->pTable )
634 : // to the relative representation
635 0 : pField->ToRelBoxNm( pUpdateField->pTable );
636 0 : break;
637 : default:
638 0 : break;
639 : }
640 : }
641 : else
642 : // reset the value flag for all
643 0 : pField->ChgValid( false );
644 : }
645 : }
646 1320 : pFieldType = pFieldTypeTmp;
647 1320 : break;
648 : }
649 : }
650 :
651 : // process all table box formulas
652 : const SfxPoolItem* pItem;
653 1320 : sal_uInt32 nMaxItems = m_rDoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
654 1320 : for (sal_uInt32 i = 0; i < nMaxItems; ++i)
655 : {
656 0 : if( 0 != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
657 0 : static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() )
658 : {
659 0 : const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem))->ChangeState( pHt );
660 : }
661 : }
662 :
663 : // all fields/boxes are now invalid, so we can start to calculate
664 2333 : if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
665 1013 : TBL_CALC != static_cast<SwTableFormulaUpdate*>(pHt)->eFlags ))
666 2028 : return ;
667 :
668 612 : SwCalc* pCalc = 0;
669 :
670 612 : if( pFieldType )
671 : {
672 612 : SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
673 612 : for( SwFormatField* pFormatField = aIter.Last(); pFormatField; pFormatField = aIter.Previous() )
674 : {
675 : // start calculation at the end
676 : // new fields are inserted at the beginning of the modify chain
677 : // that gives faster calculation on import
678 : // mba: do we really need &m_rDoc "optimization"? Is it still valid?
679 : SwTableField* pField;
680 0 : if( !pFormatField->GetTextField() || (nsSwExtendedSubType::SUB_CMD &
681 0 : (pField = static_cast<SwTableField*>(pFormatField->GetField()))->GetSubType() ))
682 0 : continue;
683 :
684 : // needs to be recalculated
685 0 : if( !pField->IsValid() )
686 : {
687 : // table where &m_rDoc field is located
688 0 : const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
689 0 : if( !rTextNd.GetNodes().IsDocNodes() )
690 0 : continue;
691 0 : const SwTableNode* pTableNd = rTextNd.FindTableNode();
692 0 : if( !pTableNd )
693 0 : continue;
694 :
695 : // if &m_rDoc field is not in the to-be-updated table, skip it
696 0 : if( pHt && &pTableNd->GetTable() !=
697 : static_cast<SwTableFormulaUpdate*>(pHt)->pTable )
698 0 : continue;
699 :
700 0 : if( !pCalc )
701 0 : pCalc = new SwCalc( m_rDoc );
702 :
703 : // get the values of all SetExpression fields that are valid
704 : // until the table
705 0 : SwFrm* pFrm = 0;
706 0 : if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
707 : {
708 : // is in the special section, that's expensive!
709 0 : Point aPt; // return the first frame of the layout - Tab.Headline!!
710 0 : pFrm = rTextNd.getLayoutFrm( m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt );
711 0 : if( pFrm )
712 : {
713 0 : SwPosition aPos( *pTableNd );
714 0 : if( GetBodyTextNode( m_rDoc, aPos, *pFrm ) )
715 : FieldsToCalc( *pCalc, _SetGetExpField(
716 0 : aPos.nNode, pFormatField->GetTextField(),
717 0 : &aPos.nContent ));
718 : else
719 0 : pFrm = 0;
720 : }
721 : }
722 0 : if( !pFrm )
723 : {
724 : // create index to determine the TextNode
725 0 : SwNodeIndex aIdx( rTextNd );
726 : FieldsToCalc( *pCalc,
727 0 : _SetGetExpField( aIdx, pFormatField->GetTextField() ));
728 : }
729 :
730 0 : SwTableCalcPara aPara( *pCalc, pTableNd->GetTable() );
731 0 : pField->CalcField( aPara );
732 0 : if( aPara.IsStackOverflow() )
733 : {
734 0 : bool const bResult = aPara.CalcWithStackOverflow();
735 0 : if (bResult)
736 : {
737 0 : pField->CalcField( aPara );
738 : }
739 : OSL_ENSURE(bResult,
740 : "the chained formula could no be calculated");
741 : }
742 0 : pCalc->SetCalcError( CALC_NOERR );
743 : }
744 0 : pFormatField->ModifyNotification( 0, pHt );
745 612 : }
746 : }
747 :
748 : // calculate the formula at the boxes
749 612 : for (sal_uInt32 i = 0; i < nMaxItems; ++i )
750 : {
751 0 : if( 0 != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
752 0 : static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() &&
753 0 : !static_cast<const SwTableBoxFormula*>(pItem)->IsValid() )
754 : {
755 0 : SwTableBoxFormula* pFormula = const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem));
756 0 : SwTableBox* pBox = pFormula->GetTableBox();
757 0 : if( pBox && pBox->GetSttNd() &&
758 0 : pBox->GetSttNd()->GetNodes().IsDocNodes() )
759 : {
760 0 : const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode();
761 0 : if( !pHt || &pTableNd->GetTable() ==
762 : static_cast<SwTableFormulaUpdate*>(pHt)->pTable )
763 : {
764 : double nValue;
765 0 : if( !pCalc )
766 0 : pCalc = new SwCalc( m_rDoc );
767 :
768 : // get the values of all SetExpression fields that are valid
769 : // until the table
770 0 : SwFrm* pFrm = 0;
771 0 : if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
772 : {
773 : // is in the special section, that's expensive!
774 0 : Point aPt; // return the first frame of the layout - Tab.Headline!!
775 0 : SwNodeIndex aCNdIdx( *pTableNd, +2 );
776 0 : SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode();
777 0 : if( !pCNd )
778 0 : pCNd = m_rDoc.GetNodes().GoNext( &aCNdIdx );
779 :
780 0 : if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt )) )
781 : {
782 0 : SwPosition aPos( *pCNd );
783 0 : if( GetBodyTextNode( m_rDoc, aPos, *pFrm ) )
784 0 : FieldsToCalc( *pCalc, _SetGetExpField( aPos.nNode ));
785 : else
786 0 : pFrm = 0;
787 0 : }
788 : }
789 0 : if( !pFrm )
790 : {
791 : // create index to determine the TextNode
792 0 : SwNodeIndex aIdx( *pTableNd );
793 0 : FieldsToCalc( *pCalc, _SetGetExpField( aIdx ));
794 : }
795 :
796 0 : SwTableCalcPara aPara( *pCalc, pTableNd->GetTable() );
797 0 : pFormula->Calc( aPara, nValue );
798 :
799 0 : if( aPara.IsStackOverflow() )
800 : {
801 0 : bool const bResult = aPara.CalcWithStackOverflow();
802 0 : if (bResult)
803 : {
804 0 : pFormula->Calc( aPara, nValue );
805 : }
806 : OSL_ENSURE(bResult,
807 : "the chained formula could no be calculated");
808 : }
809 :
810 0 : SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
811 0 : SfxItemSet aTmp( m_rDoc.GetAttrPool(),
812 0 : RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
813 :
814 0 : if( pCalc->IsCalcError() )
815 0 : nValue = DBL_MAX;
816 0 : aTmp.Put( SwTableBoxValue( nValue ));
817 0 : if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
818 0 : aTmp.Put( SwTableBoxNumFormat( 0 ));
819 0 : pFormat->SetFormatAttr( aTmp );
820 :
821 0 : pCalc->SetCalcError( CALC_NOERR );
822 : }
823 : }
824 : }
825 : }
826 :
827 612 : delete pCalc;
828 : }
829 :
830 7198 : void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUpdRefFields )
831 : {
832 7198 : if( IsExpFieldsLocked() || m_rDoc.IsInReading() )
833 13918 : return;
834 :
835 405 : bool bOldInUpdateFields = mpUpdateFields->IsInUpdateFields();
836 405 : mpUpdateFields->SetInUpdateFields( true );
837 :
838 405 : mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
839 405 : mbNewFieldLst = false;
840 :
841 405 : if( mpUpdateFields->GetSortLst()->empty() )
842 : {
843 332 : if( bUpdRefFields )
844 94 : UpdateRefFields(NULL);
845 :
846 332 : mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
847 332 : mpUpdateFields->SetFieldsDirty( false );
848 332 : return ;
849 : }
850 :
851 : sal_uInt16 nWhich;
852 :
853 : // Hash table for all string replacements is filled on-the-fly.
854 : // Try to fabricate an uneven number.
855 73 : const SwFieldTypes::size_type nHashSize {(( mpFieldTypes->size() / 7 ) + 1 ) * 7};
856 73 : const sal_uInt16 nStrFormatCnt = static_cast<sal_uInt16>(nHashSize);
857 : OSL_ENSURE( nStrFormatCnt == nHashSize, "Downcasting to sal_uInt16 lost information!" );
858 73 : SwHash** pHashStrTable = new SwHash*[ nStrFormatCnt ];
859 73 : memset( pHashStrTable, 0, sizeof( _HashStr* ) * nStrFormatCnt );
860 :
861 : {
862 : const SwFieldType* pFieldType;
863 : // process separately:
864 2612 : for( auto n = mpFieldTypes->size(); n; )
865 2466 : switch( ( pFieldType = (*mpFieldTypes)[ --n ] )->Which() )
866 : {
867 : case RES_USERFLD:
868 : {
869 : // Entry present?
870 : sal_uInt16 nPos;
871 3 : const OUString& rNm = pFieldType->GetName();
872 6 : OUString sExpand(const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0));
873 3 : SwHash* pFnd = Find( rNm, pHashStrTable, nStrFormatCnt, &nPos );
874 3 : if( pFnd )
875 : // modify entry in the hash table
876 0 : static_cast<_HashStr*>(pFnd)->aSetStr = sExpand;
877 : else
878 : // insert the new entry
879 3 : *(pHashStrTable + nPos ) = new _HashStr( rNm, sExpand,
880 9 : static_cast<_HashStr*>(*(pHashStrTable + nPos)) );
881 : }
882 3 : break;
883 : case RES_SETEXPFLD:
884 298 : const_cast<SwSetExpFieldType*>(static_cast<const SwSetExpFieldType*>(pFieldType))->SetOutlineChgNd( 0 );
885 298 : break;
886 : }
887 : }
888 :
889 : // The array is filled with all fields; start calculation.
890 73 : SwCalc aCalc( m_rDoc );
891 :
892 : #if HAVE_FEATURE_DBCONNECTIVITY
893 146 : OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
894 :
895 : // already set the current record number
896 73 : SwDBManager* pMgr = m_rDoc.GetDBManager();
897 73 : pMgr->CloseAll( false );
898 :
899 146 : SvtSysLocale aSysLocale;
900 73 : const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
901 73 : const long nLang = pLclData->getLanguageTag().getLanguageType();
902 73 : bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.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 73 : int nShownSections = 0;
907 209 : for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != mpUpdateFields->GetSortLst()->end(); ++it )
908 : {
909 136 : SwSection* pSect = const_cast<SwSection*>((*it)->GetSection());
910 136 : if ( pSect && !pSect->IsCondHidden())
911 5 : nShownSections++;
912 : }
913 :
914 146 : OUString aNew;
915 209 : for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != mpUpdateFields->GetSortLst()->end(); ++it )
916 : {
917 136 : SwSection* pSect = const_cast<SwSection*>((*it)->GetSection());
918 136 : if( pSect )
919 : {
920 :
921 : SwSbxValue aValue = aCalc.Calculate(
922 5 : pSect->GetCondition() );
923 5 : if(!aValue.IsVoidValue())
924 : {
925 : // Do we want to hide this one?
926 5 : bool bHide = aValue.GetBool();
927 5 : if (bHide && !pSect->IsCondHidden())
928 : {
929 : // This section will be hidden, but it wasn't before
930 4 : if (nShownSections == 1)
931 : {
932 : // Is the last node part of a section?
933 4 : SwPaM aPam(m_rDoc.GetNodes());
934 4 : aPam.Move(fnMoveForward, fnGoDoc);
935 4 : 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 2 : OUString aCond("0");
939 2 : pSect->SetCondition(aCond);
940 2 : bHide = false;
941 4 : }
942 : }
943 4 : nShownSections--;
944 : }
945 5 : pSect->SetCondHidden( bHide );
946 : }
947 5 : continue;
948 : }
949 :
950 131 : SwTextField* pTextField = const_cast<SwTextField*>((*it)->GetTextField());
951 131 : if( !pTextField )
952 : {
953 : OSL_ENSURE( false, "what's wrong now'" );
954 0 : continue;
955 : }
956 :
957 131 : SwFormatField* pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
958 131 : const SwField* pField = pFormatField->GetField();
959 :
960 131 : switch( nWhich = pField->GetTyp()->Which() )
961 : {
962 : case RES_HIDDENTXTFLD:
963 : {
964 0 : SwHiddenTextField* pHField = const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField));
965 0 : SwSbxValue aValue = aCalc.Calculate( pHField->GetPar1() );
966 0 : bool bValue = !aValue.GetBool();
967 0 : if(!aValue.IsVoidValue())
968 : {
969 0 : pHField->SetValue( bValue );
970 : // evaluate field
971 0 : pHField->Evaluate(&m_rDoc);
972 0 : }
973 : }
974 0 : break;
975 : case RES_HIDDENPARAFLD:
976 : {
977 0 : SwHiddenParaField* pHPField = const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField));
978 0 : SwSbxValue aValue = aCalc.Calculate( pHPField->GetPar1() );
979 0 : bool bValue = aValue.GetBool();
980 0 : if(!aValue.IsVoidValue())
981 0 : pHPField->SetHidden( bValue );
982 : }
983 0 : break;
984 : case RES_DBSETNUMBERFLD:
985 : #if HAVE_FEATURE_DBCONNECTIVITY
986 : {
987 0 : const_cast<SwDBSetNumberField*>(static_cast<const SwDBSetNumberField*>(pField))->Evaluate(&m_rDoc);
988 0 : aCalc.VarChange( sDBNumNm, static_cast<const SwDBSetNumberField*>(pField)->GetSetNumber());
989 : }
990 : #endif
991 0 : break;
992 : case RES_DBNEXTSETFLD:
993 : case RES_DBNUMSETFLD:
994 : #if HAVE_FEATURE_DBCONNECTIVITY
995 : {
996 0 : UpdateDBNumFields( *const_cast<SwDBNameInfField*>(static_cast<const SwDBNameInfField*>(pField)), aCalc );
997 0 : if( bCanFill )
998 0 : bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, true, aCalc );
999 : }
1000 : #endif
1001 0 : break;
1002 : case RES_DBFLD:
1003 : {
1004 : #if HAVE_FEATURE_DBCONNECTIVITY
1005 : // evaluate field
1006 118 : const_cast<SwDBField*>(static_cast<const SwDBField*>(pField))->Evaluate();
1007 :
1008 118 : SwDBData aTmpDBData(static_cast<const SwDBField*>(pField)->GetDBData());
1009 :
1010 118 : if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
1011 60 : aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
1012 :
1013 236 : const OUString& rName = pField->GetTyp()->GetName();
1014 :
1015 : // Add entry to hash table
1016 : // Entry present?
1017 : sal_uInt16 nPos;
1018 118 : SwHash* pFnd = Find( rName, pHashStrTable, nStrFormatCnt, &nPos );
1019 236 : OUString const value(pField->ExpandField(m_rDoc.IsClipBoard()));
1020 118 : if( pFnd )
1021 : {
1022 : // Modify entry in the hash table
1023 3 : static_cast<_HashStr*>(pFnd)->aSetStr = value;
1024 : }
1025 : else
1026 : {
1027 : // insert new entry
1028 115 : *(pHashStrTable + nPos ) = new _HashStr( rName,
1029 230 : value, static_cast<_HashStr *>(*(pHashStrTable + nPos)));
1030 118 : }
1031 : #endif
1032 : }
1033 118 : break;
1034 : case RES_GETEXPFLD:
1035 : case RES_SETEXPFLD:
1036 : {
1037 13 : if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() ) // replace String
1038 : {
1039 1 : if( RES_GETEXPFLD == nWhich )
1040 : {
1041 0 : SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1042 :
1043 0 : if( (!pUpdateField || pUpdateField == pTextField )
1044 0 : && pGField->IsInBodyText() )
1045 : {
1046 0 : aNew = LookString( pHashStrTable, nStrFormatCnt,
1047 0 : pGField->GetFormula() );
1048 0 : pGField->ChgExpStr( aNew );
1049 : }
1050 : }
1051 : else
1052 : {
1053 1 : SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1054 : // is the "formula" a field?
1055 3 : aNew = LookString( pHashStrTable, nStrFormatCnt,
1056 2 : pSField->GetFormula() );
1057 :
1058 1 : if( aNew.isEmpty() ) // nothing found then the formula is the new value
1059 1 : aNew = pSField->GetFormula();
1060 :
1061 : // only update one field
1062 1 : if( !pUpdateField || pUpdateField == pTextField )
1063 1 : pSField->ChgExpStr( aNew );
1064 :
1065 : // lookup the field's name
1066 1 : aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1067 : // Entry present?
1068 : sal_uInt16 nPos;
1069 1 : SwHash* pFnd = Find( aNew, pHashStrTable, nStrFormatCnt, &nPos );
1070 1 : if( pFnd )
1071 : // Modify entry in the hash table
1072 0 : static_cast<_HashStr*>(pFnd)->aSetStr = pSField->GetExpStr();
1073 : else
1074 : // insert new entry
1075 1 : *(pHashStrTable + nPos ) = pFnd = new _HashStr( aNew,
1076 : pSField->GetExpStr(),
1077 1 : static_cast<_HashStr*>(*(pHashStrTable + nPos) ));
1078 :
1079 : // Extension for calculation with Strings
1080 1 : SwSbxValue aValue;
1081 1 : aValue.PutString( static_cast<_HashStr*>(pFnd)->aSetStr );
1082 1 : aCalc.VarChange( aNew, aValue );
1083 : }
1084 : }
1085 : else // recalculate formula
1086 : {
1087 12 : if( RES_GETEXPFLD == nWhich )
1088 : {
1089 0 : SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1090 :
1091 0 : if( (!pUpdateField || pUpdateField == pTextField )
1092 0 : && pGField->IsInBodyText() )
1093 : {
1094 : SwSbxValue aValue = aCalc.Calculate(
1095 0 : pGField->GetFormula());
1096 0 : if(!aValue.IsVoidValue())
1097 0 : pGField->SetValue(aValue.GetDouble() );
1098 : }
1099 : }
1100 : else
1101 : {
1102 12 : SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1103 12 : SwSetExpFieldType* pSFieldTyp = static_cast<SwSetExpFieldType*>(pField->GetTyp());
1104 12 : aNew = pSFieldTyp->GetName();
1105 :
1106 12 : SwNode* pSeqNd = 0;
1107 :
1108 12 : if( pSField->IsSequenceField() )
1109 : {
1110 9 : const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
1111 9 : if( MAXLEVEL > nLvl )
1112 : {
1113 : // test if the Number needs to be updated
1114 3 : pSeqNd = m_rDoc.GetNodes()[ (*it)->GetNode() ];
1115 :
1116 : const SwTextNode* pOutlNd = pSeqNd->
1117 3 : FindOutlineNodeOfLevel( nLvl );
1118 3 : if( pSFieldTyp->GetOutlineChgNd() != pOutlNd )
1119 : {
1120 1 : pSFieldTyp->SetOutlineChgNd( pOutlNd );
1121 1 : aCalc.VarChange( aNew, 0 );
1122 : }
1123 : }
1124 : }
1125 :
1126 12 : aNew += "=";
1127 12 : aNew += pSField->GetFormula();
1128 :
1129 12 : SwSbxValue aValue = aCalc.Calculate( aNew );
1130 12 : double nErg = aValue.GetDouble();
1131 : // only update one field
1132 12 : if( !aValue.IsVoidValue() && (!pUpdateField || pUpdateField == pTextField) )
1133 : {
1134 12 : pSField->SetValue( nErg );
1135 :
1136 12 : if( pSeqNd )
1137 3 : pSFieldTyp->SetChapter( *pSField, *pSeqNd );
1138 12 : }
1139 : }
1140 : }
1141 : }
1142 : } // switch
1143 :
1144 131 : pFormatField->ModifyNotification( 0, 0 ); // trigger formatting
1145 :
1146 131 : if( pUpdateField == pTextField ) // if only &m_rDoc one is updated
1147 : {
1148 0 : if( RES_GETEXPFLD == nWhich || // only GetField or
1149 0 : RES_HIDDENTXTFLD == nWhich || // HiddenText?
1150 : RES_HIDDENPARAFLD == nWhich) // HiddenParaField?
1151 : break; // quit
1152 0 : pUpdateField = 0; // update all from here on
1153 : }
1154 : }
1155 :
1156 : #if HAVE_FEATURE_DBCONNECTIVITY
1157 73 : pMgr->CloseAll(false);
1158 : #endif
1159 : // delete hash table
1160 73 : ::DeleteHashTable( pHashStrTable, nStrFormatCnt );
1161 :
1162 : // update reference fields
1163 73 : if( bUpdRefFields )
1164 4 : UpdateRefFields(NULL);
1165 :
1166 73 : mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
1167 146 : mpUpdateFields->SetFieldsDirty( false );
1168 : }
1169 :
1170 : /// Insert field type that was marked as deleted
1171 0 : void DocumentFieldsManager::UpdateUsrFields()
1172 : {
1173 0 : SwCalc* pCalc = 0;
1174 : const SwFieldType* pFieldType;
1175 0 : for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < mpFieldTypes->size(); ++i )
1176 0 : if( RES_USERFLD == ( pFieldType = (*mpFieldTypes)[i] )->Which() )
1177 : {
1178 0 : if( !pCalc )
1179 0 : pCalc = new SwCalc( m_rDoc );
1180 0 : const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->GetValue( *pCalc );
1181 : }
1182 :
1183 0 : if( pCalc )
1184 : {
1185 0 : delete pCalc;
1186 0 : m_rDoc.getIDocumentState().SetModified();
1187 : }
1188 0 : }
1189 :
1190 4010 : void DocumentFieldsManager::UpdatePageFields( SfxPoolItem* pMsgHint )
1191 : {
1192 132330 : for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
1193 : {
1194 128320 : SwFieldType* pFieldType = (*mpFieldTypes)[ i ];
1195 128320 : switch( pFieldType->Which() )
1196 : {
1197 : case RES_PAGENUMBERFLD:
1198 : case RES_CHAPTERFLD:
1199 : case RES_GETEXPFLD:
1200 : case RES_REFPAGEGETFLD:
1201 16040 : pFieldType->ModifyNotification( 0, pMsgHint );
1202 16040 : break;
1203 : case RES_DOCSTATFLD:
1204 4010 : pFieldType->ModifyNotification( 0, 0 );
1205 4010 : break;
1206 : }
1207 : }
1208 4010 : SetNewFieldLst(true);
1209 4010 : }
1210 :
1211 3014 : void DocumentFieldsManager::LockExpFields()
1212 : {
1213 3014 : ++mnLockExpField;
1214 3014 : }
1215 :
1216 3013 : void DocumentFieldsManager::UnlockExpFields()
1217 : {
1218 : assert(mnLockExpField != 0);
1219 3013 : if( mnLockExpField )
1220 3013 : --mnLockExpField;
1221 3013 : }
1222 :
1223 7515 : bool DocumentFieldsManager::IsExpFieldsLocked() const
1224 : {
1225 7515 : return 0 != mnLockExpField;
1226 : }
1227 :
1228 31013 : SwDocUpdateField& DocumentFieldsManager::GetUpdateFields() const
1229 : {
1230 31013 : return *mpUpdateFields;
1231 : }
1232 :
1233 13354 : bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
1234 : {
1235 : // See if the supplied nodes actually contain fields.
1236 : // If they don't, the flag doesn't need to be changed.
1237 13354 : bool bFieldsFnd = false;
1238 13354 : if( b && pChk && !GetUpdateFields().IsFieldsDirty() && !m_rDoc.IsInDtor()
1239 : // ?? what's up with Undo, this is also wanted there!
1240 : /*&& &pChk->GetNodes() == &GetNodes()*/ )
1241 : {
1242 9137 : b = false;
1243 9137 : if( !nLen )
1244 0 : ++nLen;
1245 9137 : sal_uLong nStt = pChk->GetIndex();
1246 9137 : const SwNodes& rNds = pChk->GetNodes();
1247 27244 : while( nLen-- )
1248 : {
1249 9146 : const SwTextNode* pTNd = rNds[ nStt++ ]->GetTextNode();
1250 9146 : if( pTNd )
1251 : {
1252 9145 : if( pTNd->GetAttrOutlineLevel() != 0 )
1253 : // update chapter fields
1254 0 : b = true;
1255 9145 : else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
1256 : {
1257 661 : const size_t nEnd = pTNd->GetSwpHints().Count();
1258 1467 : for( size_t n = 0 ; n < nEnd; ++n )
1259 : {
1260 982 : const SwTextAttr* pAttr = pTNd->GetSwpHints()[ n ];
1261 982 : if ( pAttr->Which() == RES_TXTATR_FIELD )
1262 : {
1263 176 : b = true;
1264 176 : break;
1265 : }
1266 : }
1267 : }
1268 :
1269 9145 : if( b )
1270 176 : break;
1271 : }
1272 : }
1273 9137 : bFieldsFnd = b;
1274 : }
1275 13354 : GetUpdateFields().SetFieldsDirty( b );
1276 13354 : return bFieldsFnd;
1277 : }
1278 :
1279 58 : void DocumentFieldsManager::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
1280 : {
1281 58 : bool bIsModified = m_rDoc.getIDocumentState().IsModified();
1282 :
1283 : sal_Int32 nDate;
1284 : sal_Int64 nTime;
1285 58 : if( pNewDateTime )
1286 : {
1287 0 : nDate = pNewDateTime->GetDate();
1288 0 : nTime = pNewDateTime->GetTime();
1289 : }
1290 : else
1291 : {
1292 58 : nDate = Date( Date::SYSTEM ).GetDate();
1293 58 : nTime = tools::Time( tools::Time::SYSTEM ).GetTime();
1294 : }
1295 :
1296 : sal_uInt16 aTypes[5] = {
1297 : /*0*/ RES_DOCINFOFLD,
1298 : /*1*/ RES_AUTHORFLD,
1299 : /*2*/ RES_EXTUSERFLD,
1300 : /*3*/ RES_FILENAMEFLD,
1301 58 : /*4*/ RES_DATETIMEFLD }; // MUST be at the end!
1302 :
1303 58 : sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0;
1304 :
1305 348 : for( ; nStt < 5; ++nStt )
1306 : {
1307 290 : SwFieldType* pFieldType = GetSysFieldType( aTypes[ nStt ] );
1308 290 : SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
1309 294 : for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
1310 : {
1311 4 : if( pFormatField && pFormatField->GetTextField() )
1312 : {
1313 4 : bool bChgd = false;
1314 4 : switch( aTypes[ nStt ] )
1315 : {
1316 : case RES_DOCINFOFLD:
1317 0 : if( static_cast<SwDocInfoField*>(pFormatField->GetField())->IsFixed() )
1318 : {
1319 0 : bChgd = true;
1320 0 : SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pFormatField->GetField());
1321 : pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(
1322 0 : pDocInfField->GetTyp())->Expand(
1323 0 : pDocInfField->GetSubType(),
1324 : pDocInfField->GetFormat(),
1325 0 : pDocInfField->GetLanguage(),
1326 0 : pDocInfField->GetName() ) );
1327 : }
1328 0 : break;
1329 :
1330 : case RES_AUTHORFLD:
1331 0 : if( static_cast<SwAuthorField*>(pFormatField->GetField())->IsFixed() )
1332 : {
1333 0 : bChgd = true;
1334 0 : SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pFormatField->GetField());
1335 0 : pAuthorField->SetExpansion( SwAuthorFieldType::Expand( pAuthorField->GetFormat() ) );
1336 : }
1337 0 : break;
1338 :
1339 : case RES_EXTUSERFLD:
1340 0 : if( static_cast<SwExtUserField*>(pFormatField->GetField())->IsFixed() )
1341 : {
1342 0 : bChgd = true;
1343 0 : SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pFormatField->GetField());
1344 : pExtUserField->SetExpansion( SwExtUserFieldType::Expand(
1345 0 : pExtUserField->GetSubType(),
1346 0 : pExtUserField->GetFormat()));
1347 : }
1348 0 : break;
1349 :
1350 : case RES_DATETIMEFLD:
1351 4 : if( static_cast<SwDateTimeField*>(pFormatField->GetField())->IsFixed() )
1352 : {
1353 0 : bChgd = true;
1354 0 : static_cast<SwDateTimeField*>(pFormatField->GetField())->SetDateTime(
1355 0 : DateTime(Date(nDate), tools::Time(nTime)) );
1356 : }
1357 4 : break;
1358 :
1359 : case RES_FILENAMEFLD:
1360 0 : if( static_cast<SwFileNameField*>(pFormatField->GetField())->IsFixed() )
1361 : {
1362 0 : bChgd = true;
1363 : SwFileNameField* pFileNameField =
1364 0 : static_cast<SwFileNameField*>(pFormatField->GetField());
1365 : pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(
1366 0 : pFileNameField->GetTyp())->Expand(
1367 0 : pFileNameField->GetFormat() ) );
1368 : }
1369 0 : break;
1370 : }
1371 :
1372 : // Trigger formatting
1373 4 : if( bChgd )
1374 0 : pFormatField->ModifyNotification( 0, 0 );
1375 : }
1376 : }
1377 290 : }
1378 :
1379 58 : if( !bIsModified )
1380 37 : m_rDoc.getIDocumentState().ResetModified();
1381 58 : }
1382 :
1383 0 : void DocumentFieldsManager::FieldsToCalc( SwCalc& rCalc, const _SetGetExpField& rToThisField )
1384 : {
1385 : // create the sorted list of all SetFields
1386 0 : mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1387 0 : mbNewFieldLst = false;
1388 :
1389 : #if !HAVE_FEATURE_DBCONNECTIVITY
1390 : SwDBManager* pMgr = NULL;
1391 : #else
1392 0 : SwDBManager* pMgr = m_rDoc.GetDBManager();
1393 0 : pMgr->CloseAll(false);
1394 : #endif
1395 :
1396 0 : if( !mpUpdateFields->GetSortLst()->empty() )
1397 : {
1398 : _SetGetExpFields::const_iterator const itLast =
1399 0 : mpUpdateFields->GetSortLst()->upper_bound(
1400 0 : const_cast<_SetGetExpField*>(&rToThisField));
1401 0 : for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != itLast; ++it )
1402 0 : lcl_CalcField( m_rDoc, rCalc, **it, pMgr );
1403 : }
1404 : #if HAVE_FEATURE_DBCONNECTIVITY
1405 0 : pMgr->CloseAll(false);
1406 : #endif
1407 0 : }
1408 :
1409 1 : void DocumentFieldsManager::FieldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
1410 : {
1411 : // create the sorted list of all SetFields
1412 1 : mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1413 1 : mbNewFieldLst = false;
1414 :
1415 : #if !HAVE_FEATURE_DBCONNECTIVITY
1416 : SwDBManager* pMgr = NULL;
1417 : #else
1418 1 : SwDBManager* pMgr = m_rDoc.GetDBManager();
1419 1 : pMgr->CloseAll(false);
1420 : #endif
1421 :
1422 6 : for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin();
1423 8 : it != mpUpdateFields->GetSortLst()->end() &&
1424 1 : ( (*it)->GetNode() < nLastNd ||
1425 0 : ( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
1426 : );
1427 : ++it )
1428 : {
1429 1 : lcl_CalcField( m_rDoc, rCalc, **it, pMgr );
1430 : }
1431 :
1432 : #if HAVE_FEATURE_DBCONNECTIVITY
1433 1 : pMgr->CloseAll(false);
1434 : #endif
1435 1 : }
1436 :
1437 0 : void DocumentFieldsManager::FieldsToExpand( SwHash**& ppHashTable, sal_uInt16& rTableSize,
1438 : const _SetGetExpField& rToThisField )
1439 : {
1440 : // create the sorted list of all SetFields
1441 0 : mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_EXPAND );
1442 0 : mbNewFieldLst = false;
1443 :
1444 : // Hash table for all string replacements is filled on-the-fly.
1445 : // Try to fabricate an uneven number.
1446 0 : rTableSize = (( mpUpdateFields->GetSortLst()->size() / 7 ) + 1 ) * 7;
1447 0 : ppHashTable = new SwHash*[ rTableSize ];
1448 0 : memset( ppHashTable, 0, sizeof( _HashStr* ) * rTableSize );
1449 :
1450 : _SetGetExpFields::const_iterator const itLast =
1451 0 : mpUpdateFields->GetSortLst()->upper_bound(
1452 0 : const_cast<_SetGetExpField*>(&rToThisField));
1453 :
1454 0 : for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != itLast; ++it )
1455 : {
1456 0 : const SwTextField* pTextField = (*it)->GetTextField();
1457 0 : if( !pTextField )
1458 0 : continue;
1459 :
1460 0 : const SwField* pField = pTextField->GetFormatField().GetField();
1461 0 : switch( pField->GetTyp()->Which() )
1462 : {
1463 : case RES_SETEXPFLD:
1464 0 : if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
1465 : {
1466 : // set the new value in the hash table
1467 : // is the formula a field?
1468 0 : SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1469 0 : OUString aNew = LookString( ppHashTable, rTableSize, pSField->GetFormula() );
1470 :
1471 0 : if( aNew.isEmpty() ) // nothing found, then the formula is
1472 0 : aNew = pSField->GetFormula(); // the new value
1473 :
1474 : // #i3141# - update expression of field as in method
1475 : // <SwDoc::UpdateExpFields(..)> for string/text fields
1476 0 : pSField->ChgExpStr( aNew );
1477 :
1478 : // look up the field's name
1479 0 : aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1480 : // Entry present?
1481 : sal_uInt16 nPos;
1482 0 : SwHash* pFnd = Find( aNew, ppHashTable, rTableSize, &nPos );
1483 0 : if( pFnd )
1484 : // modify entry in the hash table
1485 0 : static_cast<_HashStr*>(pFnd)->aSetStr = pSField->GetExpStr();
1486 : else
1487 : // insert the new entry
1488 0 : *(ppHashTable + nPos ) = new _HashStr( aNew,
1489 0 : pSField->GetExpStr(), static_cast<_HashStr*>(*(ppHashTable + nPos)) );
1490 : }
1491 0 : break;
1492 : case RES_DBFLD:
1493 : {
1494 0 : const OUString& rName = pField->GetTyp()->GetName();
1495 :
1496 : // Insert entry in the hash table
1497 : // Entry present?
1498 : sal_uInt16 nPos;
1499 0 : SwHash* pFnd = Find( rName, ppHashTable, rTableSize, &nPos );
1500 0 : OUString const value(pField->ExpandField(m_rDoc.IsClipBoard()));
1501 0 : if( pFnd )
1502 : {
1503 : // modify entry in the hash table
1504 0 : static_cast<_HashStr*>(pFnd)->aSetStr = value;
1505 : }
1506 : else
1507 : {
1508 : // insert the new entry
1509 0 : *(ppHashTable + nPos ) = new _HashStr( rName,
1510 0 : value, static_cast<_HashStr *>(*(ppHashTable + nPos)));
1511 0 : }
1512 : }
1513 0 : break;
1514 : }
1515 : }
1516 0 : }
1517 :
1518 :
1519 2073 : bool DocumentFieldsManager::IsNewFieldLst() const
1520 : {
1521 2073 : return mbNewFieldLst;
1522 : }
1523 :
1524 5704 : void DocumentFieldsManager::SetNewFieldLst(bool bFlag)
1525 : {
1526 5704 : mbNewFieldLst = bFlag;
1527 5704 : }
1528 :
1529 30 : void DocumentFieldsManager::InsDelFieldInFieldLst( bool bIns, const SwTextField& rField )
1530 : {
1531 30 : if( !mbNewFieldLst || !m_rDoc.IsInDtor() )
1532 30 : mpUpdateFields->InsDelFieldInFieldLst( bIns, rField );
1533 30 : }
1534 :
1535 246 : SwField * DocumentFieldsManager::GetFieldAtPos(const SwPosition & rPos)
1536 : {
1537 246 : SwTextField * const pAttr = GetTextFieldAtPos(rPos);
1538 :
1539 246 : return (pAttr) ? const_cast<SwField *>( pAttr->GetFormatField().GetField() ) : 0;
1540 : }
1541 :
1542 276 : SwTextField * DocumentFieldsManager::GetTextFieldAtPos(const SwPosition & rPos)
1543 : {
1544 276 : SwTextNode * const pNode = rPos.nNode.GetNode().GetTextNode();
1545 :
1546 : return (pNode != NULL)
1547 276 : ? pNode->GetFieldTextAttrAt( rPos.nContent.GetIndex(), true )
1548 552 : : 0;
1549 : }
1550 :
1551 : /// @note For simplicity assume that all field types have updatable contents so
1552 : /// optimization currently only available when no fields exist.
1553 98 : bool DocumentFieldsManager::containsUpdatableFields()
1554 : {
1555 2903 : for (auto pFieldType : *mpFieldTypes)
1556 : {
1557 2819 : SwIterator<SwFormatField,SwFieldType> aIter(*pFieldType);
1558 2819 : if (aIter.First())
1559 14 : return true;
1560 2805 : }
1561 84 : return false;
1562 : }
1563 :
1564 : /// Remove all unreferenced field types of a document
1565 3 : void DocumentFieldsManager::GCFieldTypes()
1566 : {
1567 6 : for( auto n = mpFieldTypes->size(); n > INIT_FLDTYPES; )
1568 0 : if( !(*mpFieldTypes)[ --n ]->HasWriterListeners() )
1569 0 : RemoveFieldType( n );
1570 3 : }
1571 :
1572 2958 : void DocumentFieldsManager::_InitFieldTypes() // is being called by the CTOR
1573 : {
1574 : // Field types
1575 2958 : mpFieldTypes->push_back( new SwDateTimeFieldType(&m_rDoc) );
1576 2958 : mpFieldTypes->push_back( new SwChapterFieldType );
1577 2958 : mpFieldTypes->push_back( new SwPageNumberFieldType );
1578 2958 : mpFieldTypes->push_back( new SwAuthorFieldType );
1579 2958 : mpFieldTypes->push_back( new SwFileNameFieldType(&m_rDoc) );
1580 2958 : mpFieldTypes->push_back( new SwDBNameFieldType(&m_rDoc) );
1581 2958 : mpFieldTypes->push_back( new SwGetExpFieldType(&m_rDoc) );
1582 2958 : mpFieldTypes->push_back( new SwGetRefFieldType( &m_rDoc ) );
1583 2958 : mpFieldTypes->push_back( new SwHiddenTextFieldType );
1584 2958 : mpFieldTypes->push_back( new SwPostItFieldType(&m_rDoc) );
1585 2958 : mpFieldTypes->push_back( new SwDocStatFieldType(&m_rDoc) );
1586 2958 : mpFieldTypes->push_back( new SwDocInfoFieldType(&m_rDoc) );
1587 2958 : mpFieldTypes->push_back( new SwInputFieldType( &m_rDoc ) );
1588 2958 : mpFieldTypes->push_back( new SwTableFieldType( &m_rDoc ) );
1589 2958 : mpFieldTypes->push_back( new SwMacroFieldType(&m_rDoc) );
1590 2958 : mpFieldTypes->push_back( new SwHiddenParaFieldType );
1591 2958 : mpFieldTypes->push_back( new SwDBNextSetFieldType );
1592 2958 : mpFieldTypes->push_back( new SwDBNumSetFieldType );
1593 2958 : mpFieldTypes->push_back( new SwDBSetNumberFieldType );
1594 2958 : mpFieldTypes->push_back( new SwTemplNameFieldType(&m_rDoc) );
1595 2958 : mpFieldTypes->push_back( new SwTemplNameFieldType(&m_rDoc) );
1596 2958 : mpFieldTypes->push_back( new SwExtUserFieldType );
1597 2958 : mpFieldTypes->push_back( new SwRefPageSetFieldType );
1598 2958 : mpFieldTypes->push_back( new SwRefPageGetFieldType( &m_rDoc ) );
1599 2958 : mpFieldTypes->push_back( new SwJumpEditFieldType( &m_rDoc ) );
1600 2958 : mpFieldTypes->push_back( new SwScriptFieldType( &m_rDoc ) );
1601 2958 : mpFieldTypes->push_back( new SwCombinedCharFieldType );
1602 2958 : mpFieldTypes->push_back( new SwDropDownFieldType );
1603 :
1604 : // Types have to be at the end!
1605 : // We expect &m_rDoc in the InsertFieldType!
1606 : // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
1607 : // lcl_sw3io_InSetExpField (sw3field.cxx) now also
1608 : mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
1609 2958 : SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
1610 : mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
1611 2958 : SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
1612 : mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
1613 2958 : SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
1614 : mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
1615 2958 : SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
1616 :
1617 : assert( mpFieldTypes->size() == INIT_FLDTYPES );
1618 2958 : }
1619 :
1620 21 : void DocumentFieldsManager::ClearFieldTypes()
1621 : {
1622 63 : for(SwFieldTypes::const_iterator it = mpFieldTypes->begin() + INIT_FLDTYPES;
1623 42 : it != mpFieldTypes->end(); ++it)
1624 0 : delete *it;
1625 21 : mpFieldTypes->erase( mpFieldTypes->begin() + INIT_FLDTYPES, mpFieldTypes->end() );
1626 21 : }
1627 :
1628 0 : void DocumentFieldsManager::UpdateDBNumFields( SwDBNameInfField& rDBField, SwCalc& rCalc )
1629 : {
1630 : #if !HAVE_FEATURE_DBCONNECTIVITY
1631 : (void) rDBField;
1632 : (void) rCalc;
1633 : #else
1634 0 : SwDBManager* pMgr = m_rDoc.GetDBManager();
1635 :
1636 0 : sal_uInt16 nFieldType = rDBField.Which();
1637 :
1638 0 : bool bPar1 = rCalc.Calculate( rDBField.GetPar1() ).GetBool();
1639 :
1640 0 : if( RES_DBNEXTSETFLD == nFieldType )
1641 0 : static_cast<SwDBNextSetField&>(rDBField).SetCondValid( bPar1 );
1642 : else
1643 0 : static_cast<SwDBNumSetField&>(rDBField).SetCondValid( bPar1 );
1644 :
1645 0 : if( !rDBField.GetRealDBData().sDataSource.isEmpty() )
1646 : {
1647 : // Edit a certain database
1648 0 : if( RES_DBNEXTSETFLD == nFieldType )
1649 0 : static_cast<SwDBNextSetField&>(rDBField).Evaluate(&m_rDoc);
1650 : else
1651 0 : static_cast<SwDBNumSetField&>(rDBField).Evaluate(&m_rDoc);
1652 :
1653 0 : SwDBData aTmpDBData( rDBField.GetDBData(&m_rDoc) );
1654 :
1655 0 : if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false ))
1656 : rCalc.VarChange( lcl_GetDBVarName( m_rDoc, rDBField),
1657 0 : pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
1658 : }
1659 : else
1660 : {
1661 : OSL_FAIL("TODO: what should happen with unnamed DBFields?");
1662 : }
1663 : #endif
1664 0 : }
1665 :
1666 8847 : DocumentFieldsManager::~DocumentFieldsManager()
1667 : {
1668 2949 : delete mpUpdateFields;
1669 2949 : delete mpFieldTypes;
1670 5898 : }
1671 :
1672 177 : }
1673 :
1674 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|