1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 28 #include <hintids.hxx> 29 30 #include <string.h> 31 #include <float.h> 32 #include <tools/datetime.hxx> 33 #ifndef _SVSTDARR_HXX 34 #define _SVSTDARR_ULONGS 35 #include <svl/svarray.hxx> 36 #endif 37 #include <vcl/svapp.hxx> 38 #include <vcl/svapp.hxx> 39 #include <unotools/charclass.hxx> 40 #include <unotools/transliterationwrapper.hxx> 41 #include <doc.hxx> 42 #include <IDocumentUndoRedo.hxx> 43 #include <cntfrm.hxx> 44 #include <pam.hxx> 45 #include <ndtxt.hxx> 46 #include <swtable.hxx> 47 #include <calc.hxx> 48 #include <txtfld.hxx> 49 #include <fmtfld.hxx> 50 #include <tox.hxx> 51 #include <txttxmrk.hxx> 52 #include <docfld.hxx> // fuer Expression-Felder 53 #include <docufld.hxx> 54 #include <ddefld.hxx> 55 #include <usrfld.hxx> 56 #include <expfld.hxx> 57 #include <dbfld.hxx> 58 #include <flddat.hxx> 59 #include <chpfld.hxx> 60 #include <reffld.hxx> 61 #include <flddropdown.hxx> 62 #include <dbmgr.hxx> 63 #include <section.hxx> 64 #include <cellatr.hxx> 65 #include <docary.hxx> 66 #include <authfld.hxx> 67 #include <txtinet.hxx> 68 #include <fmtcntnt.hxx> 69 #include <poolfmt.hrc> // fuer InitFldTypes 70 71 #include <SwUndoField.hxx> 72 #include "switerator.hxx" 73 74 using namespace ::com::sun::star::uno; 75 76 extern sal_Bool IsFrameBehind( const SwTxtNode& rMyNd, sal_uInt16 nMySttPos, 77 const SwTxtNode& rBehindNd, sal_uInt16 nSttPos ); 78 79 SV_IMPL_OP_PTRARR_SORT( _SetGetExpFlds, _SetGetExpFldPtr ) 80 81 82 /*-------------------------------------------------------------------- 83 Beschreibung: Feldtypen einfuegen 84 --------------------------------------------------------------------*/ 85 /* 86 * Implementierung der Feldfunktionen am Doc 87 * Return immer einen gueltigen Pointer auf den Typ. Wenn er also neu 88 * zugefuegt oder schon vorhanden ist. 89 */ 90 91 SwFieldType* SwDoc::InsertFldType(const SwFieldType &rFldTyp) 92 { 93 sal_uInt16 nSize = pFldTypes->Count(), 94 nFldWhich = rFldTyp.Which(); 95 96 sal_uInt16 i = INIT_FLDTYPES; 97 98 switch( nFldWhich ) 99 { 100 case RES_SETEXPFLD: 101 //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!! 102 // Sonst gibt es doppelte Nummernkreise!! 103 //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader 104 //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern 105 //hierauf 106 if( nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() ) 107 i -= INIT_SEQ_FLDTYPES; 108 // kein break; 109 case RES_DBFLD: 110 case RES_USERFLD: 111 case RES_DDEFLD: 112 { 113 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 114 String sFldNm( rFldTyp.GetName() ); 115 for( ; i < nSize; ++i ) 116 if( nFldWhich == (*pFldTypes)[i]->Which() && 117 rSCmp.isEqual( sFldNm, (*pFldTypes)[i]->GetName() )) 118 return (*pFldTypes)[i]; 119 } 120 break; 121 122 case RES_AUTHORITY: 123 for( ; i < nSize; ++i ) 124 if( nFldWhich == (*pFldTypes)[i]->Which() ) 125 return (*pFldTypes)[i]; 126 break; 127 128 default: 129 for( i = 0; i < nSize; ++i ) 130 if( nFldWhich == (*pFldTypes)[i]->Which() ) 131 return (*pFldTypes)[i]; 132 } 133 134 SwFieldType* pNew = rFldTyp.Copy(); 135 switch( nFldWhich ) 136 { 137 case RES_DDEFLD: 138 ((SwDDEFieldType*)pNew)->SetDoc( this ); 139 break; 140 141 case RES_DBFLD: 142 case RES_TABLEFLD: 143 case RES_DATETIMEFLD: 144 case RES_GETEXPFLD: 145 ((SwValueFieldType*)pNew)->SetDoc( this ); 146 break; 147 148 case RES_USERFLD: 149 case RES_SETEXPFLD: 150 ((SwValueFieldType*)pNew)->SetDoc( this ); 151 // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten: 152 pUpdtFlds->InsertFldType( *pNew ); 153 break; 154 case RES_AUTHORITY : 155 ((SwAuthorityFieldType*)pNew)->SetDoc( this ); 156 break; 157 } 158 159 pFldTypes->Insert( pNew, nSize ); 160 SetModified(); 161 162 return (*pFldTypes)[ nSize ]; 163 } 164 165 void SwDoc::InsDeletedFldType( SwFieldType& rFldTyp ) 166 { 167 // der FeldTyp wurde als geloescht gekennzeichnet und aus dem 168 // Array entfernt. Nun muss man nach diesem wieder suchen. 169 // - Ist der nicht vorhanden, dann kann er eingefuegt werden. 170 // - Wird genau der gleiche Typ gefunden, dann muss der geloeschte 171 // einen anderen Namen erhalten. 172 173 sal_uInt16 nSize = pFldTypes->Count(), nFldWhich = rFldTyp.Which(); 174 sal_uInt16 i = INIT_FLDTYPES; 175 176 ASSERT( RES_SETEXPFLD == nFldWhich || 177 RES_USERFLD == nFldWhich || 178 RES_DDEFLD == nFldWhich, "Falscher FeldTyp" ); 179 180 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 181 const String& rFldNm = rFldTyp.GetName(); 182 SwFieldType* pFnd; 183 184 for( ; i < nSize; ++i ) 185 if( nFldWhich == (pFnd = (*pFldTypes)[i])->Which() && 186 rSCmp.isEqual( rFldNm, pFnd->GetName() ) ) 187 { 188 // neuen Namen suchen 189 sal_uInt16 nNum = 1; 190 do { 191 String sSrch( rFldNm ); 192 sSrch.Append( String::CreateFromInt32( nNum )); 193 for( i = INIT_FLDTYPES; i < nSize; ++i ) 194 if( nFldWhich == (pFnd = (*pFldTypes)[i])->Which() && 195 rSCmp.isEqual( sSrch, pFnd->GetName() ) ) 196 break; 197 198 if( i >= nSize ) // nicht gefunden 199 { 200 ((String&)rFldNm) = sSrch; 201 break; // raus aus der While-Schleife 202 } 203 ++nNum; 204 } while( sal_True ); 205 break; 206 } 207 208 // nicht gefunden, also eintragen und Flag loeschen 209 pFldTypes->Insert( &rFldTyp, nSize ); 210 switch( nFldWhich ) 211 { 212 case RES_SETEXPFLD: 213 ((SwSetExpFieldType&)rFldTyp).SetDeleted( sal_False ); 214 break; 215 case RES_USERFLD: 216 ((SwUserFieldType&)rFldTyp).SetDeleted( sal_False ); 217 break; 218 case RES_DDEFLD: 219 ((SwDDEFieldType&)rFldTyp).SetDeleted( sal_False ); 220 break; 221 } 222 } 223 224 /*-------------------------------------------------------------------- 225 Beschreibung: Feldtypen loeschen 226 --------------------------------------------------------------------*/ 227 228 void SwDoc::RemoveFldType(sal_uInt16 nFld) 229 { 230 ASSERT( INIT_FLDTYPES <= nFld, "keine InitFields loeschen" ); 231 /* 232 * Abheangige Felder vorhanden -> ErrRaise 233 */ 234 sal_uInt16 nSize = pFldTypes->Count(); 235 if(nFld < nSize) 236 { 237 SwFieldType* pTmp = (*pFldTypes)[nFld]; 238 239 // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten: 240 sal_uInt16 nWhich = pTmp->Which(); 241 switch( nWhich ) 242 { 243 case RES_SETEXPFLD: 244 case RES_USERFLD: 245 pUpdtFlds->RemoveFldType( *pTmp ); 246 // kein break; 247 case RES_DDEFLD: 248 if( pTmp->GetDepends() && !IsUsed( *pTmp ) ) 249 { 250 if( RES_SETEXPFLD == nWhich ) 251 ((SwSetExpFieldType*)pTmp)->SetDeleted( sal_True ); 252 else if( RES_USERFLD == nWhich ) 253 ((SwUserFieldType*)pTmp)->SetDeleted( sal_True ); 254 else 255 ((SwDDEFieldType*)pTmp)->SetDeleted( sal_True ); 256 nWhich = 0; 257 } 258 break; 259 } 260 261 if( nWhich ) 262 { 263 ASSERT( !pTmp->GetDepends(), "Abhaengige vorh.!" ); 264 // Feldtype loschen 265 delete pTmp; 266 } 267 pFldTypes->Remove( nFld ); 268 SetModified(); 269 } 270 } 271 272 const SwFldTypes* SwDoc::GetFldTypes() const 273 { 274 return pFldTypes; 275 } 276 277 /*-------------------------------------------------------------------- 278 Beschreibung: Den ersten Typen mit ResId und Namen finden 279 --------------------------------------------------------------------*/ 280 281 SwFieldType* SwDoc::GetFldType( sal_uInt16 nResId, const String& rName, 282 bool bDbFieldMatching // used in some UNO calls for RES_DBFLD 283 // to use different string matching code 284 // #i51815# 285 ) const 286 { 287 sal_uInt16 nSize = pFldTypes->Count(), i = 0; 288 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 289 290 switch( nResId ) 291 { 292 case RES_SETEXPFLD: 293 //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!! 294 // Sonst gibt es doppelte Nummernkreise!! 295 //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader 296 //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern 297 //hierauf 298 i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES; 299 break; 300 301 case RES_DBFLD: 302 case RES_USERFLD: 303 case RES_DDEFLD: 304 case RES_AUTHORITY: 305 i = INIT_FLDTYPES; 306 break; 307 } 308 309 SwFieldType* pRet = 0; 310 for( ; i < nSize; ++i ) 311 { 312 SwFieldType* pFldType = (*pFldTypes)[i]; 313 314 String aFldName( pFldType->GetName() ); 315 if (bDbFieldMatching && nResId == RES_DBFLD) // #i51815# 316 aFldName.SearchAndReplaceAll(DB_DELIM, '.'); 317 318 if( nResId == pFldType->Which() && 319 rSCmp.isEqual( rName, aFldName )) 320 { 321 pRet = pFldType; 322 break; 323 } 324 } 325 return pRet; 326 } 327 328 329 /************************************************************************* 330 |* SwDoc::UpdateFlds() 331 |* Beschreibung Felder updaten 332 *************************************************************************/ 333 /* 334 * Alle sollen neu evaluiert werden. 335 */ 336 337 void SwDoc::UpdateFlds( SfxPoolItem *pNewHt, bool bCloseDB ) 338 { 339 // Modify() fuer jeden Feldtypen rufen, 340 // abhaengige SwTxtFld werden benachrichtigt ... 341 342 for( sal_uInt16 i=0; i < pFldTypes->Count(); ++i) 343 { 344 switch( (*pFldTypes)[i]->Which() ) 345 { 346 // Tabellen-Felder als vorletztes Updaten 347 // Referenzen als letztes Updaten 348 case RES_GETREFFLD: 349 case RES_TABLEFLD: 350 case RES_DBFLD: 351 case RES_JUMPEDITFLD: 352 case RES_REFPAGESETFLD: // werden nie expandiert! 353 break; 354 355 case RES_DDEFLD: 356 { 357 if( !pNewHt ) 358 { 359 SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL ); 360 (*pFldTypes)[i]->ModifyNotification( 0, &aUpdateDDE ); 361 } 362 else 363 (*pFldTypes)[i]->ModifyNotification( 0, pNewHt ); 364 break; 365 } 366 case RES_GETEXPFLD: 367 case RES_SETEXPFLD: 368 case RES_HIDDENTXTFLD: 369 case RES_HIDDENPARAFLD: 370 // Expression-Felder werden gesondert behandelt 371 if( !pNewHt ) 372 break; 373 default: 374 (*pFldTypes)[i]->ModifyNotification ( 0, pNewHt ); 375 } 376 } 377 378 if( !IsExpFldsLocked() ) 379 UpdateExpFlds( 0, sal_False ); // Expression-Felder Updaten 380 381 // Tabellen 382 UpdateTblFlds(pNewHt); 383 384 // Referenzen 385 UpdateRefFlds(pNewHt); 386 387 if( bCloseDB ) 388 GetNewDBMgr()->CloseAll(); 389 390 // Nur bei KomplettUpdate evaluieren 391 SetModified(); 392 } 393 394 /****************************************************************************** 395 * void SwDoc::UpdateUsrFlds() 396 ******************************************************************************/ 397 398 void SwDoc::UpdateUsrFlds() 399 { 400 SwCalc* pCalc = 0; 401 const SwFieldType* pFldType; 402 for( sal_uInt16 i = INIT_FLDTYPES; i < pFldTypes->Count(); ++i ) 403 if( RES_USERFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) 404 { 405 if( !pCalc ) 406 pCalc = new SwCalc( *this ); 407 ((SwUserFieldType*)pFldType)->GetValue( *pCalc ); 408 } 409 410 if( pCalc ) 411 { 412 delete pCalc; 413 SetModified(); 414 } 415 } 416 417 /*-------------------------------------------------------------------- 418 Beschreibung: Referenzfelder und TableFelder erneuern 419 --------------------------------------------------------------------*/ 420 421 void SwDoc::UpdateRefFlds( SfxPoolItem* pHt ) 422 { 423 SwFieldType* pFldType; 424 for( sal_uInt16 i = 0; i < pFldTypes->Count(); ++i ) 425 if( RES_GETREFFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) 426 pFldType->ModifyNotification( 0, pHt ); 427 } 428 429 void SwDoc::UpdateTblFlds( SfxPoolItem* pHt ) 430 { 431 ASSERT( !pHt || RES_TABLEFML_UPDATE == pHt->Which(), 432 "Was ist das fuer ein MessageItem?" ); 433 434 SwFieldType* pFldType(0); 435 436 for (sal_uInt16 i = 0; i < pFldTypes->Count(); ++i) 437 { 438 if( RES_TABLEFLD == ( pFldType = (*pFldTypes)[i] )->Which() ) 439 { 440 SwTableFmlUpdate* pUpdtFld = 0; 441 if( pHt && RES_TABLEFML_UPDATE == pHt->Which() ) 442 pUpdtFld = (SwTableFmlUpdate*)pHt; 443 444 SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType ); 445 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 446 { 447 if( pFmtFld->GetTxtFld() ) 448 { 449 SwTblField* pFld = (SwTblField*)pFmtFld->GetField(); 450 451 if( pUpdtFld ) 452 { 453 // bestimme Tabelle, in der das Feld steht 454 const SwTableNode* pTblNd; 455 const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode(); 456 if( !rTxtNd.GetNodes().IsDocNodes() || 457 0 == ( pTblNd = rTxtNd.FindTableNode() ) ) 458 continue; 459 460 switch( pUpdtFld->eFlags ) 461 { 462 case TBL_CALC: 463 // setze das Value-Flag zurueck 464 // JP 17.06.96: interne Darstellung auf alle Formeln 465 // (Referenzen auf andere Tabellen!!!) 466 if( nsSwExtendedSubType::SUB_CMD & pFld->GetSubType() ) 467 pFld->PtrToBoxNm( pUpdtFld->pTbl ); 468 else 469 pFld->ChgValid( sal_False ); 470 break; 471 case TBL_BOXNAME: 472 // ist es die gesuchte Tabelle ?? 473 if( &pTblNd->GetTable() == pUpdtFld->pTbl ) 474 // zur externen Darstellung 475 pFld->PtrToBoxNm( pUpdtFld->pTbl ); 476 break; 477 case TBL_BOXPTR: 478 // zur internen Darstellung 479 // JP 17.06.96: interne Darstellung auf alle Formeln 480 // (Referenzen auf andere Tabellen!!!) 481 pFld->BoxNmToPtr( pUpdtFld->pTbl ); 482 break; 483 case TBL_RELBOXNAME: 484 // ist es die gesuchte Tabelle ?? 485 if( &pTblNd->GetTable() == pUpdtFld->pTbl ) 486 // zur relativen Darstellung 487 pFld->ToRelBoxNm( pUpdtFld->pTbl ); 488 break; 489 default: 490 break; 491 } 492 } 493 else 494 // setze bei allen das Value-Flag zurueck 495 pFld->ChgValid( sal_False ); 496 } 497 } 498 499 break; 500 } 501 pFldType = 0; 502 } 503 504 // und dann noch alle Tabellen Box Formeln abklappern 505 const SfxPoolItem* pItem; 506 sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA ); 507 for (sal_uInt32 i = 0; i < nMaxItems; ++i) 508 { 509 if( 0 != (pItem = GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) && 510 ((SwTblBoxFormula*)pItem)->GetDefinedIn() ) 511 { 512 ((SwTblBoxFormula*)pItem)->ChangeState( pHt ); 513 } 514 } 515 516 517 // alle Felder/Boxen sind jetzt invalide, also kann das Rechnen anfangen 518 if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() || 519 TBL_CALC != ((SwTableFmlUpdate*)pHt)->eFlags )) 520 return ; 521 522 SwCalc* pCalc = 0; 523 524 if( pFldType ) 525 { 526 SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType ); 527 for( SwFmtFld* pFmtFld = aIter.Last(); pFmtFld; pFmtFld = aIter.Previous() ) 528 { 529 // start calculation at the end 530 // new fields are inserted at the beginning of the modify chain 531 // that gives faster calculation on import 532 // mba: do we really need this "optimization"? Is it still valid? 533 SwTblField* pFld; 534 if( !pFmtFld->GetTxtFld() || (nsSwExtendedSubType::SUB_CMD & 535 (pFld = (SwTblField*)pFmtFld->GetField())->GetSubType() )) 536 continue; 537 538 // muss neu berechnet werden (und ist keine textuelle Anzeige) 539 if( !pFld->IsValid() ) 540 { 541 // bestimme Tabelle, in der das Feld steht 542 const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode(); 543 if( !rTxtNd.GetNodes().IsDocNodes() ) 544 continue; 545 const SwTableNode* pTblNd = rTxtNd.FindTableNode(); 546 if( !pTblNd ) 547 continue; 548 549 // falls dieses Feld nicht in der zu updatenden 550 // Tabelle steht, ueberspringen !! 551 if( pHt && &pTblNd->GetTable() != 552 ((SwTableFmlUpdate*)pHt)->pTbl ) 553 continue; 554 555 if( !pCalc ) 556 pCalc = new SwCalc( *this ); 557 558 // bestimme die Werte aller SetExpresion Felder, die 559 // bis zur Tabelle gueltig sind 560 SwFrm* pFrm = 0; 561 if( pTblNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) 562 { 563 // steht im Sonderbereich, wird teuer !! 564 Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! 565 pFrm = rTxtNd.getLayoutFrm( GetCurrentLayout(), &aPt ); 566 if( pFrm ) 567 { 568 SwPosition aPos( *pTblNd ); 569 if( GetBodyTxtNode( *this, aPos, *pFrm ) ) 570 FldsToCalc( *pCalc, _SetGetExpFld( 571 aPos.nNode, pFmtFld->GetTxtFld(), 572 &aPos.nContent )); 573 else 574 pFrm = 0; 575 } 576 } 577 if( !pFrm ) 578 { 579 // einen Index fuers bestimmen vom TextNode anlegen 580 SwNodeIndex aIdx( rTxtNd ); 581 FldsToCalc( *pCalc, 582 _SetGetExpFld( aIdx, pFmtFld->GetTxtFld() )); 583 } 584 585 SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() ); 586 pFld->CalcField( aPara ); 587 if( aPara.IsStackOverFlow() ) 588 { 589 if( aPara.CalcWithStackOverflow() ) 590 pFld->CalcField( aPara ); 591 #ifdef DBG_UTIL 592 else 593 { 594 // mind. ein ASSERT 595 ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" ); 596 } 597 #endif 598 } 599 pCalc->SetCalcError( CALC_NOERR ); 600 } 601 pFmtFld->ModifyNotification( 0, pHt ); 602 } 603 } 604 605 // dann berechene noch die Formeln an den Boxen 606 for (sal_uInt32 i = 0; i < nMaxItems; ++i ) 607 { 608 if( 0 != (pItem = GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) && 609 ((SwTblBoxFormula*)pItem)->GetDefinedIn() && 610 !((SwTblBoxFormula*)pItem)->IsValid() ) 611 { 612 SwTblBoxFormula* pFml = (SwTblBoxFormula*)pItem; 613 SwTableBox* pBox = pFml->GetTableBox(); 614 if( pBox && pBox->GetSttNd() && 615 pBox->GetSttNd()->GetNodes().IsDocNodes() ) 616 { 617 const SwTableNode* pTblNd = pBox->GetSttNd()->FindTableNode(); 618 if( !pHt || &pTblNd->GetTable() == 619 ((SwTableFmlUpdate*)pHt)->pTbl ) 620 { 621 double nValue; 622 if( !pCalc ) 623 pCalc = new SwCalc( *this ); 624 625 // bestimme die Werte aller SetExpresion Felder, die 626 // bis zur Tabelle gueltig sind 627 SwFrm* pFrm = 0; 628 if( pTblNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) 629 { 630 // steht im Sonderbereich, wird teuer !! 631 Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! 632 SwNodeIndex aCNdIdx( *pTblNd, +2 ); 633 SwCntntNode* pCNd = aCNdIdx.GetNode().GetCntntNode(); 634 if( !pCNd ) 635 pCNd = GetNodes().GoNext( &aCNdIdx ); 636 637 if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( GetCurrentLayout(), &aPt )) ) 638 { 639 SwPosition aPos( *pCNd ); 640 if( GetBodyTxtNode( *this, aPos, *pFrm ) ) 641 FldsToCalc( *pCalc, _SetGetExpFld( aPos.nNode )); 642 else 643 pFrm = 0; 644 } 645 } 646 if( !pFrm ) 647 { 648 // einen Index fuers bestimmen vom TextNode anlegen 649 SwNodeIndex aIdx( *pTblNd ); 650 FldsToCalc( *pCalc, _SetGetExpFld( aIdx )); 651 } 652 653 SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() ); 654 pFml->Calc( aPara, nValue ); 655 656 if( aPara.IsStackOverFlow() ) 657 { 658 if( aPara.CalcWithStackOverflow() ) 659 pFml->Calc( aPara, nValue ); 660 #ifdef DBG_UTIL 661 else 662 { 663 // mind. ein ASSERT 664 ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" ); 665 } 666 #endif 667 } 668 669 SwFrmFmt* pFmt = pBox->ClaimFrmFmt(); 670 SfxItemSet aTmp( GetAttrPool(), 671 RES_BOXATR_BEGIN,RES_BOXATR_END-1 ); 672 673 if( pCalc->IsCalcError() ) 674 nValue = DBL_MAX; 675 aTmp.Put( SwTblBoxValue( nValue )); 676 if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT )) 677 aTmp.Put( SwTblBoxNumFormat( 0 )); 678 pFmt->SetFmtAttr( aTmp ); 679 680 pCalc->SetCalcError( CALC_NOERR ); 681 } 682 } 683 } 684 } 685 686 if( pCalc ) 687 delete pCalc; 688 } 689 690 void SwDoc::UpdatePageFlds( SfxPoolItem* pMsgHnt ) 691 { 692 SwFieldType* pFldType; 693 for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i ) 694 switch( ( pFldType = (*pFldTypes)[ i ] )->Which() ) 695 { 696 case RES_PAGENUMBERFLD: 697 case RES_CHAPTERFLD: 698 case RES_GETEXPFLD: 699 case RES_REFPAGEGETFLD: 700 pFldType->ModifyNotification( 0, pMsgHnt ); 701 break; 702 case RES_DOCSTATFLD: 703 pFldType->ModifyNotification( 0, 0 ); 704 break; 705 } 706 SetNewFldLst(true); 707 } 708 709 /*-------------------------------------------------------------------- 710 Beschreibung: 711 --------------------------------------------------------------------*/ 712 713 // ---- Loesche alle nicht referenzierten FeldTypen eines Dokumentes -- 714 void SwDoc::GCFieldTypes() 715 { 716 for( sal_uInt16 n = pFldTypes->Count(); n > INIT_FLDTYPES; ) 717 if( !(*pFldTypes)[ --n ]->GetDepends() ) 718 RemoveFldType( n ); 719 } 720 721 void SwDoc::LockExpFlds() 722 { 723 ++nLockExpFld; 724 } 725 726 void SwDoc::UnlockExpFlds() 727 { 728 if( nLockExpFld ) 729 --nLockExpFld; 730 } 731 732 bool SwDoc::IsExpFldsLocked() const 733 { 734 return 0 != nLockExpFld; 735 } 736 737 SwDocUpdtFld& SwDoc::GetUpdtFlds() const 738 { 739 return *pUpdtFlds; 740 } 741 742 bool SwDoc::IsNewFldLst() const 743 { 744 return mbNewFldLst; 745 } 746 747 void SwDoc::SetNewFldLst(bool bFlag) 748 { 749 mbNewFldLst = bFlag; 750 } 751 752 753 //---------------------------------------------------------------------- 754 755 // der StartIndex kann optional mit angegeben werden (z.B. wenn dieser 756 // zuvor schon mal erfragt wurde - ist sonst eine virtuelle Methode !!) 757 758 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld, 759 const SwIndex* pIdx ) 760 { 761 eSetGetExpFldType = TEXTFIELD; 762 CNTNT.pTxtFld = pFld; 763 nNode = rNdIdx.GetIndex(); 764 if( pIdx ) 765 nCntnt = pIdx->GetIndex(); 766 else if( pFld ) 767 nCntnt = *pFld->GetStart(); 768 else 769 nCntnt = 0; 770 } 771 772 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex& rNdIdx, 773 const SwTxtINetFmt& rINet, const SwIndex* pIdx ) 774 { 775 eSetGetExpFldType = TEXTINET; 776 CNTNT.pTxtINet = &rINet; 777 nNode = rNdIdx.GetIndex(); 778 if( pIdx ) 779 nCntnt = pIdx->GetIndex(); 780 else 781 nCntnt = *rINet.GetStart(); 782 } 783 784 //Erweiterung fuer Sections: 785 // diese haben immer als Content-Position 0xffff !! 786 // Auf dieser steht nie ein Feld, maximal bis STRING_MAXLEN moeglich 787 _SetGetExpFld::_SetGetExpFld( const SwSectionNode& rSectNd, 788 const SwPosition* pPos ) 789 { 790 eSetGetExpFldType = SECTIONNODE; 791 CNTNT.pSection = &rSectNd.GetSection(); 792 793 if( pPos ) 794 { 795 nNode = pPos->nNode.GetIndex(); 796 nCntnt = pPos->nContent.GetIndex(); 797 } 798 else 799 { 800 nNode = rSectNd.GetIndex(); 801 nCntnt = 0; 802 } 803 } 804 805 _SetGetExpFld::_SetGetExpFld( const SwTableBox& rTBox, const SwPosition* pPos ) 806 { 807 eSetGetExpFldType = TABLEBOX; 808 CNTNT.pTBox = &rTBox; 809 810 if( pPos ) 811 { 812 nNode = pPos->nNode.GetIndex(); 813 nCntnt = pPos->nContent.GetIndex(); 814 } 815 else 816 { 817 nNode = 0; 818 nCntnt = 0; 819 if( rTBox.GetSttNd() ) 820 { 821 SwNodeIndex aIdx( *rTBox.GetSttNd() ); 822 const SwCntntNode* pNd = aIdx.GetNode().GetNodes().GoNext( &aIdx ); 823 if( pNd ) 824 nNode = pNd->GetIndex(); 825 } 826 } 827 } 828 829 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex& rNdIdx, 830 const SwTxtTOXMark& rTOX, 831 const SwIndex* pIdx ) 832 { 833 eSetGetExpFldType = TEXTTOXMARK; 834 CNTNT.pTxtTOX = &rTOX; 835 nNode = rNdIdx.GetIndex(); 836 if( pIdx ) 837 nCntnt = pIdx->GetIndex(); 838 else 839 nCntnt = *rTOX.GetStart(); 840 } 841 842 _SetGetExpFld::_SetGetExpFld( const SwPosition& rPos ) 843 { 844 eSetGetExpFldType = CRSRPOS; 845 CNTNT.pPos = &rPos; 846 nNode = rPos.nNode.GetIndex(); 847 nCntnt = rPos.nContent.GetIndex(); 848 } 849 850 _SetGetExpFld::_SetGetExpFld( const SwFlyFrmFmt& rFlyFmt, 851 const SwPosition* pPos ) 852 { 853 eSetGetExpFldType = FLYFRAME; 854 CNTNT.pFlyFmt = &rFlyFmt; 855 if( pPos ) 856 { 857 nNode = pPos->nNode.GetIndex(); 858 nCntnt = pPos->nContent.GetIndex(); 859 } 860 else 861 { 862 const SwFmtCntnt& rCntnt = rFlyFmt.GetCntnt(); 863 nNode = rCntnt.GetCntntIdx()->GetIndex() + 1; 864 nCntnt = 0; 865 } 866 } 867 868 void _SetGetExpFld::GetPos( SwPosition& rPos ) const 869 { 870 rPos.nNode = nNode; 871 rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt ); 872 } 873 874 void _SetGetExpFld::GetPosOfContent( SwPosition& rPos ) const 875 { 876 const SwNode* pNd = GetNodeFromCntnt(); 877 if( pNd ) 878 pNd = pNd->GetCntntNode(); 879 880 if( pNd ) 881 { 882 rPos.nNode = *pNd; 883 rPos.nContent.Assign( (SwCntntNode*)pNd,GetCntPosFromCntnt() ); 884 } 885 else 886 { 887 rPos.nNode = nNode; 888 rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), nCntnt ); 889 } 890 } 891 892 void _SetGetExpFld::SetBodyPos( const SwCntntFrm& rFrm ) 893 { 894 if( !rFrm.IsInDocBody() ) 895 { 896 SwNodeIndex aIdx( *rFrm.GetNode() ); 897 SwDoc& rDoc = *aIdx.GetNodes().GetDoc(); 898 SwPosition aPos( aIdx ); 899 #ifdef DBG_UTIL 900 ASSERT( ::GetBodyTxtNode( rDoc, aPos, rFrm ), "wo steht das Feld" ); 901 #else 902 ::GetBodyTxtNode( rDoc, aPos, rFrm ); 903 #endif 904 nNode = aPos.nNode.GetIndex(); 905 nCntnt = aPos.nContent.GetIndex(); 906 } 907 } 908 909 sal_Bool _SetGetExpFld::operator<( const _SetGetExpFld& rFld ) const 910 { 911 if( nNode < rFld.nNode || ( nNode == rFld.nNode && nCntnt < rFld.nCntnt )) 912 return sal_True; 913 else if( nNode != rFld.nNode || nCntnt != rFld.nCntnt ) 914 return sal_False; 915 916 const SwNode *pFirst = GetNodeFromCntnt(), 917 *pNext = rFld.GetNodeFromCntnt(); 918 919 // Position gleich: nur weiter wenn beide FeldPointer besetzt sind !! 920 if( !pFirst || !pNext ) 921 return sal_False; 922 923 // gleiche Section ?? 924 if( pFirst->StartOfSectionNode() != pNext->StartOfSectionNode() ) 925 { 926 // sollte einer in der Tabelle stehen ? 927 const SwNode *pFirstStt, *pNextStt; 928 const SwTableNode* pTblNd = pFirst->FindTableNode(); 929 if( pTblNd ) 930 pFirstStt = pTblNd->StartOfSectionNode(); 931 else 932 pFirstStt = pFirst->StartOfSectionNode(); 933 934 if( 0 != ( pTblNd = pNext->FindTableNode() ) ) 935 pNextStt = pTblNd->StartOfSectionNode(); 936 else 937 pNextStt = pNext->StartOfSectionNode(); 938 939 if( pFirstStt != pNextStt ) 940 { 941 if( pFirst->IsTxtNode() && pNext->IsTxtNode() && 942 ( pFirst->FindFlyStartNode() || pNext->FindFlyStartNode() )) 943 { 944 return ::IsFrameBehind( *(SwTxtNode*)pNext, nCntnt, 945 *(SwTxtNode*)pFirst, nCntnt ); 946 } 947 return pFirstStt->GetIndex() < pNextStt->GetIndex(); 948 } 949 } 950 951 // ist gleiche Section, dann Feld im gleichen Node ? 952 if( pFirst != pNext ) 953 return pFirst->GetIndex() < pNext->GetIndex(); 954 955 // gleicher Node in der Section, dann Position im Node 956 return GetCntPosFromCntnt() < rFld.GetCntPosFromCntnt(); 957 } 958 959 const SwNode* _SetGetExpFld::GetNodeFromCntnt() const 960 { 961 const SwNode* pRet = 0; 962 if( CNTNT.pTxtFld ) 963 switch( eSetGetExpFldType ) 964 { 965 case TEXTFIELD: 966 pRet = &CNTNT.pTxtFld->GetTxtNode(); 967 break; 968 969 case TEXTINET: 970 pRet = &CNTNT.pTxtINet->GetTxtNode(); 971 break; 972 973 case SECTIONNODE: 974 pRet = CNTNT.pSection->GetFmt()->GetSectionNode(); 975 break; 976 977 case CRSRPOS: 978 pRet = &CNTNT.pPos->nNode.GetNode(); 979 break; 980 981 case TEXTTOXMARK: 982 pRet = &CNTNT.pTxtTOX->GetTxtNode(); 983 break; 984 985 case TABLEBOX: 986 if( CNTNT.pTBox->GetSttNd() ) 987 { 988 SwNodeIndex aIdx( *CNTNT.pTBox->GetSttNd() ); 989 pRet = aIdx.GetNode().GetNodes().GoNext( &aIdx ); 990 } 991 break; 992 993 case FLYFRAME: 994 { 995 SwNodeIndex aIdx( *CNTNT.pFlyFmt->GetCntnt().GetCntntIdx() ); 996 pRet = aIdx.GetNode().GetNodes().GoNext( &aIdx ); 997 } 998 break; 999 } 1000 return pRet; 1001 } 1002 1003 xub_StrLen _SetGetExpFld::GetCntPosFromCntnt() const 1004 { 1005 sal_uInt16 nRet = 0; 1006 if( CNTNT.pTxtFld ) 1007 switch( eSetGetExpFldType ) 1008 { 1009 case TEXTFIELD: 1010 case TEXTINET: 1011 case TEXTTOXMARK: 1012 nRet = *CNTNT.pTxtFld->GetStart(); 1013 break; 1014 case CRSRPOS: 1015 nRet = CNTNT.pPos->nContent.GetIndex(); 1016 break; 1017 default: 1018 break; 1019 } 1020 return nRet; 1021 } 1022 1023 _HashStr::_HashStr( const String& rName, const String& rText, 1024 _HashStr* pNxt ) 1025 : SwHash( rName ), aSetStr( rText ) 1026 { 1027 pNext = pNxt; 1028 } 1029 1030 // suche nach dem Namen, ist er vorhanden, returne seinen String, sonst 1031 // einen LeerString 1032 void LookString( SwHash** ppTbl, sal_uInt16 nSize, const String& rName, 1033 String& rRet, sal_uInt16* pPos ) 1034 { 1035 rRet = rName; 1036 rRet.EraseLeadingChars().EraseTrailingChars(); 1037 SwHash* pFnd = Find( rRet, ppTbl, nSize, pPos ); 1038 if( pFnd ) 1039 rRet = ((_HashStr*)pFnd)->aSetStr; 1040 else 1041 rRet.Erase(); 1042 } 1043 1044 /*-------------------------------------------------------------------- 1045 Beschreibung: 1046 --------------------------------------------------------------------*/ 1047 1048 String lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBFld ) 1049 { 1050 SwDBData aDBData( rDBFld.GetDBData( &rDoc )); 1051 String sDBNumNm; 1052 SwDBData aDocData = rDoc.GetDBData(); 1053 1054 if( aDBData != aDocData ) 1055 { 1056 sDBNumNm = aDBData.sDataSource; 1057 sDBNumNm += DB_DELIM; 1058 sDBNumNm += String(aDBData.sCommand); 1059 sDBNumNm += DB_DELIM; 1060 } 1061 sDBNumNm += SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD); 1062 1063 return sDBNumNm; 1064 } 1065 1066 /*-------------------------------------------------------------------- 1067 Beschreibung: 1068 --------------------------------------------------------------------*/ 1069 1070 void lcl_CalcFld( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpFld& rSGEFld, 1071 SwNewDBMgr* pMgr ) 1072 { 1073 const SwTxtFld* pTxtFld = rSGEFld.GetTxtFld(); 1074 if( !pTxtFld ) 1075 return ; 1076 1077 const SwField* pFld = pTxtFld->GetFmtFld().GetField(); 1078 const sal_uInt16 nFldWhich = pFld->GetTyp()->Which(); 1079 1080 if( RES_SETEXPFLD == nFldWhich ) 1081 { 1082 SwSbxValue aValue; 1083 if( nsSwGetSetExpType::GSE_EXPR & pFld->GetSubType() ) 1084 aValue.PutDouble( ((SwSetExpField*)pFld)->GetValue() ); 1085 else 1086 // Erweiterung fuers Rechnen mit Strings 1087 aValue.PutString( ((SwSetExpField*)pFld)->GetExpStr() ); 1088 1089 // setze im Calculator den neuen Wert 1090 rCalc.VarChange( pFld->GetTyp()->GetName(), aValue ); 1091 } 1092 else if( pMgr ) 1093 { 1094 switch( nFldWhich ) 1095 { 1096 case RES_DBNUMSETFLD: 1097 { 1098 SwDBNumSetField* pDBFld = (SwDBNumSetField*)pFld; 1099 1100 SwDBData aDBData(pDBFld->GetDBData(&rDoc)); 1101 1102 if( pDBFld->IsCondValid() && 1103 pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand )) 1104 rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBFld), 1105 pDBFld->GetFormat() ); 1106 } 1107 break; 1108 case RES_DBNEXTSETFLD: 1109 { 1110 SwDBNextSetField* pDBFld = (SwDBNextSetField*)pFld; 1111 SwDBData aDBData(pDBFld->GetDBData(&rDoc)); 1112 if( !pDBFld->IsCondValid() || 1113 !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand )) 1114 break; 1115 1116 String sDBNumNm(lcl_GetDBVarName( rDoc, *pDBFld)); 1117 SwCalcExp* pExp = rCalc.VarLook( sDBNumNm ); 1118 if( pExp ) 1119 rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 ); 1120 } 1121 break; 1122 1123 } 1124 } 1125 } 1126 1127 void SwDoc::FldsToCalc( SwCalc& rCalc, const _SetGetExpFld& rToThisFld ) 1128 { 1129 // erzeuge die Sortierteliste aller SetFelder 1130 pUpdtFlds->MakeFldList( *this, mbNewFldLst, GETFLD_CALC ); 1131 mbNewFldLst = sal_False; 1132 1133 SwNewDBMgr* pMgr = GetNewDBMgr(); 1134 pMgr->CloseAll(sal_False); 1135 1136 if( pUpdtFlds->GetSortLst()->Count() ) 1137 { 1138 sal_uInt16 nLast; 1139 _SetGetExpFld* pFld = (_SetGetExpFld*)&rToThisFld; 1140 if( pUpdtFlds->GetSortLst()->Seek_Entry( pFld, &nLast ) ) 1141 ++nLast; 1142 1143 const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); 1144 for( sal_uInt16 n = 0; n < nLast; ++n, ++ppSortLst ) 1145 lcl_CalcFld( *this, rCalc, **ppSortLst, pMgr ); 1146 } 1147 1148 pMgr->CloseAll(sal_False); 1149 } 1150 1151 void SwDoc::FldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt ) 1152 { 1153 // erzeuge die Sortierteliste aller SetFelder 1154 pUpdtFlds->MakeFldList( *this, mbNewFldLst, GETFLD_CALC ); 1155 mbNewFldLst = sal_False; 1156 1157 SwNewDBMgr* pMgr = GetNewDBMgr(); 1158 pMgr->CloseAll(sal_False); 1159 1160 const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); 1161 1162 for( sal_uInt16 n = pUpdtFlds->GetSortLst()->Count(); 1163 n && 1164 ( (*ppSortLst)->GetNode() < nLastNd || 1165 ( (*ppSortLst)->GetNode() == nLastNd && (*ppSortLst)->GetCntnt() <= nLastCnt ) 1166 ); 1167 --n, ++ppSortLst ) 1168 lcl_CalcFld( *this, rCalc, **ppSortLst, pMgr ); 1169 1170 pMgr->CloseAll(sal_False); 1171 } 1172 1173 void SwDoc::FldsToExpand( SwHash**& ppHashTbl, sal_uInt16& rTblSize, 1174 const _SetGetExpFld& rToThisFld ) 1175 { 1176 // erzeuge die Sortierteliste aller SetFelder 1177 pUpdtFlds->MakeFldList( *this, mbNewFldLst, GETFLD_EXPAND ); 1178 mbNewFldLst = sal_False; 1179 1180 // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt 1181 // (versuche eine "ungerade"-Zahl zu erzeugen) 1182 rTblSize = (( pUpdtFlds->GetSortLst()->Count() / 7 ) + 1 ) * 7; 1183 ppHashTbl = new SwHash*[ rTblSize ]; 1184 memset( ppHashTbl, 0, sizeof( _HashStr* ) * rTblSize ); 1185 1186 sal_uInt16 nLast; 1187 { 1188 _SetGetExpFld* pTmp = (_SetGetExpFld*)&rToThisFld; 1189 if( pUpdtFlds->GetSortLst()->Seek_Entry( pTmp, &nLast ) ) 1190 ++nLast; 1191 } 1192 1193 sal_uInt16 nPos; 1194 SwHash* pFnd; 1195 String aNew; 1196 const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); 1197 for( ; nLast; --nLast, ++ppSortLst ) 1198 { 1199 const SwTxtFld* pTxtFld = (*ppSortLst)->GetTxtFld(); 1200 if( !pTxtFld ) 1201 continue; 1202 1203 const SwField* pFld = pTxtFld->GetFmtFld().GetField(); 1204 switch( pFld->GetTyp()->Which() ) 1205 { 1206 case RES_SETEXPFLD: 1207 if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() ) 1208 { 1209 // setze in der HashTabelle den neuen Wert 1210 // ist die "Formel" ein Feld ?? 1211 SwSetExpField* pSFld = (SwSetExpField*)pFld; 1212 LookString( ppHashTbl, rTblSize, pSFld->GetFormula(), aNew ); 1213 1214 if( !aNew.Len() ) // nichts gefunden, dann ist 1215 aNew = pSFld->GetFormula(); // die Formel der neue Wert 1216 1217 // OD 11.02.2003 #i3141# - update expression of field as in 1218 // method <SwDoc::UpdateExpFlds(..)> for string/text fields 1219 pSFld->ChgExpStr( aNew ); 1220 1221 // suche den Namen vom Feld 1222 aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName(); 1223 // Eintrag vorhanden ? 1224 pFnd = Find( aNew, ppHashTbl, rTblSize, &nPos ); 1225 if( pFnd ) 1226 // Eintrag in der HashTabelle aendern 1227 ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr(); 1228 else 1229 // neuen Eintrag einfuegen 1230 *(ppHashTbl + nPos ) = new _HashStr( aNew, 1231 pSFld->GetExpStr(), (_HashStr*)*(ppHashTbl + nPos) ); 1232 } 1233 break; 1234 case RES_DBFLD: 1235 { 1236 const String& rName = pFld->GetTyp()->GetName(); 1237 1238 // Eintrag in den HashTable eintragen 1239 // Eintrag vorhanden ? 1240 pFnd = Find( rName, ppHashTbl, rTblSize, &nPos ); 1241 String const value(pFld->ExpandField(IsClipBoard())); 1242 if( pFnd ) 1243 { 1244 // Eintrag in der HashTabelle aendern 1245 static_cast<_HashStr*>(pFnd)->aSetStr = value; 1246 } 1247 else 1248 { 1249 // neuen Eintrag einfuegen 1250 *(ppHashTbl + nPos ) = new _HashStr( rName, 1251 value, static_cast<_HashStr *>(*(ppHashTbl + nPos))); 1252 } 1253 } 1254 break; 1255 } 1256 } 1257 } 1258 1259 1260 void SwDoc::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds ) 1261 { 1262 if( IsExpFldsLocked() || IsInReading() ) 1263 return; 1264 1265 sal_Bool bOldInUpdateFlds = pUpdtFlds->IsInUpdateFlds(); 1266 pUpdtFlds->SetInUpdateFlds( sal_True ); 1267 1268 pUpdtFlds->MakeFldList( *this, sal_True, GETFLD_ALL ); 1269 mbNewFldLst = sal_False; 1270 1271 if( !pUpdtFlds->GetSortLst()->Count() ) 1272 { 1273 if( bUpdRefFlds ) 1274 UpdateRefFlds(NULL); 1275 1276 pUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds ); 1277 pUpdtFlds->SetFieldsDirty( sal_False ); 1278 return ; 1279 } 1280 1281 sal_uInt16 nWhich, n; 1282 1283 // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt 1284 // (versuche eine "ungerade"-Zahl zu erzeugen) 1285 sal_uInt16 nStrFmtCnt = (( pFldTypes->Count() / 7 ) + 1 ) * 7; 1286 SwHash** pHashStrTbl = new SwHash*[ nStrFmtCnt ]; 1287 memset( pHashStrTbl, 0, sizeof( _HashStr* ) * nStrFmtCnt ); 1288 1289 { 1290 const SwFieldType* pFldType; 1291 // gesondert behandeln: 1292 for( n = pFldTypes->Count(); n; ) 1293 switch( ( pFldType = (*pFldTypes)[ --n ] )->Which() ) 1294 { 1295 case RES_USERFLD: 1296 { 1297 // Eintrag vorhanden ? 1298 sal_uInt16 nPos; 1299 const String& rNm = pFldType->GetName(); 1300 String sExpand(((SwUserFieldType*)pFldType)->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0)); 1301 SwHash* pFnd = Find( rNm, pHashStrTbl, nStrFmtCnt, &nPos ); 1302 if( pFnd ) 1303 // Eintrag in der HashTabelle aendern ?? 1304 ((_HashStr*)pFnd)->aSetStr = sExpand; 1305 else 1306 // neuen Eintrag einfuegen 1307 *(pHashStrTbl + nPos ) = new _HashStr( rNm, sExpand, 1308 (_HashStr*)*(pHashStrTbl + nPos) ); 1309 } 1310 break; 1311 case RES_SETEXPFLD: 1312 ((SwSetExpFieldType*)pFldType)->SetOutlineChgNd( 0 ); 1313 break; 1314 } 1315 } 1316 1317 // Ok, das Array ist soweit mit allen Feldern gefuellt, dann rechne mal 1318 SwCalc aCalc( *this ); 1319 1320 String sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) ); 1321 1322 // aktuelle Datensatznummer schon vorher einstellen 1323 SwNewDBMgr* pMgr = GetNewDBMgr(); 1324 pMgr->CloseAll(sal_False); 1325 /* 1326 if(pMgr && pMgr->OpenDB(DBMGR_STD, GetDBDesc(), sal_False)) 1327 { 1328 if(!pMgr->IsInMerge() ) 1329 pMgr->ToFirstSelectedRecord(DBMGR_STD); 1330 1331 aCalc.VarChange( sDBNumNm, pMgr->GetCurSelectedRecordId(DBMGR_STD)); 1332 } 1333 */ 1334 1335 String aNew; 1336 const _SetGetExpFldPtr* ppSortLst = pUpdtFlds->GetSortLst()->GetData(); 1337 for( n = pUpdtFlds->GetSortLst()->Count(); n; --n, ++ppSortLst ) 1338 { 1339 SwSection* pSect = (SwSection*)(*ppSortLst)->GetSection(); 1340 if( pSect ) 1341 { 1342 //!SECTION 1343 1344 SwSbxValue aValue = aCalc.Calculate( 1345 pSect->GetCondition() ); 1346 if(!aValue.IsVoidValue()) 1347 pSect->SetCondHidden( aValue.GetBool() ); 1348 continue; 1349 } 1350 1351 SwTxtFld* pTxtFld = (SwTxtFld*)(*ppSortLst)->GetTxtFld(); 1352 if( !pTxtFld ) 1353 { 1354 ASSERT( !this, "was ist es denn nun" ); 1355 continue; 1356 } 1357 1358 SwFmtFld* pFmtFld = (SwFmtFld*)&pTxtFld->GetFmtFld(); 1359 const SwField* pFld = pFmtFld->GetField(); 1360 1361 switch( nWhich = pFld->GetTyp()->Which() ) 1362 { 1363 case RES_HIDDENTXTFLD: 1364 { 1365 SwHiddenTxtField* pHFld = (SwHiddenTxtField*)pFld; 1366 SwSbxValue aValue = aCalc.Calculate( pHFld->GetPar1() ); 1367 sal_Bool bValue = !aValue.GetBool(); 1368 if(!aValue.IsVoidValue()) 1369 { 1370 pHFld->SetValue( bValue ); 1371 // Feld Evaluieren 1372 pHFld->Evaluate(this); 1373 } 1374 } 1375 break; 1376 case RES_HIDDENPARAFLD: 1377 { 1378 SwHiddenParaField* pHPFld = (SwHiddenParaField*)pFld; 1379 SwSbxValue aValue = aCalc.Calculate( pHPFld->GetPar1() ); 1380 sal_Bool bValue = aValue.GetBool(); 1381 if(!aValue.IsVoidValue()) 1382 pHPFld->SetHidden( bValue ); 1383 } 1384 break; 1385 case RES_DBSETNUMBERFLD: 1386 { 1387 ((SwDBSetNumberField*)pFld)->Evaluate(this); 1388 aCalc.VarChange( sDBNumNm, ((SwDBSetNumberField*)pFld)->GetSetNumber()); 1389 } 1390 break; 1391 case RES_DBNEXTSETFLD: 1392 case RES_DBNUMSETFLD: 1393 UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc ); 1394 break; 1395 case RES_DBFLD: 1396 { 1397 // Feld Evaluieren 1398 ((SwDBField*)pFld)->Evaluate(); 1399 1400 SwDBData aTmpDBData(((SwDBField*)pFld)->GetDBData()); 1401 1402 if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, sal_False)) 1403 aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType)); 1404 1405 const String& rName = pFld->GetTyp()->GetName(); 1406 1407 // Wert fuer den Calculator setzen 1408 //JP 10.02.96: GetValue macht hier doch keinen Sinn 1409 // ((SwDBField*)pFld)->GetValue(); 1410 1411 //!OK aCalc.VarChange(aName, ((SwDBField*)pFld)->GetValue(aCalc)); 1412 1413 // Eintrag in den HashTable eintragen 1414 // Eintrag vorhanden ? 1415 sal_uInt16 nPos; 1416 SwHash* pFnd = Find( rName, pHashStrTbl, nStrFmtCnt, &nPos ); 1417 String const value(pFld->ExpandField(IsClipBoard())); 1418 if( pFnd ) 1419 { 1420 // Eintrag in der HashTabelle aendern 1421 static_cast<_HashStr*>(pFnd)->aSetStr = value; 1422 } 1423 else 1424 { 1425 // neuen Eintrag einfuegen 1426 *(pHashStrTbl + nPos ) = new _HashStr( rName, 1427 value, static_cast<_HashStr *>(*(pHashStrTbl + nPos))); 1428 } 1429 } 1430 break; 1431 case RES_GETEXPFLD: 1432 case RES_SETEXPFLD: 1433 { 1434 if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() ) // String Ersetzung 1435 { 1436 if( RES_GETEXPFLD == nWhich ) 1437 { 1438 SwGetExpField* pGFld = (SwGetExpField*)pFld; 1439 1440 if( (!pUpdtFld || pUpdtFld == pTxtFld ) 1441 && pGFld->IsInBodyTxt() ) 1442 { 1443 LookString( pHashStrTbl, nStrFmtCnt, 1444 pGFld->GetFormula(), aNew ); 1445 pGFld->ChgExpStr( aNew ); 1446 } 1447 } 1448 else 1449 { 1450 SwSetExpField* pSFld = (SwSetExpField*)pFld; 1451 // ist die "Formel" ein Feld ?? 1452 LookString( pHashStrTbl, nStrFmtCnt, 1453 pSFld->GetFormula(), aNew ); 1454 1455 if( !aNew.Len() ) // nichts gefunden, dann ist die 1456 aNew = pSFld->GetFormula(); // Formel der neue Wert 1457 1458 // nur ein spezielles FeldUpdaten ? 1459 if( !pUpdtFld || pUpdtFld == pTxtFld ) 1460 pSFld->ChgExpStr( aNew ); 1461 1462 // suche den Namen vom Feld 1463 aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName(); 1464 // Eintrag vorhanden ? 1465 sal_uInt16 nPos; 1466 SwHash* pFnd = Find( aNew, pHashStrTbl, nStrFmtCnt, &nPos ); 1467 if( pFnd ) 1468 // Eintrag in der HashTabelle aendern 1469 ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr(); 1470 else 1471 // neuen Eintrag einfuegen 1472 *(pHashStrTbl + nPos ) = pFnd = new _HashStr( aNew, 1473 pSFld->GetExpStr(), 1474 (_HashStr*)*(pHashStrTbl + nPos) ); 1475 1476 // Erweiterung fuers Rechnen mit Strings 1477 SwSbxValue aValue; 1478 aValue.PutString( ((_HashStr*)pFnd)->aSetStr ); 1479 aCalc.VarChange( aNew, aValue ); 1480 } 1481 } 1482 else // Formel neu berechnen 1483 { 1484 if( RES_GETEXPFLD == nWhich ) 1485 { 1486 SwGetExpField* pGFld = (SwGetExpField*)pFld; 1487 1488 if( (!pUpdtFld || pUpdtFld == pTxtFld ) 1489 && pGFld->IsInBodyTxt() ) 1490 { 1491 SwSbxValue aValue = aCalc.Calculate( 1492 pGFld->GetFormula()); 1493 if(!aValue.IsVoidValue()) 1494 pGFld->SetValue(aValue.GetDouble() ); 1495 } 1496 } 1497 else 1498 { 1499 SwSetExpField* pSFld = (SwSetExpField*)pFld; 1500 SwSetExpFieldType* pSFldTyp = (SwSetExpFieldType*)pFld->GetTyp(); 1501 aNew = pSFldTyp->GetName(); 1502 1503 SwNode* pSeqNd = 0; 1504 1505 if( pSFld->IsSequenceFld() ) 1506 { 1507 const sal_uInt8 nLvl = pSFldTyp->GetOutlineLvl(); 1508 if( MAXLEVEL > nLvl ) 1509 { 1510 // dann teste, ob die Nummer neu aufsetzen muss 1511 pSeqNd = GetNodes()[ (*ppSortLst)->GetNode() ]; 1512 1513 const SwTxtNode* pOutlNd = pSeqNd-> 1514 FindOutlineNodeOfLevel( nLvl ); 1515 if( pSFldTyp->GetOutlineChgNd() != pOutlNd ) 1516 { 1517 pSFldTyp->SetOutlineChgNd( pOutlNd ); 1518 aCalc.VarChange( aNew, 0 ); 1519 } 1520 } 1521 } 1522 1523 aNew += '='; 1524 aNew += pSFld->GetFormula(); 1525 1526 SwSbxValue aValue = aCalc.Calculate( aNew ); 1527 double nErg = aValue.GetDouble(); 1528 // nur ein spezielles Feld updaten ? 1529 if( !aValue.IsVoidValue() && (!pUpdtFld || pUpdtFld == pTxtFld) ) 1530 { 1531 pSFld->SetValue( nErg ); 1532 1533 if( pSeqNd ) 1534 pSFldTyp->SetChapter( *pSFld, *pSeqNd ); 1535 } 1536 } 1537 } 1538 } 1539 } // switch 1540 1541 pFmtFld->ModifyNotification( 0, 0 ); // Formatierung anstossen 1542 1543 if( pUpdtFld == pTxtFld ) // sollte nur dieses geupdatet werden 1544 { 1545 if( RES_GETEXPFLD == nWhich || // nur GetFeld oder 1546 RES_HIDDENTXTFLD == nWhich || // HiddenTxt? 1547 RES_HIDDENPARAFLD == nWhich) // HiddenParaFld? 1548 break; // beenden 1549 pUpdtFld = 0; // ab jetzt alle Updaten 1550 } 1551 } 1552 1553 pMgr->CloseAll(sal_False); 1554 // HashTabelle wieder loeschen 1555 ::DeleteHashTable( pHashStrTbl, nStrFmtCnt ); 1556 1557 // Referenzfelder updaten 1558 if( bUpdRefFlds ) 1559 UpdateRefFlds(NULL); 1560 1561 pUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds ); 1562 pUpdtFlds->SetFieldsDirty( sal_False ); 1563 } 1564 1565 /*-------------------------------------------------------------------- 1566 Beschreibung: 1567 --------------------------------------------------------------------*/ 1568 1569 void SwDoc::UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc ) 1570 { 1571 SwNewDBMgr* pMgr = GetNewDBMgr(); 1572 1573 sal_uInt16 nFldType = rDBFld.Which(); 1574 1575 sal_Bool bPar1 = rCalc.Calculate( rDBFld.GetPar1() ).GetBool(); 1576 1577 if( RES_DBNEXTSETFLD == nFldType ) 1578 ((SwDBNextSetField&)rDBFld).SetCondValid( bPar1 ); 1579 else 1580 ((SwDBNumSetField&)rDBFld).SetCondValid( bPar1 ); 1581 1582 if( rDBFld.GetRealDBData().sDataSource.getLength() ) 1583 { 1584 // Eine bestimmte Datenbank bearbeiten 1585 if( RES_DBNEXTSETFLD == nFldType ) 1586 ((SwDBNextSetField&)rDBFld).Evaluate(this); 1587 else 1588 ((SwDBNumSetField&)rDBFld).Evaluate(this); 1589 1590 SwDBData aTmpDBData( rDBFld.GetDBData(this) ); 1591 1592 if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false )) 1593 rCalc.VarChange( lcl_GetDBVarName( *this, rDBFld), 1594 pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) ); 1595 } 1596 else 1597 { 1598 DBG_ERROR("TODO: what should happen with unnamed DBFields?"); 1599 } 1600 } 1601 1602 /*-------------------------------------------------------------------- 1603 Beschreibung: 1604 --------------------------------------------------------------------*/ 1605 1606 void SwDoc::_InitFieldTypes() // wird vom CTOR gerufen!! 1607 { 1608 // Feldtypen 1609 sal_uInt16 nFldType = 0; 1610 pFldTypes->Insert( new SwDateTimeFieldType(this), nFldType++ ); 1611 pFldTypes->Insert( new SwChapterFieldType, nFldType++ ); 1612 pFldTypes->Insert( new SwPageNumberFieldType, nFldType++ ); 1613 pFldTypes->Insert( new SwAuthorFieldType, nFldType++ ); 1614 pFldTypes->Insert( new SwFileNameFieldType(this), nFldType++ ); 1615 pFldTypes->Insert( new SwDBNameFieldType(this), nFldType++); 1616 pFldTypes->Insert( new SwGetExpFieldType(this), nFldType++ ); 1617 pFldTypes->Insert( new SwGetRefFieldType( this ), nFldType++ ); 1618 pFldTypes->Insert( new SwHiddenTxtFieldType, nFldType++ ); 1619 pFldTypes->Insert( new SwPostItFieldType(this), nFldType++ ); 1620 pFldTypes->Insert( new SwDocStatFieldType(this), nFldType++); 1621 pFldTypes->Insert( new SwDocInfoFieldType(this), nFldType++); 1622 pFldTypes->Insert( new SwInputFieldType( this ), nFldType++ ); 1623 pFldTypes->Insert( new SwTblFieldType( this ), nFldType++); 1624 pFldTypes->Insert( new SwMacroFieldType(this), nFldType++ ); 1625 pFldTypes->Insert( new SwHiddenParaFieldType, nFldType++ ); 1626 pFldTypes->Insert( new SwDBNextSetFieldType, nFldType++ ); 1627 pFldTypes->Insert( new SwDBNumSetFieldType, nFldType++ ); 1628 pFldTypes->Insert( new SwDBSetNumberFieldType, nFldType++ ); 1629 pFldTypes->Insert( new SwTemplNameFieldType(this), nFldType++); 1630 pFldTypes->Insert( new SwTemplNameFieldType(this),nFldType++); 1631 pFldTypes->Insert( new SwExtUserFieldType, nFldType++ ); 1632 pFldTypes->Insert( new SwRefPageSetFieldType, nFldType++ ); 1633 pFldTypes->Insert( new SwRefPageGetFieldType( this ), nFldType++ ); 1634 pFldTypes->Insert( new SwJumpEditFieldType( this ), nFldType++ ); 1635 pFldTypes->Insert( new SwScriptFieldType( this ), nFldType++ ); 1636 pFldTypes->Insert( new SwCombinedCharFieldType, nFldType++ ); 1637 pFldTypes->Insert( new SwDropDownFieldType, nFldType++ ); 1638 1639 // Types muessen am Ende stehen !! 1640 // Im InsertFldType wird davon ausgegangen !!!! 1641 // MIB 14.04.95: Im Sw3StringPool::Setup (sw3imp.cxx) und 1642 // lcl_sw3io_InSetExpField (sw3field.cxx) jetzt auch 1643 pFldTypes->Insert( new SwSetExpFieldType(this, 1644 SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ), nFldType++); 1645 pFldTypes->Insert( new SwSetExpFieldType(this, 1646 SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ),nFldType++); 1647 pFldTypes->Insert( new SwSetExpFieldType(this, 1648 SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ),nFldType++); 1649 pFldTypes->Insert( new SwSetExpFieldType(this, 1650 SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ),nFldType++); 1651 1652 ASSERT( nFldType == INIT_FLDTYPES, "Bad initsize: SwFldTypes" ); 1653 } 1654 1655 void SwDoc::InsDelFldInFldLst( bool bIns, const SwTxtFld& rFld ) 1656 { 1657 if( !mbNewFldLst || !IsInDtor() ) 1658 pUpdtFlds->InsDelFldInFldLst( bIns, rFld ); 1659 } 1660 1661 SwDBData SwDoc::GetDBData() 1662 { 1663 return GetDBDesc(); 1664 } 1665 1666 const SwDBData& SwDoc::GetDBDesc() 1667 { 1668 if(!aDBData.sDataSource.getLength()) 1669 { 1670 const sal_uInt16 nSize = pFldTypes->Count(); 1671 for(sal_uInt16 i = 0; i < nSize && !aDBData.sDataSource.getLength(); ++i) 1672 { 1673 SwFieldType& rFldType = *((*pFldTypes)[i]); 1674 sal_uInt16 nWhich = rFldType.Which(); 1675 if(IsUsed(rFldType)) 1676 { 1677 switch(nWhich) 1678 { 1679 case RES_DBFLD: 1680 case RES_DBNEXTSETFLD: 1681 case RES_DBNUMSETFLD: 1682 case RES_DBSETNUMBERFLD: 1683 { 1684 SwIterator<SwFmtFld,SwFieldType> aIter( rFldType ); 1685 for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() ) 1686 { 1687 if(pFld->IsFldInDoc()) 1688 { 1689 if(RES_DBFLD == nWhich) 1690 aDBData = (static_cast < SwDBFieldType * > (pFld->GetField()->GetTyp()))->GetDBData(); 1691 else 1692 aDBData = (static_cast < SwDBNameInfField* > (pFld->GetField()))->GetRealDBData(); 1693 break; 1694 } 1695 } 1696 } 1697 break; 1698 } 1699 } 1700 } 1701 } 1702 if(!aDBData.sDataSource.getLength()) 1703 aDBData = GetNewDBMgr()->GetAddressDBName(); 1704 return aDBData; 1705 } 1706 1707 void SwDoc::SetInitDBFields( sal_Bool b ) 1708 { 1709 GetNewDBMgr()->SetInitDBFields( b ); 1710 } 1711 1712 /*-------------------------------------------------------------------- 1713 Beschreibung: Alle von Feldern verwendete Datenbanken herausfinden 1714 --------------------------------------------------------------------*/ 1715 String lcl_DBDataToString(const SwDBData& rData) 1716 { 1717 String sRet = rData.sDataSource; 1718 sRet += DB_DELIM; 1719 sRet += (String)rData.sCommand; 1720 sRet += DB_DELIM; 1721 sRet += String::CreateFromInt32(rData.nCommandType); 1722 return sRet; 1723 } 1724 void SwDoc::GetAllUsedDB( SvStringsDtor& rDBNameList, 1725 const SvStringsDtor* pAllDBNames ) 1726 { 1727 SvStringsDtor aUsedDBNames; 1728 SvStringsDtor aAllDBNames; 1729 1730 if( !pAllDBNames ) 1731 { 1732 GetAllDBNames( aAllDBNames ); 1733 pAllDBNames = &aAllDBNames; 1734 } 1735 1736 SwSectionFmts& rArr = GetSections(); 1737 for (sal_uInt16 n = rArr.Count(); n; ) 1738 { 1739 SwSection* pSect = rArr[ --n ]->GetSection(); 1740 1741 if( pSect ) 1742 { 1743 String aCond( pSect->GetCondition() ); 1744 AddUsedDBToList( rDBNameList, FindUsedDBs( *pAllDBNames, 1745 aCond, aUsedDBNames ) ); 1746 aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); 1747 } 1748 } 1749 1750 const SfxPoolItem* pItem; 1751 sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD ); 1752 for (sal_uInt32 n = 0; n < nMaxItems; ++n) 1753 { 1754 if( 0 == (pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) )) 1755 continue; 1756 1757 const SwFmtFld* pFmtFld = (SwFmtFld*)pItem; 1758 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1759 if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) 1760 continue; 1761 1762 const SwField* pFld = pFmtFld->GetField(); 1763 switch( pFld->GetTyp()->Which() ) 1764 { 1765 case RES_DBFLD: 1766 AddUsedDBToList( rDBNameList, 1767 lcl_DBDataToString(((SwDBField*)pFld)->GetDBData() )); 1768 break; 1769 1770 case RES_DBSETNUMBERFLD: 1771 case RES_DBNAMEFLD: 1772 AddUsedDBToList( rDBNameList, 1773 lcl_DBDataToString(((SwDBNameInfField*)pFld)->GetRealDBData() )); 1774 break; 1775 1776 case RES_DBNUMSETFLD: 1777 case RES_DBNEXTSETFLD: 1778 AddUsedDBToList( rDBNameList, 1779 lcl_DBDataToString(((SwDBNameInfField*)pFld)->GetRealDBData() )); 1780 // kein break // JP: ist das so richtig ?? 1781 1782 case RES_HIDDENTXTFLD: 1783 case RES_HIDDENPARAFLD: 1784 AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames, 1785 pFld->GetPar1(), aUsedDBNames )); 1786 aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); 1787 break; 1788 1789 case RES_SETEXPFLD: 1790 case RES_GETEXPFLD: 1791 case RES_TABLEFLD: 1792 AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames, 1793 pFld->GetFormula(), aUsedDBNames )); 1794 aUsedDBNames.DeleteAndDestroy( 0, aUsedDBNames.Count() ); 1795 break; 1796 } 1797 } 1798 } 1799 1800 /*-------------------------------------------------------------------- 1801 Beschreibung: 1802 --------------------------------------------------------------------*/ 1803 1804 void SwDoc::GetAllDBNames( SvStringsDtor& rAllDBNames ) 1805 { 1806 SwNewDBMgr* pMgr = GetNewDBMgr(); 1807 1808 const SwDSParamArr& rArr = pMgr->GetDSParamArray(); 1809 for(sal_uInt16 i = 0; i < rArr.Count(); i++) 1810 { 1811 SwDSParam* pParam = rArr[i]; 1812 String* pStr = new String( pParam->sDataSource ); 1813 (*pStr) += DB_DELIM; 1814 (*pStr) += (String)pParam->sCommand; 1815 rAllDBNames.Insert( pStr, rAllDBNames.Count() ); 1816 } 1817 } 1818 1819 /*-------------------------------------------------------------------- 1820 Beschreibung: 1821 --------------------------------------------------------------------*/ 1822 1823 SvStringsDtor& SwDoc::FindUsedDBs( const SvStringsDtor& rAllDBNames, 1824 const String& rFormel, 1825 SvStringsDtor& rUsedDBNames ) 1826 { 1827 const CharClass& rCC = GetAppCharClass(); 1828 String sFormel( rFormel); 1829 #ifndef UNX 1830 rCC.toUpper( sFormel ); 1831 #endif 1832 1833 xub_StrLen nPos; 1834 for (sal_uInt16 i = 0; i < rAllDBNames.Count(); ++i ) 1835 { 1836 const String* pStr = rAllDBNames.GetObject(i); 1837 1838 if( STRING_NOTFOUND != (nPos = sFormel.Search( *pStr )) && 1839 sFormel.GetChar( nPos + pStr->Len() ) == '.' && 1840 (!nPos || !rCC.isLetterNumeric( sFormel, nPos - 1 ))) 1841 { 1842 // Tabellenname suchen 1843 xub_StrLen nEndPos; 1844 nPos += pStr->Len() + 1; 1845 if( STRING_NOTFOUND != (nEndPos = sFormel.Search('.', nPos)) ) 1846 { 1847 String* pDBNm = new String( *pStr ); 1848 pDBNm->Append( DB_DELIM ); 1849 pDBNm->Append( sFormel.Copy( nPos, nEndPos - nPos )); 1850 rUsedDBNames.Insert( pDBNm, rUsedDBNames.Count() ); 1851 } 1852 } 1853 } 1854 return rUsedDBNames; 1855 } 1856 1857 /*-------------------------------------------------------------------- 1858 Beschreibung: 1859 --------------------------------------------------------------------*/ 1860 1861 void SwDoc::AddUsedDBToList( SvStringsDtor& rDBNameList, 1862 const SvStringsDtor& rUsedDBNames ) 1863 { 1864 for (sal_uInt16 i = 0; i < rUsedDBNames.Count(); i++) 1865 AddUsedDBToList( rDBNameList, *rUsedDBNames.GetObject(i) ); 1866 } 1867 1868 /*-------------------------------------------------------------------- 1869 Beschreibung: 1870 --------------------------------------------------------------------*/ 1871 1872 void SwDoc::AddUsedDBToList( SvStringsDtor& rDBNameList, const String& rDBName) 1873 { 1874 if( !rDBName.Len() ) 1875 return; 1876 1877 #ifdef UNX 1878 for( sal_uInt16 i = 0; i < rDBNameList.Count(); ++i ) 1879 if( rDBName == rDBNameList.GetObject(i)->GetToken(0) ) 1880 return; 1881 #else 1882 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 1883 for( sal_uInt16 i = 0; i < rDBNameList.Count(); ++i ) 1884 if( rSCmp.isEqual( rDBName, rDBNameList.GetObject(i)->GetToken(0) ) ) 1885 return; 1886 #endif 1887 1888 SwDBData aData; 1889 aData.sDataSource = rDBName.GetToken(0, DB_DELIM); 1890 aData.sCommand = rDBName.GetToken(1, DB_DELIM); 1891 aData.nCommandType = -1; 1892 GetNewDBMgr()->CreateDSData(aData); 1893 String* pNew = new String( rDBName ); 1894 rDBNameList.Insert( pNew, rDBNameList.Count() ); 1895 } 1896 1897 /*-------------------------------------------------------------------- 1898 Beschreibung: 1899 --------------------------------------------------------------------*/ 1900 1901 void SwDoc::ChangeDBFields( const SvStringsDtor& rOldNames, 1902 const String& rNewName ) 1903 { 1904 SwDBData aNewDBData; 1905 aNewDBData.sDataSource = rNewName.GetToken(0, DB_DELIM); 1906 aNewDBData.sCommand = rNewName.GetToken(1, DB_DELIM); 1907 aNewDBData.nCommandType = (short)rNewName.GetToken(2, DB_DELIM).ToInt32(); 1908 1909 String sFormel; 1910 1911 SwSectionFmts& rArr = GetSections(); 1912 for (sal_uInt16 n = rArr.Count(); n; ) 1913 { 1914 SwSection* pSect = rArr[ --n ]->GetSection(); 1915 1916 if( pSect ) 1917 { 1918 sFormel = pSect->GetCondition(); 1919 ReplaceUsedDBs( rOldNames, rNewName, sFormel); 1920 pSect->SetCondition(sFormel); 1921 } 1922 } 1923 1924 const SfxPoolItem* pItem; 1925 sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD ); 1926 1927 for (sal_uInt32 n = 0; n < nMaxItems; ++n ) 1928 { 1929 if( 0 == (pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) )) 1930 continue; 1931 1932 SwFmtFld* pFmtFld = (SwFmtFld*)pItem; 1933 SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1934 if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) 1935 continue; 1936 1937 SwField* pFld = pFmtFld->GetField(); 1938 sal_Bool bExpand = sal_False; 1939 1940 switch( pFld->GetTyp()->Which() ) 1941 { 1942 case RES_DBFLD: 1943 if( IsNameInArray( rOldNames, lcl_DBDataToString(((SwDBField*)pFld)->GetDBData()))) 1944 { 1945 SwDBFieldType* pOldTyp = (SwDBFieldType*)pFld->GetTyp(); 1946 1947 SwDBFieldType* pTyp = (SwDBFieldType*)InsertFldType( 1948 SwDBFieldType(this, pOldTyp->GetColumnName(), aNewDBData)); 1949 1950 pFmtFld->RegisterToFieldType( *pTyp ); 1951 pFld->ChgTyp(pTyp); 1952 1953 ((SwDBField*)pFld)->ClearInitialized(); 1954 ((SwDBField*)pFld)->InitContent(); 1955 1956 bExpand = sal_True; 1957 } 1958 break; 1959 1960 case RES_DBSETNUMBERFLD: 1961 case RES_DBNAMEFLD: 1962 if( IsNameInArray( rOldNames, 1963 lcl_DBDataToString(((SwDBNameInfField*)pFld)->GetRealDBData()))) 1964 { 1965 ((SwDBNameInfField*)pFld)->SetDBData(aNewDBData); 1966 bExpand = sal_True; 1967 } 1968 break; 1969 1970 case RES_DBNUMSETFLD: 1971 case RES_DBNEXTSETFLD: 1972 if( IsNameInArray( rOldNames, 1973 lcl_DBDataToString(((SwDBNameInfField*)pFld)->GetRealDBData()))) 1974 { 1975 ((SwDBNameInfField*)pFld)->SetDBData(aNewDBData); 1976 bExpand = sal_True; 1977 } 1978 // kein break; 1979 case RES_HIDDENTXTFLD: 1980 case RES_HIDDENPARAFLD: 1981 sFormel = pFld->GetPar1(); 1982 ReplaceUsedDBs( rOldNames, rNewName, sFormel); 1983 pFld->SetPar1( sFormel ); 1984 bExpand = sal_True; 1985 break; 1986 1987 case RES_SETEXPFLD: 1988 case RES_GETEXPFLD: 1989 case RES_TABLEFLD: 1990 sFormel = pFld->GetFormula(); 1991 ReplaceUsedDBs( rOldNames, rNewName, sFormel); 1992 pFld->SetPar2( sFormel ); 1993 bExpand = sal_True; 1994 break; 1995 } 1996 1997 if (bExpand) 1998 pTxtFld->ExpandAlways(); 1999 } 2000 SetModified(); 2001 } 2002 2003 /*-------------------------------------------------------------------- 2004 Beschreibung: 2005 --------------------------------------------------------------------*/ 2006 2007 void SwDoc::ReplaceUsedDBs( const SvStringsDtor& rUsedDBNames, 2008 const String& rNewName, String& rFormel ) 2009 { 2010 const CharClass& rCC = GetAppCharClass(); 2011 String sFormel(rFormel); 2012 String sNewName( rNewName ); 2013 sNewName.SearchAndReplace( DB_DELIM, '.'); 2014 //the command type is not part of the condition 2015 sNewName = sNewName.GetToken(0, DB_DELIM); 2016 String sUpperNewNm( sNewName ); 2017 2018 2019 for( sal_uInt16 i = 0; i < rUsedDBNames.Count(); ++i ) 2020 { 2021 String sDBName( *rUsedDBNames.GetObject( i ) ); 2022 2023 sDBName.SearchAndReplace( DB_DELIM, '.'); 2024 //cut off command type 2025 sDBName = sDBName.GetToken(0, DB_DELIM); 2026 if( !sDBName.Equals( sUpperNewNm )) 2027 { 2028 xub_StrLen nPos = 0; 2029 2030 while ((nPos = sFormel.Search(sDBName, nPos)) != STRING_NOTFOUND) 2031 { 2032 if( sFormel.GetChar( nPos + sDBName.Len() ) == '.' && 2033 (!nPos || !rCC.isLetterNumeric( sFormel, nPos - 1 ))) 2034 { 2035 rFormel.Erase( nPos, sDBName.Len() ); 2036 rFormel.Insert( sNewName, nPos ); 2037 //prevent re-searching - this is useless and provokes 2038 //endless loops when names containing each other and numbers are exchanged 2039 //e.g.: old ?12345.12345 new: i12345.12345 2040 nPos = nPos + sNewName.Len(); 2041 sFormel = rFormel; 2042 } 2043 } 2044 } 2045 } 2046 } 2047 2048 /*-------------------------------------------------------------------- 2049 Beschreibung: 2050 --------------------------------------------------------------------*/ 2051 2052 sal_Bool SwDoc::IsNameInArray( const SvStringsDtor& rArr, const String& rName ) 2053 { 2054 #ifdef UNX 2055 for( sal_uInt16 i = 0; i < rArr.Count(); ++i ) 2056 if( rName == *rArr[ i ] ) 2057 return sal_True; 2058 #else 2059 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 2060 for( sal_uInt16 i = 0; i < rArr.Count(); ++i ) 2061 if( rSCmp.isEqual( rName, *rArr[ i] )) 2062 return sal_True; 2063 #endif 2064 return sal_False; 2065 } 2066 2067 void SwDoc::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime ) 2068 { 2069 sal_Bool bIsModified = IsModified(); 2070 2071 sal_uLong nDate, nTime; 2072 if( pNewDateTime ) 2073 { 2074 nDate = pNewDateTime->GetDate(); 2075 nTime = pNewDateTime->GetTime(); 2076 } 2077 else 2078 { 2079 nDate = Date().GetDate(); 2080 nTime = Time().GetTime(); 2081 } 2082 2083 sal_uInt16 aTypes[5] = { 2084 /*0*/ RES_DOCINFOFLD, 2085 /*1*/ RES_AUTHORFLD, 2086 /*2*/ RES_EXTUSERFLD, 2087 /*3*/ RES_FILENAMEFLD, 2088 /*4*/ RES_DATETIMEFLD }; // MUSS am Ende stehen!! 2089 2090 sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0; 2091 2092 for( ; nStt < 5; ++nStt ) 2093 { 2094 SwFieldType* pFldType = GetSysFldType( aTypes[ nStt ] ); 2095 SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType ); 2096 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 2097 { 2098 if( pFmtFld && pFmtFld->GetTxtFld() ) 2099 { 2100 sal_Bool bChgd = sal_False; 2101 switch( aTypes[ nStt ] ) 2102 { 2103 case RES_DOCINFOFLD: 2104 if( ((SwDocInfoField*)pFmtFld->GetField())->IsFixed() ) 2105 { 2106 bChgd = sal_True; 2107 SwDocInfoField* pDocInfFld = (SwDocInfoField*)pFmtFld->GetField(); 2108 pDocInfFld->SetExpansion( ((SwDocInfoFieldType*) 2109 pDocInfFld->GetTyp())->Expand( 2110 pDocInfFld->GetSubType(), 2111 pDocInfFld->GetFormat(), 2112 pDocInfFld->GetLanguage(), 2113 pDocInfFld->GetName() ) ); 2114 } 2115 break; 2116 2117 case RES_AUTHORFLD: 2118 if( ((SwAuthorField*)pFmtFld->GetField())->IsFixed() ) 2119 { 2120 bChgd = sal_True; 2121 SwAuthorField* pAuthorFld = (SwAuthorField*)pFmtFld->GetField(); 2122 pAuthorFld->SetExpansion( ((SwAuthorFieldType*) 2123 pAuthorFld->GetTyp())->Expand( 2124 pAuthorFld->GetFormat() ) ); 2125 } 2126 break; 2127 2128 case RES_EXTUSERFLD: 2129 if( ((SwExtUserField*)pFmtFld->GetField())->IsFixed() ) 2130 { 2131 bChgd = sal_True; 2132 SwExtUserField* pExtUserFld = (SwExtUserField*)pFmtFld->GetField(); 2133 pExtUserFld->SetExpansion( ((SwExtUserFieldType*) 2134 pExtUserFld->GetTyp())->Expand( 2135 pExtUserFld->GetSubType(), 2136 pExtUserFld->GetFormat())); 2137 } 2138 break; 2139 2140 case RES_DATETIMEFLD: 2141 if( ((SwDateTimeField*)pFmtFld->GetField())->IsFixed() ) 2142 { 2143 bChgd = sal_True; 2144 ((SwDateTimeField*)pFmtFld->GetField())->SetDateTime( 2145 DateTime(Date(nDate), Time(nTime)) ); 2146 } 2147 break; 2148 2149 case RES_FILENAMEFLD: 2150 if( ((SwFileNameField*)pFmtFld->GetField())->IsFixed() ) 2151 { 2152 bChgd = sal_True; 2153 SwFileNameField* pFileNameFld = 2154 (SwFileNameField*)pFmtFld->GetField(); 2155 pFileNameFld->SetExpansion( ((SwFileNameFieldType*) 2156 pFileNameFld->GetTyp())->Expand( 2157 pFileNameFld->GetFormat() ) ); 2158 } 2159 break; 2160 } 2161 2162 // Formatierung anstossen 2163 if( bChgd ) 2164 pFmtFld->ModifyNotification( 0, 0 ); 2165 } 2166 } 2167 } 2168 2169 if( !bIsModified ) 2170 ResetModified(); 2171 } 2172 2173 bool SwDoc::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen ) 2174 { 2175 // teste ggfs. mal, ob die angegbenen Nodes ueberhaupt Felder beinhalten. 2176 // wenn nicht, braucht das Flag nicht veraendert werden. 2177 sal_Bool bFldsFnd = sal_False; 2178 if( b && pChk && !GetUpdtFlds().IsFieldsDirty() && !IsInDtor() 2179 // ?? was ist mit Undo, da will man es doch auch haben !! 2180 /*&& &pChk->GetNodes() == &GetNodes()*/ ) 2181 { 2182 b = sal_False; 2183 if( !nLen ) 2184 ++nLen; 2185 sal_uLong nStt = pChk->GetIndex(); 2186 const SwNodes& rNds = pChk->GetNodes(); 2187 while( nLen-- ) 2188 { 2189 const SwTxtNode* pTNd = rNds[ nStt++ ]->GetTxtNode(); 2190 if( pTNd ) 2191 { 2192 if( //pTNd->GetFmtColl() && //#outline level,zhaojianwei 2193 // MAXLEVEL > pTNd->GetTxtColl()->GetOutlineLevel() ) 2194 pTNd->GetAttrOutlineLevel() != 0 )//<-end,zhaojianwei 2195 // Kapitelfelder aktualisieren 2196 b = sal_True; 2197 else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() ) 2198 for( sal_uInt16 n = 0, nEnd = pTNd->GetSwpHints().Count(); 2199 n < nEnd; ++n ) 2200 { 2201 const SwTxtAttr* pAttr = pTNd->GetSwpHints()[ n ]; 2202 if( RES_TXTATR_FIELD == pAttr->Which() ) 2203 { 2204 b = sal_True; 2205 break; 2206 } 2207 } 2208 2209 if( b ) 2210 break; 2211 } 2212 } 2213 bFldsFnd = b; 2214 } 2215 GetUpdtFlds().SetFieldsDirty( b ); 2216 return bFldsFnd; 2217 } 2218 /* -----------------------------21.12.99 12:55-------------------------------- 2219 2220 ---------------------------------------------------------------------------*/ 2221 void SwDoc::ChangeAuthorityData( const SwAuthEntry* pNewData ) 2222 { 2223 const sal_uInt16 nSize = pFldTypes->Count(); 2224 2225 for( sal_uInt16 i = INIT_FLDTYPES; i < nSize; ++i ) 2226 { 2227 SwFieldType* pFldType = (*pFldTypes)[i]; 2228 if( RES_AUTHORITY == pFldType->Which() ) 2229 { 2230 SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)pFldType; 2231 pAuthType->ChangeEntryContent(pNewData); 2232 break; 2233 } 2234 } 2235 2236 } 2237 /*-------------------------------------------------------------------- 2238 Beschreibung: 2239 --------------------------------------------------------------------*/ 2240 2241 void SwDocUpdtFld::InsDelFldInFldLst( sal_Bool bIns, const SwTxtFld& rFld ) 2242 { 2243 const sal_uInt16 nWhich = rFld.GetFmtFld().GetField()->GetTyp()->Which(); 2244 switch( nWhich ) 2245 { 2246 case RES_DBFLD: 2247 case RES_SETEXPFLD: 2248 case RES_HIDDENPARAFLD: 2249 case RES_HIDDENTXTFLD: 2250 case RES_DBNUMSETFLD: 2251 case RES_DBNEXTSETFLD: 2252 case RES_DBSETNUMBERFLD: 2253 case RES_GETEXPFLD: 2254 break; // diese muessen ein-/ausgetragen werden! 2255 2256 default: 2257 return; 2258 } 2259 2260 SetFieldsDirty( sal_True ); 2261 if( !pFldSortLst ) 2262 { 2263 if( !bIns ) // keine Liste vorhanden und loeschen 2264 return; // dann nichts tun 2265 pFldSortLst = new _SetGetExpFlds( 64, 16 ); 2266 } 2267 2268 if( bIns ) // neu einfuegen: 2269 GetBodyNode( rFld, nWhich ); 2270 else 2271 { 2272 // ueber den pTxtFld Pointer suchen. Ist zwar eine Sortierte 2273 // Liste, aber nach Node-Positionen sortiert. Bis dieser 2274 // bestimmt ist, ist das Suchen nach dem Pointer schon fertig 2275 for( sal_uInt16 n = 0; n < pFldSortLst->Count(); ++n ) 2276 if( &rFld == (*pFldSortLst)[ n ]->GetPointer() ) 2277 pFldSortLst->DeleteAndDestroy( n--, 1 ); 2278 // ein Feld kann mehrfach vorhanden sein! 2279 } 2280 } 2281 2282 void SwDocUpdtFld::MakeFldList( SwDoc& rDoc, int bAll, int eGetMode ) 2283 { 2284 if( !pFldSortLst || bAll || !( eGetMode & nFldLstGetMode ) || 2285 rDoc.GetNodes().Count() != nNodes ) 2286 _MakeFldList( rDoc, eGetMode ); 2287 } 2288 2289 void SwDocUpdtFld::_MakeFldList( SwDoc& rDoc, int eGetMode ) 2290 { 2291 // neue Version: gehe ueber alle Felder vom Attribut-Pool 2292 if( pFldSortLst ) 2293 delete pFldSortLst; 2294 pFldSortLst = new _SetGetExpFlds( 64, 16 ); 2295 2296 /// OD 09.08.2002 [#101207#,#101216#,#101778#] - consider and unhide sections 2297 /// with hide condition, only in mode GETFLD_ALL (<eGetMode == GETFLD_ALL>) 2298 /// notes by OD: 2299 /// eGetMode == GETFLD_CALC in call from methods SwDoc::FldsToCalc 2300 /// eGetMode == GETFLD_EXPAND in call from method SwDoc::FldsToExpand 2301 /// eGetMode == GETFLD_ALL in call from method SwDoc::UpdateExpFlds 2302 /// I figured out that hidden section only have to be shown, 2303 /// if fields have updated (call by SwDoc::UpdateExpFlds) and thus 2304 /// the hide conditions of section have to be updated. 2305 /// For correct updating the hide condition of a section, its position 2306 /// have to be known in order to insert the hide condition as a new 2307 /// expression field into the sorted field list (<pFldSortLst>). 2308 if ( eGetMode == GETFLD_ALL ) 2309 // zuerst die Bereiche einsammeln. Alle die ueber Bedingung 2310 // gehiddet sind, wieder mit Frames versorgen, damit die darin 2311 // enthaltenen Felder richtig einsortiert werden!!! 2312 { 2313 // damit die Frames richtig angelegt werden, muessen sie in der 2314 // Reihenfolgen von oben nach unten expandiert werden 2315 SvULongs aTmpArr; 2316 SwSectionFmts& rArr = rDoc.GetSections(); 2317 SwSectionNode* pSectNd; 2318 sal_uInt16 nArrStt = 0; 2319 sal_uLong nSttCntnt = rDoc.GetNodes().GetEndOfExtras().GetIndex(); 2320 2321 for (sal_uInt16 n = rArr.Count(); n; ) 2322 { 2323 SwSection* pSect = rArr[ --n ]->GetSection(); 2324 if( pSect && pSect->IsHidden() && pSect->GetCondition().Len() && 2325 0 != ( pSectNd = pSect->GetFmt()->GetSectionNode() )) 2326 { 2327 sal_uLong nIdx = pSectNd->GetIndex(); 2328 sal_uInt16 i; 2329 2330 for( i = 0; i < aTmpArr.Count() && aTmpArr[ i ] < nIdx; ++i ) 2331 ; 2332 aTmpArr.Insert( nIdx, i ); 2333 if( nIdx < nSttCntnt ) 2334 ++nArrStt; 2335 } 2336 } 2337 2338 // erst alle anzeigen, damit die Frames vorhanden sind. Mit deren 2339 // Position wird das BodyAnchor ermittelt. 2340 // Dafuer erst den ContentBereich, dann die Sonderbereiche!!! 2341 for (sal_uInt16 n = nArrStt; n < aTmpArr.Count(); ++n) 2342 { 2343 pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode(); 2344 ASSERT( pSectNd, "Wo ist mein SectionNode" ); 2345 pSectNd->GetSection().SetCondHidden( sal_False ); 2346 } 2347 for (sal_uInt16 n = 0; n < nArrStt; ++n) 2348 { 2349 pSectNd = rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode(); 2350 ASSERT( pSectNd, "Wo ist mein SectionNode" ); 2351 pSectNd->GetSection().SetCondHidden( sal_False ); 2352 } 2353 2354 // so, erst jetzt alle sortiert in die Liste eintragen 2355 for (sal_uInt16 n = 0; n < aTmpArr.Count(); ++n) 2356 { 2357 GetBodyNode( *rDoc.GetNodes()[ aTmpArr[ n ] ]->GetSectionNode() ); 2358 } 2359 } 2360 2361 String sTrue( String::CreateFromAscii( 2362 RTL_CONSTASCII_STRINGPARAM( "sal_True" ))), 2363 sFalse( String::CreateFromAscii( 2364 RTL_CONSTASCII_STRINGPARAM( "sal_False" ))); 2365 2366 sal_Bool bIsDBMgr = 0 != rDoc.GetNewDBMgr(); 2367 sal_uInt16 nWhich, n; 2368 const String* pFormel = 0; 2369 const SfxPoolItem* pItem; 2370 sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_FIELD ); 2371 for( n = 0; n < nMaxItems; ++n ) 2372 { 2373 if( 0 == (pItem = rDoc.GetAttrPool().GetItem2( RES_TXTATR_FIELD, n )) ) 2374 continue; 2375 2376 const SwFmtFld* pFmtFld = (SwFmtFld*)pItem; 2377 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 2378 if( !pTxtFld || !pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) 2379 continue; 2380 2381 const SwField* pFld = pFmtFld->GetField(); 2382 switch( nWhich = pFld->GetTyp()->Which() ) 2383 { 2384 case RES_DBSETNUMBERFLD: 2385 case RES_GETEXPFLD: 2386 if( GETFLD_ALL == eGetMode ) 2387 pFormel = &sTrue; 2388 break; 2389 2390 case RES_DBFLD: 2391 if( GETFLD_EXPAND & eGetMode ) 2392 pFormel = &sTrue; 2393 break; 2394 2395 case RES_SETEXPFLD: 2396 /// fields of subtype <string> have also been add 2397 /// for calculation (eGetMode == GETFLD_CALC). 2398 /// Thus, add fields of subtype <string> in all modes 2399 /// (eGetMode == GETFLD_EXPAND||GETFLD_CALC||GETFLD_ALL) 2400 /// and fields of other subtypes only in the modes 2401 /// (eGetMode == GETFLD_CALC||GETFLD_ALL) 2402 /* "old" if construct - not deleted for history and code review 2403 if( ( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() 2404 ? GETFLD_EXPAND : GETFLD_CALC ) 2405 & eGetMode ) 2406 */ 2407 if ( !(eGetMode == GETFLD_EXPAND) || 2408 (nsSwGetSetExpType::GSE_STRING & pFld->GetSubType()) ) 2409 { 2410 pFormel = &sTrue; 2411 } 2412 break; 2413 2414 case RES_HIDDENPARAFLD: 2415 if( GETFLD_ALL == eGetMode ) 2416 { 2417 pFormel = &pFld->GetPar1(); 2418 if( !pFormel->Len() || pFormel->Equals( sFalse )) 2419 ((SwHiddenParaField*)pFld)->SetHidden( sal_False ); 2420 else if( pFormel->Equals( sTrue )) 2421 ((SwHiddenParaField*)pFld)->SetHidden( sal_True ); 2422 else 2423 break; 2424 2425 pFormel = 0; 2426 // Formatierung anstossen 2427 ((SwFmtFld*)pFmtFld)->ModifyNotification( 0, 0 ); 2428 } 2429 break; 2430 2431 case RES_HIDDENTXTFLD: 2432 if( GETFLD_ALL == eGetMode ) 2433 { 2434 pFormel = &pFld->GetPar1(); 2435 if( !pFormel->Len() || pFormel->Equals( sFalse )) 2436 ((SwHiddenTxtField*)pFld)->SetValue( sal_True ); 2437 else if( pFormel->Equals( sTrue )) 2438 ((SwHiddenTxtField*)pFld)->SetValue( sal_False ); 2439 else 2440 break; 2441 2442 pFormel = 0; 2443 2444 // Feld Evaluieren 2445 ((SwHiddenTxtField*)pFld)->Evaluate(&rDoc); 2446 // Formatierung anstossen 2447 ((SwFmtFld*)pFmtFld)->ModifyNotification( 0, 0 ); 2448 } 2449 break; 2450 2451 case RES_DBNUMSETFLD: 2452 { 2453 SwDBData aDBData(((SwDBNumSetField*)pFld)->GetDBData(&rDoc)); 2454 2455 if ( 2456 (bIsDBMgr && rDoc.GetNewDBMgr()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) && 2457 (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && ((SwDBNumSetField*)pFld)->IsCondValid())) 2458 ) 2459 { 2460 pFormel = &pFld->GetPar1(); 2461 } 2462 } 2463 break; 2464 case RES_DBNEXTSETFLD: 2465 { 2466 SwDBData aDBData(((SwDBNextSetField*)pFld)->GetDBData(&rDoc)); 2467 2468 if ( 2469 (bIsDBMgr && rDoc.GetNewDBMgr()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) && 2470 (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && ((SwDBNextSetField*)pFld)->IsCondValid())) 2471 ) 2472 { 2473 pFormel = &pFld->GetPar1(); 2474 } 2475 } 2476 break; 2477 } 2478 2479 if( pFormel && pFormel->Len() ) 2480 { 2481 GetBodyNode( *pTxtFld, nWhich ); 2482 pFormel = 0; 2483 } 2484 } 2485 nFldLstGetMode = static_cast<sal_uInt8>( eGetMode ); 2486 nNodes = rDoc.GetNodes().Count(); 2487 2488 #ifdef JP_DEBUG 2489 { 2490 SvFileStream sOut( "f:\\x.x", STREAM_STD_WRITE ); 2491 sOut.Seek( STREAM_SEEK_TO_END ); 2492 sOut << "------------------" << endl; 2493 const _SetGetExpFldPtr* pSortLst = pFldSortLst->GetData(); 2494 for( sal_uInt16 n = pFldSortLst->Count(); n; --n, ++pSortLst ) 2495 { 2496 String sStr( (*pSortLst)->GetNode() ); 2497 sStr += "\t, "; 2498 sStr += (*pSortLst)->GetCntnt(); 2499 sStr += "\tNode: "; 2500 sStr += (*pSortLst)->GetFld()->GetTxtNode().StartOfSectionIndex(); 2501 sStr += "\tPos: "; 2502 sStr += *(*pSortLst)->GetFld()->GetStart(); 2503 sStr += "\tType: "; 2504 sStr += (*pSortLst)->GetFld()->GetFld().GetFld()->GetTyp()->Which(); 2505 2506 sOut << sStr.GetStr() << endl; 2507 } 2508 } 2509 #endif 2510 // JP_DEBUG 2511 } 2512 2513 /*-------------------------------------------------------------------- 2514 Beschreibung: 2515 --------------------------------------------------------------------*/ 2516 2517 void SwDocUpdtFld::GetBodyNode( const SwTxtFld& rTFld, sal_uInt16 nFldWhich ) 2518 { 2519 const SwTxtNode& rTxtNd = rTFld.GetTxtNode(); 2520 const SwDoc& rDoc = *rTxtNd.GetDoc(); 2521 2522 // immer den ersten !! (in Tab-Headline, Kopf-/Fuss ) 2523 Point aPt; 2524 const SwCntntFrm* pFrm = rTxtNd.getLayoutFrm( rDoc.GetCurrentLayout(), &aPt, 0, sal_False ); 2525 2526 _SetGetExpFld* pNew = NULL; 2527 sal_Bool bIsInBody = sal_False; 2528 2529 if( !pFrm || pFrm->IsInDocBody() ) 2530 { 2531 // einen Index fuers bestimmen vom TextNode anlegen 2532 SwNodeIndex aIdx( rTxtNd ); 2533 bIsInBody = rDoc.GetNodes().GetEndOfExtras().GetIndex() < aIdx.GetIndex(); 2534 2535 // #104291# dvo: We don't want to update fields in redlines, or those 2536 // in frames whose anchor is in redline. However, we do want to update 2537 // fields in hidden sections. So: In order to be updated, a field 1) 2538 // must have a frame, or 2) it must be in the document body. 2539 if( (pFrm != NULL) || bIsInBody ) 2540 pNew = new _SetGetExpFld( aIdx, &rTFld ); 2541 } 2542 else 2543 { 2544 // einen Index fuers bestimmen vom TextNode anlegen 2545 SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() ); 2546 #ifdef DBG_UTIL 2547 ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ), "wo steht das Feld" ); 2548 #else 2549 GetBodyTxtNode( rDoc, aPos, *pFrm ); 2550 #endif 2551 pNew = new _SetGetExpFld( aPos.nNode, &rTFld, &aPos.nContent ); 2552 } 2553 2554 // bei GetExp.-/DB.-Felder immer das BodyTxtFlag setzen 2555 if( RES_GETEXPFLD == nFldWhich ) 2556 { 2557 SwGetExpField* pGetFld = (SwGetExpField*)rTFld.GetFmtFld().GetField(); 2558 pGetFld->ChgBodyTxtFlag( bIsInBody ); 2559 } 2560 else if( RES_DBFLD == nFldWhich ) 2561 { 2562 SwDBField* pDBFld = (SwDBField*)rTFld.GetFmtFld().GetField(); 2563 pDBFld->ChgBodyTxtFlag( bIsInBody ); 2564 } 2565 2566 if( pNew != NULL ) 2567 if( !pFldSortLst->Insert( pNew )) 2568 delete pNew; 2569 } 2570 2571 void SwDocUpdtFld::GetBodyNode( const SwSectionNode& rSectNd ) 2572 { 2573 const SwDoc& rDoc = *rSectNd.GetDoc(); 2574 _SetGetExpFld* pNew = 0; 2575 2576 if( rSectNd.GetIndex() < rDoc.GetNodes().GetEndOfExtras().GetIndex() ) 2577 { 2578 do { // middle check loop 2579 2580 // dann muessen wir uns mal den Anker besorgen! 2581 // einen Index fuers bestimmen vom TextNode anlegen 2582 SwPosition aPos( rSectNd ); 2583 SwCntntNode* pCNd = rDoc.GetNodes().GoNext( &aPos.nNode ); // zum naechsten ContentNode 2584 2585 if( !pCNd || !pCNd->IsTxtNode() ) 2586 break; 2587 2588 // immer den ersten !! (in Tab-Headline, Kopf-/Fuss ) 2589 Point aPt; 2590 const SwCntntFrm* pFrm = pCNd->getLayoutFrm( rDoc.GetCurrentLayout(), &aPt, 0, sal_False ); 2591 if( !pFrm ) 2592 break; 2593 2594 #ifdef DBG_UTIL 2595 ASSERT( GetBodyTxtNode( rDoc, aPos, *pFrm ), "wo steht das Feld" ); 2596 #else 2597 GetBodyTxtNode( rDoc, aPos, *pFrm ); 2598 #endif 2599 pNew = new _SetGetExpFld( rSectNd, &aPos ); 2600 2601 } while( sal_False ); 2602 } 2603 2604 if( !pNew ) 2605 pNew = new _SetGetExpFld( rSectNd ); 2606 2607 if( !pFldSortLst->Insert( pNew )) 2608 delete pNew; 2609 } 2610 2611 void SwDocUpdtFld::InsertFldType( const SwFieldType& rType ) 2612 { 2613 String sFldName; 2614 switch( rType.Which() ) 2615 { 2616 case RES_USERFLD : 2617 sFldName = ((SwUserFieldType&)rType).GetName(); 2618 break; 2619 case RES_SETEXPFLD: 2620 sFldName = ((SwSetExpFieldType&)rType).GetName(); 2621 break; 2622 default: 2623 ASSERT( !this, "kein gueltiger FeldTyp" ); 2624 } 2625 2626 if( sFldName.Len() ) 2627 { 2628 SetFieldsDirty( sal_True ); 2629 // suchen und aus der HashTabelle entfernen 2630 GetAppCharClass().toLower( sFldName ); 2631 sal_uInt16 n; 2632 2633 SwHash* pFnd = Find( sFldName, GetFldTypeTable(), TBLSZ, &n ); 2634 2635 if( !pFnd ) 2636 { 2637 SwCalcFldType* pNew = new SwCalcFldType( sFldName, &rType ); 2638 pNew->pNext = aFldTypeTable[ n ]; 2639 aFldTypeTable[ n ] = pNew; 2640 } 2641 } 2642 } 2643 2644 void SwDocUpdtFld::RemoveFldType( const SwFieldType& rType ) 2645 { 2646 String sFldName; 2647 switch( rType.Which() ) 2648 { 2649 case RES_USERFLD : 2650 sFldName = ((SwUserFieldType&)rType).GetName(); 2651 break; 2652 case RES_SETEXPFLD: 2653 sFldName = ((SwSetExpFieldType&)rType).GetName(); 2654 break; 2655 } 2656 2657 if( sFldName.Len() ) 2658 { 2659 SetFieldsDirty( sal_True ); 2660 // suchen und aus der HashTabelle entfernen 2661 GetAppCharClass().toLower( sFldName ); 2662 sal_uInt16 n; 2663 2664 SwHash* pFnd = Find( sFldName, GetFldTypeTable(), TBLSZ, &n ); 2665 if( pFnd ) 2666 { 2667 if( aFldTypeTable[ n ] == pFnd ) 2668 aFldTypeTable[ n ] = (SwCalcFldType*)pFnd->pNext; 2669 else 2670 { 2671 SwHash* pPrev = aFldTypeTable[ n ]; 2672 while( pPrev->pNext != pFnd ) 2673 pPrev = pPrev->pNext; 2674 pPrev->pNext = pFnd->pNext; 2675 } 2676 pFnd->pNext = 0; 2677 delete pFnd; 2678 } 2679 } 2680 } 2681 2682 SwDocUpdtFld::SwDocUpdtFld() 2683 : pFldSortLst(0), nFldUpdtPos(LONG_MAX), nFldLstGetMode(0) 2684 { 2685 bInUpdateFlds = bFldsDirty = sal_False; 2686 memset( aFldTypeTable, 0, sizeof( aFldTypeTable ) ); 2687 } 2688 2689 SwDocUpdtFld::~SwDocUpdtFld() 2690 { 2691 delete pFldSortLst; 2692 2693 for( sal_uInt16 n = 0; n < TBLSZ; ++n ) 2694 delete aFldTypeTable[n]; 2695 } 2696 2697 // #111840# 2698 bool SwDoc::UpdateFld(SwTxtFld * pDstTxtFld, SwField & rSrcFld, 2699 SwMsgPoolItem * pMsgHnt, 2700 bool bUpdateFlds) 2701 { 2702 ASSERT(pDstTxtFld, "no field to update!"); 2703 2704 sal_Bool bTblSelBreak = sal_False; 2705 2706 SwFmtFld * pDstFmtFld = (SwFmtFld*)&pDstTxtFld->GetFmtFld(); 2707 SwField * pDstFld = pDstFmtFld->GetField(); 2708 sal_uInt16 nFldWhich = rSrcFld.GetTyp()->Which(); 2709 SwNodeIndex aTblNdIdx(pDstTxtFld->GetTxtNode()); 2710 2711 if (pDstFld->GetTyp()->Which() == 2712 rSrcFld.GetTyp()->Which()) 2713 { 2714 if (GetIDocumentUndoRedo().DoesUndo()) 2715 { 2716 SwPosition aPosition( pDstTxtFld->GetTxtNode() ); 2717 aPosition.nContent = *pDstTxtFld->GetStart(); 2718 2719 SwUndo *const pUndo( new SwUndoFieldFromDoc( 2720 aPosition, *pDstFld, rSrcFld, pMsgHnt, bUpdateFlds) ); 2721 GetIDocumentUndoRedo().AppendUndo(pUndo); 2722 } 2723 2724 // Das gefundene Feld wird angepasst ... 2725 //pDstFld->ChangeFormat( rSrcFld.GetFormat() ); 2726 //pDstFld->SetLanguage( rSrcFld.GetLanguage() ); 2727 2728 SwField * pNewFld = rSrcFld.CopyField(); 2729 pDstFmtFld->SetFld(pNewFld); 2730 2731 switch( nFldWhich ) 2732 { 2733 case RES_SETEXPFLD: 2734 case RES_GETEXPFLD: 2735 case RES_HIDDENTXTFLD: 2736 case RES_HIDDENPARAFLD: 2737 UpdateExpFlds( pDstTxtFld, true ); 2738 break; 2739 2740 case RES_TABLEFLD: 2741 { 2742 const SwTableNode* pTblNd = 2743 IsIdxInTbl(aTblNdIdx); 2744 if( pTblNd ) 2745 { 2746 SwTableFmlUpdate aTblUpdate( &pTblNd-> 2747 GetTable() ); 2748 if (bUpdateFlds) 2749 UpdateTblFlds( &aTblUpdate ); 2750 else 2751 pNewFld->GetTyp()->ModifyNotification(0, &aTblUpdate); 2752 2753 if (! bUpdateFlds) 2754 bTblSelBreak = sal_True; 2755 } 2756 } 2757 break; 2758 2759 case RES_MACROFLD: 2760 if( bUpdateFlds && pDstTxtFld->GetpTxtNode() ) 2761 (pDstTxtFld->GetpTxtNode())-> 2762 ModifyNotification( 0, pDstFmtFld ); 2763 break; 2764 2765 case RES_DBNAMEFLD: 2766 case RES_DBNEXTSETFLD: 2767 case RES_DBNUMSETFLD: 2768 case RES_DBSETNUMBERFLD: 2769 ChgDBData(((SwDBNameInfField*) pNewFld)->GetRealDBData()); 2770 pNewFld->GetTyp()->UpdateFlds(); 2771 2772 break; 2773 2774 case RES_DBFLD: 2775 { 2776 // JP 10.02.96: ChgValue aufrufen, damit 2777 //die Format- aenderung den ContentString 2778 //richtig setzt 2779 SwDBField* pDBFld = (SwDBField*)pNewFld; 2780 if (pDBFld->IsInitialized()) 2781 pDBFld->ChgValue( pDBFld->GetValue(), sal_True ); 2782 2783 pDBFld->ClearInitialized(); 2784 pDBFld->InitContent(); 2785 } 2786 // kein break; 2787 2788 default: 2789 pDstFmtFld->ModifyNotification( 0, pMsgHnt ); 2790 } 2791 2792 // Die Felder die wir berechnen koennen werden hier expli. 2793 // zum Update angestossen. 2794 if( nFldWhich == RES_USERFLD ) 2795 UpdateUsrFlds(); 2796 } 2797 2798 return bTblSelBreak; 2799 } 2800 2801 bool SwDoc::PutValueToField(const SwPosition & rPos, 2802 const Any& rVal, sal_uInt16 nWhich) 2803 { 2804 Any aOldVal; 2805 SwField * pField = GetField(rPos); 2806 2807 2808 if (GetIDocumentUndoRedo().DoesUndo() && 2809 pField->QueryValue(aOldVal, nWhich)) 2810 { 2811 SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich)); 2812 GetIDocumentUndoRedo().AppendUndo(pUndo); 2813 } 2814 2815 return pField->PutValue(rVal, nWhich); 2816 } 2817