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