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 this 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 :
20 : #include <config_features.h>
21 :
22 : #include <hintids.hxx>
23 :
24 : #include <string.h>
25 : #include <float.h>
26 : #include <comphelper/string.hxx>
27 : #include <tools/datetime.hxx>
28 : #include <vcl/svapp.hxx>
29 : #include <unotools/charclass.hxx>
30 : #include <unotools/transliterationwrapper.hxx>
31 : #include <doc.hxx>
32 : #include <IDocumentUndoRedo.hxx>
33 : #include <IDocumentFieldsAccess.hxx>
34 : #include <IDocumentState.hxx>
35 : #include <IDocumentLayoutAccess.hxx>
36 : #include <cntfrm.hxx>
37 : #include <pam.hxx>
38 : #include <ndtxt.hxx>
39 : #include <swtable.hxx>
40 : #include <calc.hxx>
41 : #include <txtfld.hxx>
42 : #include <fmtfld.hxx>
43 : #include <tox.hxx>
44 : #include <txttxmrk.hxx>
45 : #include <docfld.hxx>
46 : #include <docufld.hxx>
47 : #include <ddefld.hxx>
48 : #include <usrfld.hxx>
49 : #include <expfld.hxx>
50 : #include <dbfld.hxx>
51 : #include <flddat.hxx>
52 : #include <chpfld.hxx>
53 : #include <reffld.hxx>
54 : #include <flddropdown.hxx>
55 : #include <dbmgr.hxx>
56 : #include <section.hxx>
57 : #include <cellatr.hxx>
58 : #include <docary.hxx>
59 : #include <authfld.hxx>
60 : #include <txtinet.hxx>
61 : #include <fmtcntnt.hxx>
62 : #include <poolfmt.hrc>
63 :
64 : #include <SwUndoField.hxx>
65 : #include <calbck.hxx>
66 :
67 : using namespace ::com::sun::star::uno;
68 :
69 : // the StartIndex can be supplied optionally (e.g. if it was queried before - is a virtual
70 : // method otherwise!)
71 132 : _SetGetExpField::_SetGetExpField(
72 : const SwNodeIndex& rNdIdx,
73 : const SwTextField* pField,
74 : const SwIndex* pIdx )
75 : {
76 132 : eSetGetExpFieldType = TEXTFIELD;
77 132 : CNTNT.pTextField = pField;
78 132 : nNode = rNdIdx.GetIndex();
79 132 : if( pIdx )
80 30 : nContent = pIdx->GetIndex();
81 102 : else if( pField )
82 102 : nContent = pField->GetStart();
83 : else
84 0 : nContent = 0;
85 132 : }
86 :
87 0 : _SetGetExpField::_SetGetExpField( const SwNodeIndex& rNdIdx,
88 : const SwTextINetFormat& rINet, const SwIndex* pIdx )
89 : {
90 0 : eSetGetExpFieldType = TEXTINET;
91 0 : CNTNT.pTextINet = &rINet;
92 0 : nNode = rNdIdx.GetIndex();
93 0 : if( pIdx )
94 0 : nContent = pIdx->GetIndex();
95 : else
96 0 : nContent = rINet.GetStart();
97 0 : }
98 :
99 : // Extension for Sections:
100 : // these always have content position 0xffffffff!
101 : // There is never a field on this, only up to COMPLETE_STRING possible
102 5 : _SetGetExpField::_SetGetExpField( const SwSectionNode& rSectNd,
103 : const SwPosition* pPos )
104 : {
105 5 : eSetGetExpFieldType = SECTIONNODE;
106 5 : CNTNT.pSection = &rSectNd.GetSection();
107 :
108 5 : if( pPos )
109 : {
110 0 : nNode = pPos->nNode.GetIndex();
111 0 : nContent = pPos->nContent.GetIndex();
112 : }
113 : else
114 : {
115 5 : nNode = rSectNd.GetIndex();
116 5 : nContent = 0;
117 : }
118 5 : }
119 :
120 0 : _SetGetExpField::_SetGetExpField( const SwTableBox& rTBox, const SwPosition* pPos )
121 : {
122 0 : eSetGetExpFieldType = TABLEBOX;
123 0 : CNTNT.pTBox = &rTBox;
124 :
125 0 : if( pPos )
126 : {
127 0 : nNode = pPos->nNode.GetIndex();
128 0 : nContent = pPos->nContent.GetIndex();
129 : }
130 : else
131 : {
132 0 : nNode = 0;
133 0 : nContent = 0;
134 0 : if( rTBox.GetSttNd() )
135 : {
136 0 : SwNodeIndex aIdx( *rTBox.GetSttNd() );
137 0 : const SwContentNode* pNd = aIdx.GetNode().GetNodes().GoNext( &aIdx );
138 0 : if( pNd )
139 0 : nNode = pNd->GetIndex();
140 : }
141 : }
142 0 : }
143 :
144 0 : _SetGetExpField::_SetGetExpField( const SwNodeIndex& rNdIdx,
145 : const SwTextTOXMark& rTOX,
146 : const SwIndex* pIdx )
147 : {
148 0 : eSetGetExpFieldType = TEXTTOXMARK;
149 0 : CNTNT.pTextTOX = &rTOX;
150 0 : nNode = rNdIdx.GetIndex();
151 0 : if( pIdx )
152 0 : nContent = pIdx->GetIndex();
153 : else
154 0 : nContent = rTOX.GetStart();
155 0 : }
156 :
157 0 : _SetGetExpField::_SetGetExpField( const SwPosition& rPos )
158 : {
159 0 : eSetGetExpFieldType = CRSRPOS;
160 0 : CNTNT.pPos = &rPos;
161 0 : nNode = rPos.nNode.GetIndex();
162 0 : nContent = rPos.nContent.GetIndex();
163 0 : }
164 :
165 0 : _SetGetExpField::_SetGetExpField( const SwFlyFrameFormat& rFlyFormat,
166 : const SwPosition* pPos )
167 : {
168 0 : eSetGetExpFieldType = FLYFRAME;
169 0 : CNTNT.pFlyFormat = &rFlyFormat;
170 0 : if( pPos )
171 : {
172 0 : nNode = pPos->nNode.GetIndex();
173 0 : nContent = pPos->nContent.GetIndex();
174 : }
175 : else
176 : {
177 0 : const SwFormatContent& rContent = rFlyFormat.GetContent();
178 0 : nNode = rContent.GetContentIdx()->GetIndex() + 1;
179 0 : nContent = 0;
180 : }
181 0 : }
182 :
183 0 : void _SetGetExpField::GetPosOfContent( SwPosition& rPos ) const
184 : {
185 0 : const SwNode* pNd = GetNodeFromContent();
186 0 : if( pNd )
187 0 : pNd = pNd->GetContentNode();
188 :
189 0 : if( pNd )
190 : {
191 0 : rPos.nNode = *pNd;
192 0 : rPos.nContent.Assign( const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pNd)), GetCntPosFromContent() );
193 : }
194 : else
195 : {
196 0 : rPos.nNode = nNode;
197 0 : rPos.nContent.Assign( rPos.nNode.GetNode().GetContentNode(), nContent );
198 : }
199 0 : }
200 :
201 0 : void _SetGetExpField::SetBodyPos( const SwContentFrm& rFrm )
202 : {
203 0 : if( !rFrm.IsInDocBody() )
204 : {
205 0 : SwNodeIndex aIdx( *rFrm.GetNode() );
206 0 : SwDoc& rDoc = *aIdx.GetNodes().GetDoc();
207 0 : SwPosition aPos( aIdx );
208 0 : bool const bResult = ::GetBodyTextNode( rDoc, aPos, rFrm );
209 : OSL_ENSURE(bResult, "Where is the field?");
210 : (void) bResult; // unused in non-debug
211 0 : nNode = aPos.nNode.GetIndex();
212 0 : nContent = aPos.nContent.GetIndex();
213 : }
214 0 : }
215 :
216 0 : bool _SetGetExpField::operator==( const _SetGetExpField& rField ) const
217 : {
218 0 : return nNode == rField.nNode
219 0 : && nContent == rField.nContent
220 0 : && ( !CNTNT.pTextField
221 0 : || !rField.CNTNT.pTextField
222 0 : || CNTNT.pTextField == rField.CNTNT.pTextField );
223 : }
224 :
225 112 : bool _SetGetExpField::operator<( const _SetGetExpField& rField ) const
226 : {
227 112 : if( nNode < rField.nNode || ( nNode == rField.nNode && nContent < rField.nContent ))
228 58 : return true;
229 54 : else if( nNode != rField.nNode || nContent != rField.nContent )
230 11 : return false;
231 :
232 43 : const SwNode *pFirst = GetNodeFromContent(),
233 43 : *pNext = rField.GetNodeFromContent();
234 :
235 : // Position is the same: continue only if both field pointers are set!
236 43 : if( !pFirst || !pNext )
237 0 : return false;
238 :
239 : // same Section?
240 43 : if( pFirst->StartOfSectionNode() != pNext->StartOfSectionNode() )
241 : {
242 : // is one in the table?
243 : const SwNode *pFirstStt, *pNextStt;
244 0 : const SwTableNode* pTableNd = pFirst->FindTableNode();
245 0 : if( pTableNd )
246 0 : pFirstStt = pTableNd->StartOfSectionNode();
247 : else
248 0 : pFirstStt = pFirst->StartOfSectionNode();
249 :
250 0 : if( 0 != ( pTableNd = pNext->FindTableNode() ) )
251 0 : pNextStt = pTableNd->StartOfSectionNode();
252 : else
253 0 : pNextStt = pNext->StartOfSectionNode();
254 :
255 0 : if( pFirstStt != pNextStt )
256 : {
257 0 : if( pFirst->IsTextNode() && pNext->IsTextNode() &&
258 0 : ( pFirst->FindFlyStartNode() || pNext->FindFlyStartNode() ))
259 : {
260 0 : return ::IsFrameBehind( *pNext->GetTextNode(), nContent, *pFirst->GetTextNode(), nContent );
261 : }
262 0 : return pFirstStt->GetIndex() < pNextStt->GetIndex();
263 : }
264 : }
265 :
266 : // same Section: is the field in the same Node?
267 43 : if( pFirst != pNext )
268 28 : return pFirst->GetIndex() < pNext->GetIndex();
269 :
270 : // same Node in the Section, check Position in the Node
271 15 : return GetCntPosFromContent() < rField.GetCntPosFromContent();
272 : }
273 :
274 86 : const SwNode* _SetGetExpField::GetNodeFromContent() const
275 : {
276 86 : const SwNode* pRet = 0;
277 86 : if( CNTNT.pTextField )
278 86 : switch( eSetGetExpFieldType )
279 : {
280 : case TEXTFIELD:
281 86 : pRet = &CNTNT.pTextField->GetTextNode();
282 86 : break;
283 :
284 : case TEXTINET:
285 0 : pRet = &CNTNT.pTextINet->GetTextNode();
286 0 : break;
287 :
288 : case SECTIONNODE:
289 0 : pRet = CNTNT.pSection->GetFormat()->GetSectionNode();
290 0 : break;
291 :
292 : case CRSRPOS:
293 0 : pRet = &CNTNT.pPos->nNode.GetNode();
294 0 : break;
295 :
296 : case TEXTTOXMARK:
297 0 : pRet = &CNTNT.pTextTOX->GetTextNode();
298 0 : break;
299 :
300 : case TABLEBOX:
301 0 : if( CNTNT.pTBox->GetSttNd() )
302 : {
303 0 : SwNodeIndex aIdx( *CNTNT.pTBox->GetSttNd() );
304 0 : pRet = aIdx.GetNode().GetNodes().GoNext( &aIdx );
305 : }
306 0 : break;
307 :
308 : case FLYFRAME:
309 : {
310 0 : SwNodeIndex aIdx( *CNTNT.pFlyFormat->GetContent().GetContentIdx() );
311 0 : pRet = aIdx.GetNode().GetNodes().GoNext( &aIdx );
312 : }
313 0 : break;
314 : }
315 86 : return pRet;
316 : }
317 :
318 30 : sal_Int32 _SetGetExpField::GetCntPosFromContent() const
319 : {
320 30 : sal_Int32 nRet = 0;
321 30 : if( CNTNT.pTextField )
322 30 : switch( eSetGetExpFieldType )
323 : {
324 : case TEXTFIELD:
325 : case TEXTINET:
326 : case TEXTTOXMARK:
327 30 : nRet = CNTNT.pTextField->GetStart();
328 30 : break;
329 : case CRSRPOS:
330 0 : nRet = CNTNT.pPos->nContent.GetIndex();
331 0 : break;
332 : default:
333 0 : break;
334 : }
335 30 : return nRet;
336 : }
337 :
338 119 : _HashStr::_HashStr( const OUString& rName, const OUString& rText,
339 : _HashStr* pNxt )
340 119 : : SwHash( rName ), aSetStr( rText )
341 : {
342 119 : pNext = pNxt;
343 119 : }
344 :
345 : /// Look up the Name, if it is present, return it's String, otherwise return an empty String
346 1 : OUString LookString( SwHash** ppTable, sal_uInt16 nSize, const OUString& rName,
347 : sal_uInt16* pPos )
348 : {
349 1 : SwHash* pFnd = Find( comphelper::string::strip(rName, ' '), ppTable, nSize, pPos );
350 1 : if( pFnd )
351 0 : return static_cast<_HashStr*>(pFnd)->aSetStr;
352 :
353 1 : return OUString();
354 : }
355 :
356 854 : SwDBData SwDoc::GetDBData()
357 : {
358 854 : return GetDBDesc();
359 : }
360 :
361 1072 : const SwDBData& SwDoc::GetDBDesc()
362 : {
363 : #if HAVE_FEATURE_DBCONNECTIVITY
364 1072 : if(maDBData.sDataSource.isEmpty())
365 : {
366 830 : const SwFieldTypes::size_type nSize = getIDocumentFieldsAccess().GetFieldTypes()->size();
367 27399 : for(SwFieldTypes::size_type i = 0; i < nSize && maDBData.sDataSource.isEmpty(); ++i)
368 : {
369 26569 : SwFieldType& rFieldType = *((*getIDocumentFieldsAccess().GetFieldTypes())[i]);
370 26569 : sal_uInt16 nWhich = rFieldType.Which();
371 26569 : if(IsUsed(rFieldType))
372 : {
373 23 : switch(nWhich)
374 : {
375 : case RES_DBFLD:
376 : case RES_DBNEXTSETFLD:
377 : case RES_DBNUMSETFLD:
378 : case RES_DBSETNUMBERFLD:
379 : {
380 3 : SwIterator<SwFormatField,SwFieldType> aIter( rFieldType );
381 3 : for( SwFormatField* pField = aIter.First(); pField; pField = aIter.Next() )
382 : {
383 3 : if(pField->IsFieldInDoc())
384 : {
385 3 : if(RES_DBFLD == nWhich)
386 3 : maDBData = (static_cast < SwDBFieldType * > (pField->GetField()->GetTyp()))->GetDBData();
387 : else
388 0 : maDBData = (static_cast < SwDBNameInfField* > (pField->GetField()))->GetRealDBData();
389 3 : break;
390 : }
391 3 : }
392 : }
393 3 : break;
394 : }
395 : }
396 : }
397 : }
398 1072 : if(maDBData.sDataSource.isEmpty())
399 827 : maDBData = SwDBManager::GetAddressDBName();
400 : #endif
401 1072 : return maDBData;
402 : }
403 :
404 125 : void SwDoc::SetInitDBFields( bool b )
405 : {
406 : #if !HAVE_FEATURE_DBCONNECTIVITY
407 : (void) b;
408 : #else
409 125 : GetDBManager()->SetInitDBFields( b );
410 : #endif
411 125 : }
412 :
413 : #if HAVE_FEATURE_DBCONNECTIVITY
414 :
415 : /// Get all databases that are used by fields
416 0 : static OUString lcl_DBDataToString(const SwDBData& rData)
417 : {
418 0 : return rData.sDataSource + OUString(DB_DELIM)
419 0 : + rData.sCommand + OUString(DB_DELIM)
420 0 : + OUString::number(rData.nCommandType);
421 : }
422 :
423 : #endif
424 :
425 0 : void SwDoc::GetAllUsedDB( std::vector<OUString>& rDBNameList,
426 : const std::vector<OUString>* pAllDBNames )
427 : {
428 : #if !HAVE_FEATURE_DBCONNECTIVITY
429 : (void) rDBNameList;
430 : (void) pAllDBNames;
431 : #else
432 0 : std::vector<OUString> aUsedDBNames;
433 0 : std::vector<OUString> aAllDBNames;
434 :
435 0 : if( !pAllDBNames )
436 : {
437 0 : GetAllDBNames( aAllDBNames );
438 0 : pAllDBNames = &aAllDBNames;
439 : }
440 :
441 0 : SwSectionFormats& rArr = GetSections();
442 0 : for (auto n = rArr.size(); n; )
443 : {
444 0 : SwSection* pSect = rArr[ --n ]->GetSection();
445 :
446 0 : if( pSect )
447 : {
448 : AddUsedDBToList( rDBNameList, FindUsedDBs( *pAllDBNames,
449 0 : pSect->GetCondition(), aUsedDBNames ) );
450 0 : aUsedDBNames.clear();
451 : }
452 : }
453 :
454 0 : sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
455 0 : for (sal_uInt32 n = 0; n < nMaxItems; ++n)
456 : {
457 : const SfxPoolItem* pItem;
458 0 : if( 0 == (pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) ))
459 0 : continue;
460 :
461 0 : const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
462 0 : const SwTextField* pTextField = pFormatField->GetTextField();
463 0 : if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
464 0 : continue;
465 :
466 0 : const SwField* pField = pFormatField->GetField();
467 0 : switch( pField->GetTyp()->Which() )
468 : {
469 : case RES_DBFLD:
470 : AddUsedDBToList( rDBNameList,
471 0 : lcl_DBDataToString(static_cast<const SwDBField*>(pField)->GetDBData() ));
472 0 : break;
473 :
474 : case RES_DBSETNUMBERFLD:
475 : case RES_DBNAMEFLD:
476 : AddUsedDBToList( rDBNameList,
477 0 : lcl_DBDataToString(static_cast<const SwDBNameInfField*>(pField)->GetRealDBData() ));
478 0 : break;
479 :
480 : case RES_DBNUMSETFLD:
481 : case RES_DBNEXTSETFLD:
482 : AddUsedDBToList( rDBNameList,
483 0 : lcl_DBDataToString(static_cast<const SwDBNameInfField*>(pField)->GetRealDBData() ));
484 : // no break // JP: is that right like that?
485 :
486 : case RES_HIDDENTXTFLD:
487 : case RES_HIDDENPARAFLD:
488 : AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
489 0 : pField->GetPar1(), aUsedDBNames ));
490 0 : aUsedDBNames.clear();
491 0 : break;
492 :
493 : case RES_SETEXPFLD:
494 : case RES_GETEXPFLD:
495 : case RES_TABLEFLD:
496 : AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
497 0 : pField->GetFormula(), aUsedDBNames ));
498 0 : aUsedDBNames.clear();
499 0 : break;
500 : }
501 0 : }
502 : #endif
503 0 : }
504 :
505 0 : void SwDoc::GetAllDBNames( std::vector<OUString>& rAllDBNames )
506 : {
507 : #if !HAVE_FEATURE_DBCONNECTIVITY
508 : (void) rAllDBNames;
509 : #else
510 0 : SwDBManager* pMgr = GetDBManager();
511 :
512 0 : const SwDSParamArr& rArr = pMgr->GetDSParamArray();
513 0 : for(const auto &aParam : rArr)
514 : {
515 0 : rAllDBNames.push_back(aParam.sDataSource + OUString(DB_DELIM) + aParam.sCommand);
516 : }
517 : #endif
518 0 : }
519 :
520 0 : std::vector<OUString>& SwDoc::FindUsedDBs( const std::vector<OUString>& rAllDBNames,
521 : const OUString& rFormula,
522 : std::vector<OUString>& rUsedDBNames )
523 : {
524 0 : const CharClass& rCC = GetAppCharClass();
525 : #ifndef UNX
526 : const OUString sFormula(rCC.uppercase( rFormula ));
527 : #else
528 0 : const OUString sFormula(rFormula);
529 : #endif
530 :
531 0 : for (const auto &sItem : rAllDBNames)
532 : {
533 0 : sal_Int32 nPos = sFormula.indexOf( sItem );
534 0 : if( nPos>=0 &&
535 0 : sFormula[ nPos + sItem.getLength() ] == '.' &&
536 0 : (!nPos || !rCC.isLetterNumeric( sFormula, nPos - 1 )))
537 : {
538 : // Look up table name
539 0 : nPos += sItem.getLength() + 1;
540 0 : const sal_Int32 nEndPos = sFormula.indexOf('.', nPos);
541 0 : if( nEndPos>=0 )
542 : {
543 0 : rUsedDBNames.push_back(sItem + OUString( DB_DELIM ) + sFormula.copy( nPos, nEndPos - nPos ));
544 : }
545 : }
546 : }
547 0 : return rUsedDBNames;
548 : }
549 :
550 0 : void SwDoc::AddUsedDBToList( std::vector<OUString>& rDBNameList,
551 : const std::vector<OUString>& rUsedDBNames )
552 : {
553 0 : for ( const auto &sName : rUsedDBNames )
554 0 : AddUsedDBToList( rDBNameList, sName );
555 0 : }
556 :
557 0 : void SwDoc::AddUsedDBToList( std::vector<OUString>& rDBNameList, const OUString& rDBName)
558 : {
559 : #if !HAVE_FEATURE_DBCONNECTIVITY
560 : (void) rDBNameList;
561 : (void) rDBName;
562 : #else
563 0 : if( rDBName.isEmpty() )
564 0 : return;
565 :
566 : #ifdef UNX
567 0 : for( const auto &sName : rDBNameList )
568 0 : if( rDBName == sName.getToken(0, ';') )
569 0 : return;
570 : #else
571 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
572 : for( const auto &sName : rDBNameList )
573 : if( rSCmp.isEqual( rDBName, sName.getToken(0, ';') ) )
574 : return;
575 : #endif
576 :
577 0 : SwDBData aData;
578 0 : aData.sDataSource = rDBName.getToken(0, DB_DELIM);
579 0 : aData.sCommand = rDBName.getToken(1, DB_DELIM);
580 0 : aData.nCommandType = -1;
581 0 : GetDBManager()->CreateDSData(aData);
582 0 : rDBNameList.push_back(rDBName);
583 : #endif
584 : }
585 :
586 0 : void SwDoc::ChangeDBFields( const std::vector<OUString>& rOldNames,
587 : const OUString& rNewName )
588 : {
589 : #if !HAVE_FEATURE_DBCONNECTIVITY
590 : (void) rOldNames;
591 : (void) rNewName;
592 : #else
593 0 : SwDBData aNewDBData;
594 0 : aNewDBData.sDataSource = rNewName.getToken(0, DB_DELIM);
595 0 : aNewDBData.sCommand = rNewName.getToken(1, DB_DELIM);
596 0 : aNewDBData.nCommandType = (short)rNewName.getToken(2, DB_DELIM).toInt32();
597 :
598 0 : SwSectionFormats& rArr = GetSections();
599 0 : for (auto n = rArr.size(); n; )
600 : {
601 0 : SwSection* pSect = rArr[ --n ]->GetSection();
602 :
603 0 : if( pSect )
604 : {
605 0 : pSect->SetCondition(ReplaceUsedDBs(rOldNames, rNewName, pSect->GetCondition()));
606 : }
607 : }
608 :
609 0 : sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
610 :
611 0 : for (sal_uInt32 n = 0; n < nMaxItems; ++n )
612 : {
613 0 : const SfxPoolItem* pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n );
614 0 : if( !pItem )
615 0 : continue;
616 :
617 0 : SwFormatField* pFormatField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem));
618 0 : SwTextField* pTextField = pFormatField->GetTextField();
619 0 : if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
620 0 : continue;
621 :
622 0 : SwField* pField = pFormatField->GetField();
623 0 : bool bExpand = false;
624 :
625 0 : switch( pField->GetTyp()->Which() )
626 : {
627 : case RES_DBFLD:
628 : #if HAVE_FEATURE_DBCONNECTIVITY
629 0 : if( IsNameInArray( rOldNames, lcl_DBDataToString(static_cast<SwDBField*>(pField)->GetDBData())))
630 : {
631 0 : SwDBFieldType* pOldTyp = static_cast<SwDBFieldType*>(pField->GetTyp());
632 :
633 0 : SwDBFieldType* pTyp = static_cast<SwDBFieldType*>(getIDocumentFieldsAccess().InsertFieldType(
634 0 : SwDBFieldType(this, pOldTyp->GetColumnName(), aNewDBData)));
635 :
636 0 : pFormatField->RegisterToFieldType( *pTyp );
637 0 : pField->ChgTyp(pTyp);
638 :
639 0 : static_cast<SwDBField*>(pField)->ClearInitialized();
640 0 : static_cast<SwDBField*>(pField)->InitContent();
641 :
642 0 : bExpand = true;
643 : }
644 : #endif
645 0 : break;
646 :
647 : case RES_DBSETNUMBERFLD:
648 : case RES_DBNAMEFLD:
649 0 : if( IsNameInArray( rOldNames,
650 0 : lcl_DBDataToString(static_cast<SwDBNameInfField*>(pField)->GetRealDBData())))
651 : {
652 0 : static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
653 0 : bExpand = true;
654 : }
655 0 : break;
656 :
657 : case RES_DBNUMSETFLD:
658 : case RES_DBNEXTSETFLD:
659 0 : if( IsNameInArray( rOldNames,
660 0 : lcl_DBDataToString(static_cast<SwDBNameInfField*>(pField)->GetRealDBData())))
661 : {
662 0 : static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
663 : }
664 : // no break;
665 : case RES_HIDDENTXTFLD:
666 : case RES_HIDDENPARAFLD:
667 0 : pField->SetPar1( ReplaceUsedDBs(rOldNames, rNewName, pField->GetPar1()) );
668 0 : bExpand = true;
669 0 : break;
670 :
671 : case RES_SETEXPFLD:
672 : case RES_GETEXPFLD:
673 : case RES_TABLEFLD:
674 0 : pField->SetPar2( ReplaceUsedDBs(rOldNames, rNewName, pField->GetFormula()) );
675 0 : bExpand = true;
676 0 : break;
677 : }
678 :
679 0 : if (bExpand)
680 0 : pTextField->ExpandTextField( true );
681 : }
682 0 : getIDocumentState().SetModified();
683 : #endif
684 0 : }
685 :
686 : namespace
687 : {
688 :
689 0 : inline OUString lcl_CutOffDBCommandType(const OUString& rName)
690 : {
691 0 : return rName.replaceFirst(OUString(DB_DELIM), ".").getToken(0, DB_DELIM);
692 : }
693 :
694 : }
695 :
696 0 : OUString SwDoc::ReplaceUsedDBs( const std::vector<OUString>& rUsedDBNames,
697 : const OUString& rNewName, const OUString& rFormula )
698 : {
699 0 : const CharClass& rCC = GetAppCharClass();
700 0 : const OUString sNewName( lcl_CutOffDBCommandType(rNewName) );
701 0 : OUString sFormula(rFormula);
702 :
703 0 : for( size_t i = 0; i < rUsedDBNames.size(); ++i )
704 : {
705 0 : const OUString sDBName( lcl_CutOffDBCommandType(rUsedDBNames[i]) );
706 :
707 0 : if (sDBName!=sNewName)
708 : {
709 0 : sal_Int32 nPos = 0;
710 : for (;;)
711 : {
712 0 : nPos = sFormula.indexOf(sDBName, nPos);
713 0 : if (nPos<0)
714 : {
715 0 : break;
716 : }
717 :
718 0 : if( sFormula[nPos + sDBName.getLength()] == '.' &&
719 0 : (!nPos || !rCC.isLetterNumeric( sFormula, nPos - 1 )))
720 : {
721 0 : sFormula = sFormula.replaceAt(nPos, sDBName.getLength(), sNewName);
722 : //prevent re-searching - this is useless and provokes
723 : //endless loops when names containing each other and numbers are exchanged
724 : //e.g.: old ?12345.12345 new: i12345.12345
725 0 : nPos += sNewName.getLength();
726 : }
727 0 : }
728 : }
729 0 : }
730 0 : return sFormula;
731 : }
732 :
733 0 : bool SwDoc::IsNameInArray( const std::vector<OUString>& rArr, const OUString& rName )
734 : {
735 : #ifdef UNX
736 0 : for( const auto &sName : rArr )
737 0 : if( rName == sName )
738 0 : return true;
739 : #else
740 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
741 : for( const auto &sName : rArr )
742 : if( rSCmp.isEqual( rName, sName ))
743 : return true;
744 : #endif
745 0 : return false;
746 : }
747 :
748 0 : void SwDoc::ChangeAuthorityData( const SwAuthEntry* pNewData )
749 : {
750 0 : const SwFieldTypes::size_type nSize = getIDocumentFieldsAccess().GetFieldTypes()->size();
751 :
752 0 : for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < nSize; ++i )
753 : {
754 0 : SwFieldType* pFieldType = (*getIDocumentFieldsAccess().GetFieldTypes())[i];
755 0 : if( RES_AUTHORITY == pFieldType->Which() )
756 : {
757 0 : SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(pFieldType);
758 0 : pAuthType->ChangeEntryContent(pNewData);
759 0 : break;
760 : }
761 : }
762 :
763 0 : }
764 :
765 30 : void SwDocUpdateField::InsDelFieldInFieldLst( bool bIns, const SwTextField& rField )
766 : {
767 30 : const sal_uInt16 nWhich = rField.GetFormatField().GetField()->GetTyp()->Which();
768 30 : switch( nWhich )
769 : {
770 : case RES_DBFLD:
771 : case RES_SETEXPFLD:
772 : case RES_HIDDENPARAFLD:
773 : case RES_HIDDENTXTFLD:
774 : case RES_DBNUMSETFLD:
775 : case RES_DBNEXTSETFLD:
776 : case RES_DBSETNUMBERFLD:
777 : case RES_GETEXPFLD:
778 30 : break; // these have to be added/removed!
779 :
780 : default:
781 0 : return;
782 : }
783 :
784 30 : SetFieldsDirty( true );
785 30 : if( !pFieldSortLst )
786 : {
787 0 : if( !bIns ) // if list is present and deleted
788 0 : return; // don't do a thing
789 0 : pFieldSortLst = new _SetGetExpFields;
790 : }
791 :
792 30 : if( bIns ) // insert anew:
793 0 : GetBodyNode( rField, nWhich );
794 : else
795 : {
796 : // look up via the pTextField pointer. It is a sorted list, but it's sorted by node
797 : // position. Until this is found, the search for the pointer is already done.
798 70 : for( _SetGetExpFields::size_type n = 0; n < pFieldSortLst->size(); ++n )
799 40 : if( &rField == (*pFieldSortLst)[ n ]->GetPointer() )
800 : {
801 30 : delete (*pFieldSortLst)[n];
802 30 : pFieldSortLst->erase(n);
803 30 : n--; // one field can occur multiple times
804 : }
805 : }
806 : }
807 :
808 406 : void SwDocUpdateField::MakeFieldList( SwDoc& rDoc, bool bAll, int eGetMode )
809 : {
810 406 : if( !pFieldSortLst || bAll || !( eGetMode & nFieldLstGetMode ) ||
811 0 : rDoc.GetNodes().Count() != nNodes )
812 406 : _MakeFieldList( rDoc, eGetMode );
813 406 : }
814 :
815 406 : void SwDocUpdateField::_MakeFieldList( SwDoc& rDoc, int eGetMode )
816 : {
817 : // new version: walk all fields of the attribute pool
818 406 : delete pFieldSortLst;
819 406 : pFieldSortLst = new _SetGetExpFields;
820 :
821 : // consider and unhide sections
822 : // with hide condition, only in mode GETFLD_ALL (<eGetMode == GETFLD_ALL>)
823 : // notes by OD:
824 : // eGetMode == GETFLD_CALC in call from methods SwDoc::FieldsToCalc
825 : // eGetMode == GETFLD_EXPAND in call from method SwDoc::FieldsToExpand
826 : // eGetMode == GETFLD_ALL in call from method SwDoc::UpdateExpFields
827 : // I figured out that hidden section only have to be shown,
828 : // if fields have updated (call by SwDoc::UpdateExpFields) and thus
829 : // the hide conditions of section have to be updated.
830 : // For correct updating the hide condition of a section, its position
831 : // have to be known in order to insert the hide condition as a new
832 : // expression field into the sorted field list (<pFieldSortLst>).
833 406 : if ( eGetMode == GETFLD_ALL )
834 : // Collect the sections first. Supply sections that are hidden by condition
835 : // with frames so that the contained fields are sorted properly.
836 : {
837 : // In order for the frames to be created the right way, they have to be expanded
838 : // from top to bottom
839 405 : std::vector<sal_uLong> aTmpArr;
840 405 : std::vector<sal_uLong>::size_type nArrStt = 0;
841 405 : SwSectionFormats& rArr = rDoc.GetSections();
842 405 : SwSectionNode* pSectNd = 0;
843 405 : sal_uLong nSttContent = rDoc.GetNodes().GetEndOfExtras().GetIndex();
844 :
845 931 : for (SwSectionFormats::size_type n = rArr.size(); n; )
846 : {
847 121 : SwSection* pSect = rArr[ --n ]->GetSection();
848 126 : if( pSect && pSect->IsHidden() && !pSect->GetCondition().isEmpty() &&
849 5 : 0 != ( pSectNd = pSect->GetFormat()->GetSectionNode() ))
850 : {
851 5 : sal_uLong nIdx = pSectNd->GetIndex();
852 5 : aTmpArr.push_back( nIdx );
853 5 : if( nIdx < nSttContent )
854 0 : ++nArrStt;
855 : }
856 : }
857 405 : std::sort(aTmpArr.begin(), aTmpArr.end());
858 :
859 : // Display all first so that we have frames. The BodyAnchor is defined by that.
860 : // First the ContentArea, then the special areas!
861 410 : for (std::vector<sal_uLong>::size_type n = nArrStt; n < aTmpArr.size(); ++n)
862 : {
863 5 : pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode();
864 : OSL_ENSURE( pSectNd, "Where is my SectionNode" );
865 5 : pSectNd->GetSection().SetCondHidden( false );
866 : }
867 405 : for (std::vector<sal_uLong>::size_type n = 0; n < nArrStt; ++n)
868 : {
869 0 : pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode();
870 : OSL_ENSURE( pSectNd, "Where is my SectionNode" );
871 0 : pSectNd->GetSection().SetCondHidden( false );
872 : }
873 :
874 : // add all to the list so that they are sorted
875 410 : for (const auto &nId : aTmpArr)
876 : {
877 5 : GetBodyNode( *rDoc.GetNodes()[ nId ]->GetSectionNode() );
878 405 : }
879 : }
880 :
881 406 : const OUString sTrue("TRUE");
882 812 : const OUString sFalse("FALSE");
883 :
884 : #if HAVE_FEATURE_DBCONNECTIVITY
885 406 : bool bIsDBManager = 0 != rDoc.GetDBManager();
886 : #endif
887 :
888 406 : const sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
889 2096 : for( sal_uInt32 n = 0; n < nMaxItems; ++n )
890 : {
891 1690 : const SfxPoolItem* pItem = rDoc.GetAttrPool().GetItem2( RES_TXTATR_FIELD, n );
892 1690 : if( !pItem )
893 747 : continue;
894 :
895 1357 : const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
896 1357 : const SwTextField* pTextField = pFormatField->GetTextField();
897 1357 : if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
898 81 : continue;
899 :
900 1276 : OUString sFormula;
901 1276 : const SwField* pField = pFormatField->GetField();
902 1276 : const sal_uInt16 nWhich = pField->GetTyp()->Which();
903 1276 : switch( nWhich )
904 : {
905 : case RES_DBSETNUMBERFLD:
906 : case RES_GETEXPFLD:
907 0 : if( GETFLD_ALL == eGetMode )
908 0 : sFormula = sTrue;
909 0 : break;
910 :
911 : case RES_DBFLD:
912 125 : if( GETFLD_EXPAND & eGetMode )
913 125 : sFormula = sTrue;
914 125 : break;
915 :
916 : case RES_SETEXPFLD:
917 15 : if ( !(eGetMode == GETFLD_EXPAND) ||
918 0 : (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
919 : {
920 15 : sFormula = sTrue;
921 : }
922 15 : break;
923 :
924 : case RES_HIDDENPARAFLD:
925 0 : if( GETFLD_ALL == eGetMode )
926 : {
927 0 : sFormula = pField->GetPar1();
928 0 : if (sFormula.isEmpty() || sFormula==sFalse)
929 0 : const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( false );
930 0 : else if (sFormula==sTrue)
931 0 : const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( true );
932 : else
933 0 : break;
934 :
935 0 : sFormula.clear();
936 : // trigger formatting
937 0 : const_cast<SwFormatField*>(pFormatField)->ModifyNotification( 0, 0 );
938 : }
939 0 : break;
940 :
941 : case RES_HIDDENTXTFLD:
942 0 : if( GETFLD_ALL == eGetMode )
943 : {
944 0 : sFormula = pField->GetPar1();
945 0 : if (sFormula.isEmpty() || sFormula==sFalse)
946 0 : const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( true );
947 0 : else if (sFormula==sTrue)
948 0 : const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( false );
949 : else
950 0 : break;
951 :
952 0 : sFormula.clear();
953 :
954 : // evaluate field
955 0 : const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->Evaluate(&rDoc);
956 : // trigger formatting
957 0 : const_cast<SwFormatField*>(pFormatField)->ModifyNotification( 0, 0 );
958 : }
959 0 : break;
960 :
961 : #if HAVE_FEATURE_DBCONNECTIVITY
962 : case RES_DBNUMSETFLD:
963 : {
964 0 : SwDBData aDBData(const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField))->GetDBData(&rDoc));
965 :
966 0 : if (
967 0 : (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) &&
968 0 : (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && static_cast<const SwDBNumSetField*>(pField)->IsCondValid()))
969 : )
970 : {
971 0 : sFormula = pField->GetPar1();
972 0 : }
973 : }
974 0 : break;
975 : case RES_DBNEXTSETFLD:
976 : {
977 0 : SwDBData aDBData(const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField))->GetDBData(&rDoc));
978 :
979 0 : if (
980 0 : (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) &&
981 0 : (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && static_cast<const SwDBNextSetField*>(pField)->IsCondValid()))
982 : )
983 : {
984 0 : sFormula = pField->GetPar1();
985 0 : }
986 : }
987 0 : break;
988 : #endif
989 : }
990 :
991 1276 : if (!sFormula.isEmpty())
992 : {
993 140 : GetBodyNode( *pTextField, nWhich );
994 : }
995 1276 : }
996 406 : nFieldLstGetMode = static_cast<sal_uInt8>( eGetMode );
997 812 : nNodes = rDoc.GetNodes().Count();
998 406 : }
999 :
1000 140 : void SwDocUpdateField::GetBodyNode( const SwTextField& rTField, sal_uInt16 nFieldWhich )
1001 : {
1002 140 : const SwTextNode& rTextNd = rTField.GetTextNode();
1003 140 : const SwDoc& rDoc = *rTextNd.GetDoc();
1004 :
1005 : // always the first! (in tab headline, header-/footer)
1006 140 : Point aPt;
1007 140 : const SwContentFrm* pFrm = rTextNd.getLayoutFrm( rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
1008 :
1009 140 : _SetGetExpField* pNew = NULL;
1010 140 : bool bIsInBody = false;
1011 :
1012 140 : if( !pFrm || pFrm->IsInDocBody() )
1013 : {
1014 : // create index to determine the TextNode
1015 110 : SwNodeIndex aIdx( rTextNd );
1016 110 : bIsInBody = rDoc.GetNodes().GetEndOfExtras().GetIndex() < aIdx.GetIndex();
1017 :
1018 : // We don't want to update fields in redlines, or those
1019 : // in frames whose anchor is in redline. However, we do want to update
1020 : // fields in hidden sections. So: In order to be updated, a field 1)
1021 : // must have a frame, or 2) it must be in the document body.
1022 110 : if( (pFrm != NULL) || bIsInBody )
1023 102 : pNew = new _SetGetExpField( aIdx, &rTField );
1024 : }
1025 : else
1026 : {
1027 : // create index to determine the TextNode
1028 30 : SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
1029 30 : bool const bResult = GetBodyTextNode( rDoc, aPos, *pFrm );
1030 : OSL_ENSURE(bResult, "where is the Field");
1031 : (void) bResult; // unused in non-debug
1032 30 : pNew = new _SetGetExpField( aPos.nNode, &rTField, &aPos.nContent );
1033 : }
1034 :
1035 : // always set the BodyTextFlag in GetExp or DB fields
1036 140 : if( RES_GETEXPFLD == nFieldWhich )
1037 : {
1038 0 : SwGetExpField* pGetField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(rTField.GetFormatField().GetField()));
1039 0 : pGetField->ChgBodyTextFlag( bIsInBody );
1040 : }
1041 : #if HAVE_FEATURE_DBCONNECTIVITY
1042 140 : else if( RES_DBFLD == nFieldWhich )
1043 : {
1044 125 : SwDBField* pDBField = const_cast<SwDBField*>(static_cast<const SwDBField*>(rTField.GetFormatField().GetField()));
1045 125 : pDBField->ChgBodyTextFlag( bIsInBody );
1046 : }
1047 : #endif
1048 140 : if( pNew != NULL )
1049 132 : if( !pFieldSortLst->insert( pNew ).second )
1050 0 : delete pNew;
1051 140 : }
1052 :
1053 5 : void SwDocUpdateField::GetBodyNode( const SwSectionNode& rSectNd )
1054 : {
1055 5 : const SwDoc& rDoc = *rSectNd.GetDoc();
1056 5 : _SetGetExpField* pNew = 0;
1057 :
1058 5 : if( rSectNd.GetIndex() < rDoc.GetNodes().GetEndOfExtras().GetIndex() )
1059 : {
1060 : do { // middle check loop
1061 :
1062 : // we need to get the anchor first
1063 : // create index to determine the TextNode
1064 0 : SwPosition aPos( rSectNd );
1065 0 : SwContentNode* pCNd = rDoc.GetNodes().GoNext( &aPos.nNode ); // to the next ContentNode
1066 :
1067 0 : if( !pCNd || !pCNd->IsTextNode() )
1068 0 : break;
1069 :
1070 : // always the first! (in tab headline, header-/footer)
1071 0 : Point aPt;
1072 0 : const SwContentFrm* pFrm = pCNd->getLayoutFrm( rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
1073 0 : if( !pFrm )
1074 0 : break;
1075 :
1076 0 : bool const bResult = GetBodyTextNode( rDoc, aPos, *pFrm );
1077 : OSL_ENSURE(bResult, "where is the Field");
1078 : (void) bResult; // unused in non-debug
1079 0 : pNew = new _SetGetExpField( rSectNd, &aPos );
1080 :
1081 : } while( false );
1082 : }
1083 :
1084 5 : if( !pNew )
1085 5 : pNew = new _SetGetExpField( rSectNd );
1086 :
1087 5 : if( !pFieldSortLst->insert( pNew ).second )
1088 0 : delete pNew;
1089 5 : }
1090 :
1091 58 : void SwDocUpdateField::InsertFieldType( const SwFieldType& rType )
1092 : {
1093 58 : OUString sFieldName;
1094 58 : switch( rType.Which() )
1095 : {
1096 : case RES_USERFLD :
1097 28 : sFieldName = static_cast<const SwUserFieldType&>(rType).GetName();
1098 28 : break;
1099 : case RES_SETEXPFLD:
1100 30 : sFieldName = static_cast<const SwSetExpFieldType&>(rType).GetName();
1101 30 : break;
1102 : default:
1103 : OSL_ENSURE( false, "kein gueltiger FeldTyp" );
1104 : }
1105 :
1106 58 : if( !sFieldName.isEmpty() )
1107 : {
1108 56 : SetFieldsDirty( true );
1109 : // look up and remove from the hash table
1110 56 : sFieldName = GetAppCharClass().lowercase( sFieldName );
1111 : sal_uInt16 n;
1112 :
1113 56 : SwHash* pFnd = Find( sFieldName, GetFieldTypeTable(), TBLSZ, &n );
1114 :
1115 56 : if( !pFnd )
1116 : {
1117 56 : SwCalcFieldType* pNew = new SwCalcFieldType( sFieldName, &rType );
1118 56 : pNew->pNext = aFieldTypeTable[ n ];
1119 56 : aFieldTypeTable[ n ] = pNew;
1120 : }
1121 58 : }
1122 58 : }
1123 :
1124 0 : void SwDocUpdateField::RemoveFieldType( const SwFieldType& rType )
1125 : {
1126 0 : OUString sFieldName;
1127 0 : switch( rType.Which() )
1128 : {
1129 : case RES_USERFLD :
1130 0 : sFieldName = static_cast<const SwUserFieldType&>(rType).GetName();
1131 0 : break;
1132 : case RES_SETEXPFLD:
1133 0 : sFieldName = static_cast<const SwSetExpFieldType&>(rType).GetName();
1134 0 : break;
1135 : }
1136 :
1137 0 : if( !sFieldName.isEmpty() )
1138 : {
1139 0 : SetFieldsDirty( true );
1140 : // look up and remove from the hash table
1141 0 : sFieldName = GetAppCharClass().lowercase( sFieldName );
1142 : sal_uInt16 n;
1143 :
1144 0 : SwHash* pFnd = Find( sFieldName, GetFieldTypeTable(), TBLSZ, &n );
1145 0 : if( pFnd )
1146 : {
1147 0 : if( aFieldTypeTable[ n ] == pFnd )
1148 0 : aFieldTypeTable[ n ] = static_cast<SwCalcFieldType*>(pFnd->pNext);
1149 : else
1150 : {
1151 0 : SwHash* pPrev = aFieldTypeTable[ n ];
1152 0 : while( pPrev->pNext != pFnd )
1153 0 : pPrev = pPrev->pNext;
1154 0 : pPrev->pNext = pFnd->pNext;
1155 : }
1156 0 : pFnd->pNext = 0;
1157 0 : delete pFnd;
1158 : }
1159 0 : }
1160 0 : }
1161 :
1162 2958 : SwDocUpdateField::SwDocUpdateField(SwDoc* pDoc)
1163 : : pFieldSortLst(0)
1164 : , nNodes(0)
1165 : , nFieldLstGetMode(0)
1166 : , pDocument(pDoc)
1167 : , bInUpdateFields(false)
1168 2958 : , bFieldsDirty(false)
1169 :
1170 : {
1171 2958 : memset( aFieldTypeTable, 0, sizeof( aFieldTypeTable ) );
1172 2958 : }
1173 :
1174 2949 : SwDocUpdateField::~SwDocUpdateField()
1175 : {
1176 2949 : delete pFieldSortLst;
1177 :
1178 141552 : for( int n = 0; n < TBLSZ; ++n )
1179 138603 : delete aFieldTypeTable[n];
1180 3126 : }
1181 :
1182 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|