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 <float.h> 29 #include <hintids.hxx> 30 #include <hints.hxx> 31 #include <fmtfld.hxx> 32 #include <txtfld.hxx> 33 #include <frmfmt.hxx> 34 #include <layfrm.hxx> 35 #include <cntfrm.hxx> 36 #include <tabfrm.hxx> 37 #include <doc.hxx> 38 #include <docary.hxx> 39 #include <ndtxt.hxx> 40 #include <swtable.hxx> 41 #include <tblsel.hxx> 42 #include <cellfml.hxx> 43 #include <calc.hxx> 44 #include <expfld.hxx> 45 #include <usrfld.hxx> 46 #include <flddat.hxx> 47 #include <cellatr.hxx> 48 #include <ndindex.hxx> 49 50 const sal_Unicode cRelTrenner = ','; 51 const sal_Unicode cRelKennung = ''; // CTRL-R 52 53 const sal_uInt16 cMAXSTACKSIZE = 50; 54 55 const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox ); 56 long lcl_GetLongBoxNum( String& rStr ); 57 const SwTableBox* lcl_RelToBox( const SwTable&, const SwTableBox*, const String& ); 58 String lcl_BoxNmToRel( const SwTable&, const SwTableNode&, 59 const String& , const String& , sal_Bool ); 60 61 62 /************************************************************************* 63 |* 64 |* double SwTableBox::GetValue() const 65 |* gebe den Wert dieser Box zurueck. Der Wert ergibt sich aus dem 1. 66 |* TextNode. Beginnt dieser mit einer Zahl/Formel, so berechne diese; 67 |* oder mit einem Feld, dann hole den Wert. 68 |* Alle anderen Bedingungen returnen einen Fehler (oder 0 ?) 69 |* 70 |* Ersterstellung JP 30. Jun. 93 71 |* Letzte Aenderung JP 30. Jun. 93 72 |* 73 |*************************************************************************/ 74 75 double SwTableBox::GetValue( SwTblCalcPara& rCalcPara ) const 76 { 77 double nRet = 0; 78 79 if( rCalcPara.rCalc.IsCalcError() ) 80 return nRet; // schon ein Fehler in der Berechnung 81 82 rCalcPara.rCalc.SetCalcError( CALC_SYNTAX ); // default immer Fehler 83 84 // keine Content Box ? 85 if( !pSttNd ) 86 return nRet; 87 88 if( rCalcPara.IncStackCnt() ) 89 return nRet; 90 91 rCalcPara.SetLastTblBox( this ); 92 93 // wird eine Rekursion erzeugt ? 94 SwTableBox* pBox = (SwTableBox*)this; 95 if( rCalcPara.pBoxStk->Seek_Entry( pBox )) 96 return nRet; // steht schon auf dem Stack: FEHLER 97 98 // bei dieser Box nochmal aufsetzen 99 rCalcPara.SetLastTblBox( this ); 100 101 rCalcPara.pBoxStk->Insert( pBox ); // eintragen 102 do { // Middle-Check-Loop, damit aus dieser gesprungen werden kann 103 // hier aufgespannt, damit am Ende der Box-Pointer aus dem 104 // Stack ausgetragen wird 105 SwDoc* pDoc = GetFrmFmt()->GetDoc(); 106 107 const SfxPoolItem* pItem; 108 if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( 109 RES_BOXATR_FORMULA, sal_False, &pItem ) ) 110 { 111 rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen 112 if( !((SwTblBoxFormula*)pItem)->IsValid() ) 113 { 114 // dann berechnen 115 const SwTable* pTmp = rCalcPara.pTbl; 116 rCalcPara.pTbl = &pBox->GetSttNd()->FindTableNode()->GetTable(); 117 ((SwTblBoxFormula*)pItem)->Calc( rCalcPara, nRet ); 118 119 if( !rCalcPara.IsStackOverFlow() ) 120 { 121 SwFrmFmt* pFmt = pBox->ClaimFrmFmt(); 122 SfxItemSet aTmp( pDoc->GetAttrPool(), 123 RES_BOXATR_BEGIN,RES_BOXATR_END-1 ); 124 aTmp.Put( SwTblBoxValue( nRet ) ); 125 if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT )) 126 aTmp.Put( SwTblBoxNumFormat( 0 )); 127 pFmt->SetFmtAttr( aTmp ); 128 } 129 rCalcPara.pTbl = pTmp; 130 } 131 else 132 nRet = GetFrmFmt()->GetTblBoxValue().GetValue(); 133 break; 134 } 135 else if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( 136 RES_BOXATR_VALUE, sal_False, &pItem ) ) 137 { 138 rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen 139 nRet = ((SwTblBoxValue*)pItem)->GetValue(); 140 break; 141 } 142 143 SwTxtNode* pTxtNd = pDoc->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode(); 144 if( !pTxtNd ) 145 break; 146 147 xub_StrLen nSttPos = 0; 148 const String& rTxt = pTxtNd->GetTxt(); 149 while( nSttPos < rTxt.Len() && 150 ( ' ' == rTxt.GetChar( nSttPos ) || '\t' == rTxt.GetChar( nSttPos ) ) ) 151 ++nSttPos; 152 153 // beginnt an erster Position ein "RechenFeld", dann erfrage den Wert 154 // von diesem 155 sal_Unicode const Char = rTxt.GetChar(nSttPos); 156 if ( nSttPos < rTxt.Len() && 157 ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char ) ) 158 { 159 SwIndex aIdx( pTxtNd, nSttPos ); 160 SwTxtFld * const pTxtFld = static_cast<SwTxtFld*>( 161 pTxtNd->GetTxtAttrForCharAt(aIdx.GetIndex(), RES_TXTATR_FIELD)); 162 if( !pTxtFld ) 163 break; 164 165 rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen 166 167 const SwField* pFld = pTxtFld->GetFmtFld().GetField(); 168 switch( pFld->GetTyp()->Which() ) 169 { 170 case RES_SETEXPFLD: 171 nRet = ((SwSetExpField*)pFld)->GetValue(); 172 break; 173 case RES_USERFLD: 174 nRet = ((SwUserFieldType*)pFld)->GetValue(); 175 break; 176 case RES_TABLEFLD: 177 { 178 SwTblField* pTblFld = (SwTblField*)pFld; 179 if( !pTblFld->IsValid() ) // ist der Wert gueltig ?? 180 { 181 // die richtige Tabelle mitgeben! 182 const SwTable* pTmp = rCalcPara.pTbl; 183 rCalcPara.pTbl = &pTxtNd->FindTableNode()->GetTable(); 184 pTblFld->CalcField( rCalcPara ); 185 rCalcPara.pTbl = pTmp; 186 } 187 nRet = pTblFld->GetValue(); 188 } 189 break; 190 191 case RES_DATETIMEFLD: 192 nRet = ((SwDateTimeField*)pFld)->GetValue(); 193 break; 194 195 case RES_JUMPEDITFLD: 196 //JP 14.09.98: Bug 56112 - der Platzhalter kann nie einen 197 // gueltigen Inhalt haben! 198 nRet = 0; 199 break; 200 201 default: 202 String const value(pFld->ExpandField(true)); 203 nRet = rCalcPara.rCalc.Calculate(value).GetDouble(); 204 } 205 } 206 else 207 { 208 // Ergebnis ist 0 und kein Fehler! 209 rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen 210 211 double aNum; 212 String sTxt( rTxt.Copy( nSttPos ) ); 213 sal_uInt32 nFmtIndex = GetFrmFmt()->GetTblBoxNumFmt().GetValue(); 214 215 SvNumberFormatter* pNumFmtr = pDoc->GetNumberFormatter(); 216 217 if( NUMBERFORMAT_TEXT == nFmtIndex ) 218 nFmtIndex = 0; 219 // JP 22.04.98: Bug 49659 - Sonderbehandlung fuer Prozent 220 else if( sTxt.Len() && 221 NUMBERFORMAT_PERCENT == pNumFmtr->GetType( nFmtIndex )) 222 { 223 sal_uInt32 nTmpFmt = 0; 224 if( pNumFmtr->IsNumberFormat( sTxt, nTmpFmt, aNum ) && 225 NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt )) 226 sTxt += '%'; 227 } 228 229 if( pNumFmtr->IsNumberFormat( sTxt, nFmtIndex, aNum )) 230 nRet = aNum; 231 } 232 233 // ?? sonst ist das ein Fehler 234 } while( sal_False ); 235 236 if( !rCalcPara.IsStackOverFlow() ) 237 { 238 rCalcPara.pBoxStk->Remove( pBox ); // raus aus dem Stack 239 rCalcPara.DecStackCnt(); 240 } 241 242 //JP 12.01.99: mit Fehlererkennung, Bug 60794 243 if( DBL_MAX == nRet ) 244 rCalcPara.rCalc.SetCalcError( CALC_SYNTAX ); // Fehler setzen 245 246 return nRet; 247 } 248 249 /* */ 250 251 // Struktur, die zum TabelleRechnen benoetigt wird 252 253 SwTblCalcPara::SwTblCalcPara( SwCalc& rCalculator, const SwTable& rTable ) 254 : pLastTblBox( 0 ), nStackCnt( 0 ), nMaxSize( cMAXSTACKSIZE ), 255 rCalc( rCalculator ), pTbl( &rTable ) 256 { 257 pBoxStk = new SwTableSortBoxes; 258 } 259 260 SwTblCalcPara::~SwTblCalcPara() 261 { 262 delete pBoxStk; 263 } 264 265 sal_Bool SwTblCalcPara::CalcWithStackOverflow() 266 { 267 // falls ein StackUeberlauf erkannt wurde, sollte mit 268 // der letzten Box noch mal aufgesetzt werden. Irgend 269 // ein Weg sollte dann 270 sal_uInt16 nSaveMaxSize = nMaxSize; 271 272 nMaxSize = cMAXSTACKSIZE - 5; 273 sal_uInt16 nCnt = 0; 274 SwTableBoxes aStackOverFlows; 275 do { 276 SwTableBox* pBox = (SwTableBox*)pLastTblBox; 277 nStackCnt = 0; 278 rCalc.SetCalcError( CALC_NOERR ); 279 aStackOverFlows.C40_INSERT( SwTableBox, pBox, nCnt++ ); 280 281 pBoxStk->Remove( pBox ); 282 pBox->GetValue( *this ); 283 } while( IsStackOverFlow() ); 284 285 nMaxSize = cMAXSTACKSIZE - 3; // es muss mind. 1 Stufe tiefer gehen! 286 287 // falls Rekursionen erkannt wurden 288 nStackCnt = 0; 289 rCalc.SetCalcError( CALC_NOERR ); 290 pBoxStk->Remove( sal_uInt16(0), pBoxStk->Count() ); 291 292 while( !rCalc.IsCalcError() && nCnt ) 293 { 294 aStackOverFlows[ --nCnt ]->GetValue( *this ); 295 if( IsStackOverFlow() && !CalcWithStackOverflow() ) 296 break; 297 } 298 299 nMaxSize = nSaveMaxSize; 300 aStackOverFlows.Remove( 0, aStackOverFlows.Count() ); 301 return !rCalc.IsCalcError(); 302 } 303 304 /* */ 305 306 SwTableFormula::SwTableFormula( const String& rFormel ) 307 : sFormel( rFormel ) 308 { 309 eNmType = EXTRNL_NAME; 310 bValidValue = sal_False; 311 } 312 313 SwTableFormula::~SwTableFormula() 314 { 315 } 316 317 void SwTableFormula::_MakeFormel( const SwTable& rTbl, String& rNewStr, 318 String& rFirstBox, String* pLastBox, void* pPara ) const 319 { 320 SwTblCalcPara* pCalcPara = (SwTblCalcPara*)pPara; 321 if( pCalcPara->rCalc.IsCalcError() ) // ist schon Fehler gesetzt ? 322 return; 323 324 SwTableBox* pSttBox, *pEndBox = 0; 325 326 rFirstBox.Erase(0,1); // Kennung fuer Box loeschen 327 // ein Bereich in dieser Klammer ? 328 if( pLastBox ) 329 { 330 pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); 331 332 // ist das ueberhaupt ein gueltiger Pointer ?? 333 if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox )) 334 pEndBox = 0; 335 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 336 } 337 pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); 338 // ist das ueberhaupt ein gueltiger Pointer ?? 339 if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox )) 340 pSttBox = 0; 341 342 rNewStr += ' '; 343 if( pEndBox && pSttBox ) // Bereich ? 344 { 345 // hole ueber das Layout alle "selectierten" Boxen und berechne 346 // deren Werte 347 SwSelBoxes aBoxes; 348 GetBoxes( *pSttBox, *pEndBox, aBoxes ); 349 350 rNewStr += '('; 351 bool bDelim = false; 352 for( sal_uInt16 n = 0; n < aBoxes.Count() && 353 !pCalcPara->rCalc.IsCalcError(); ++n ) 354 { 355 const SwTableBox* pTblBox = aBoxes[n]; 356 if ( pTblBox->getRowSpan() >= 1 ) 357 { 358 if( bDelim ) 359 rNewStr += cListDelim; 360 bDelim = true; 361 rNewStr += pCalcPara->rCalc.GetStrResult( 362 pTblBox->GetValue( *pCalcPara ), sal_False ); 363 } 364 } 365 rNewStr += ')'; 366 } 367 else if( pSttBox && !pLastBox ) // nur die StartBox ? 368 { 369 //JP 12.01.99: und keine EndBox in der Formel! 370 // Berechne den Wert der Box 371 if ( pSttBox->getRowSpan() >= 1 ) 372 { 373 rNewStr += pCalcPara->rCalc.GetStrResult( 374 pSttBox->GetValue( *pCalcPara ), sal_False ); 375 } 376 } 377 else 378 pCalcPara->rCalc.SetCalcError( CALC_SYNTAX ); // Fehler setzen 379 rNewStr += ' '; 380 } 381 382 void SwTableFormula::RelNmsToBoxNms( const SwTable& rTbl, String& rNewStr, 383 String& rFirstBox, String* pLastBox, void* pPara ) const 384 { 385 // relativen Namen zu Box-Namen (externe Darstellung) 386 SwNode* pNd = (SwNode*)pPara; 387 ASSERT( pNd, "Feld steht in keinem TextNode" ); 388 const SwTableBox *pRelBox, *pBox = (SwTableBox *)rTbl.GetTblBox( 389 pNd->FindTableBoxStartNode()->GetIndex() ); 390 391 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 392 rFirstBox.Erase(0,1); 393 if( pLastBox ) 394 { 395 if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) ) 396 rNewStr += pRelBox->GetName(); 397 else 398 rNewStr.AppendAscii("A1"); 399 rNewStr += ':'; 400 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 401 } 402 403 if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) ) 404 rNewStr += pRelBox->GetName(); 405 else 406 rNewStr.AppendAscii("A1"); 407 408 // Kennung fuer Box erhalten 409 rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 410 } 411 412 void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTbl, String& rNewStr, 413 String& rFirstBox, String* pLastBox, void* pPara ) const 414 { 415 // relativen Namen zu Box-Pointern (interne Darstellung) 416 SwNode* pNd = (SwNode*)pPara; 417 ASSERT( pNd, "Feld steht in keinem Node" ); 418 const SwTableBox *pRelBox, *pBox = (SwTableBox*)rTbl.GetTblBox( 419 pNd->FindTableBoxStartNode()->GetIndex() ); 420 421 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 422 rFirstBox.Erase(0,1); 423 if( pLastBox ) 424 { 425 if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) ) 426 rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox ); 427 else 428 rNewStr += '0'; 429 rNewStr += ':'; 430 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 431 } 432 433 if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) ) 434 rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox ); 435 else 436 rNewStr += '0'; 437 438 // Kennung fuer Box erhalten 439 rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 440 } 441 442 443 void SwTableFormula::BoxNmsToRelNm( const SwTable& rTbl, String& rNewStr, 444 String& rFirstBox, String* pLastBox, void* pPara ) const 445 { 446 // Box-Namen (externe Darstellung) zu relativen Namen 447 SwNode* pNd = (SwNode*)pPara; 448 ASSERT( pNd, "Feld steht in keinem Node" ); 449 const SwTableNode* pTblNd = pNd->FindTableNode(); 450 451 String sRefBoxNm; 452 if( &pTblNd->GetTable() == &rTbl ) 453 { 454 const SwTableBox *pBox = rTbl.GetTblBox( 455 pNd->FindTableBoxStartNode()->GetIndex() ); 456 ASSERT( pBox, "Feld steht in keiner Tabelle" ); 457 sRefBoxNm = pBox->GetName(); 458 } 459 460 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 461 rFirstBox.Erase(0,1); 462 if( pLastBox ) 463 { 464 rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, *pLastBox, 465 eNmType == EXTRNL_NAME ); 466 rNewStr += ':'; 467 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 468 } 469 470 rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, rFirstBox, 471 eNmType == EXTRNL_NAME ); 472 473 // Kennung fuer Box erhalten 474 rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 475 } 476 477 478 void SwTableFormula::PtrToBoxNms( const SwTable& rTbl, String& rNewStr, 479 String& rFirstBox, String* pLastBox, void* ) const 480 { 481 // ein Bereich in dieser Klammer ? 482 SwTableBox* pBox; 483 484 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 485 rFirstBox.Erase(0,1); 486 if( pLastBox ) 487 { 488 pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); 489 490 // ist das ueberhaupt ein gueltiger Pointer ?? 491 if( rTbl.GetTabSortBoxes().Seek_Entry( pBox )) 492 rNewStr += pBox->GetName(); 493 else 494 rNewStr += '?'; 495 rNewStr += ':'; 496 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 497 } 498 499 pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); 500 // ist das ueberhaupt ein gueltiger Pointer ?? 501 if( rTbl.GetTabSortBoxes().Seek_Entry( pBox )) 502 rNewStr += pBox->GetName(); 503 else 504 rNewStr += '?'; 505 506 // Kennung fuer Box erhalten 507 rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 508 } 509 510 void SwTableFormula::BoxNmsToPtr( const SwTable& rTbl, String& rNewStr, 511 String& rFirstBox, String* pLastBox, void* ) const 512 { 513 // ein Bereich in dieser Klammer ? 514 const SwTableBox* pBox; 515 516 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 517 rFirstBox.Erase(0,1); 518 if( pLastBox ) 519 { 520 pBox = rTbl.GetTblBox( *pLastBox ); 521 rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox ); 522 rNewStr += ':'; 523 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 524 } 525 526 pBox = rTbl.GetTblBox( rFirstBox ); 527 rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox ); 528 529 // Kennung fuer Box erhalten 530 rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 531 } 532 533 // erzeuge die externe (fuer UI) Formel 534 void SwTableFormula::PtrToBoxNm( const SwTable* pTbl ) 535 { 536 const SwNode* pNd = 0; 537 FnScanFormel fnFormel = 0; 538 switch( eNmType) 539 { 540 case INTRNL_NAME: 541 if( pTbl ) 542 fnFormel = &SwTableFormula::PtrToBoxNms; 543 break; 544 case REL_NAME: 545 if( pTbl ) 546 { 547 fnFormel = &SwTableFormula::RelNmsToBoxNms; 548 pNd = GetNodeOfFormula(); 549 } 550 break; 551 case EXTRNL_NAME: 552 return; 553 } 554 sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); 555 eNmType = EXTRNL_NAME; 556 } 557 558 // erzeuge die interne (in CORE) Formel 559 void SwTableFormula::BoxNmToPtr( const SwTable* pTbl ) 560 { 561 const SwNode* pNd = 0; 562 FnScanFormel fnFormel = 0; 563 switch( eNmType) 564 { 565 case EXTRNL_NAME: 566 if( pTbl ) 567 fnFormel = &SwTableFormula::BoxNmsToPtr; 568 break; 569 case REL_NAME: 570 if( pTbl ) 571 { 572 fnFormel = &SwTableFormula::RelBoxNmsToPtr; 573 pNd = GetNodeOfFormula(); 574 } 575 break; 576 case INTRNL_NAME: 577 return; 578 } 579 sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); 580 eNmType = INTRNL_NAME; 581 } 582 583 // erzeuge die relative (fuers Kopieren) Formel 584 void SwTableFormula::ToRelBoxNm( const SwTable* pTbl ) 585 { 586 const SwNode* pNd = 0; 587 FnScanFormel fnFormel = 0; 588 switch( eNmType) 589 { 590 case INTRNL_NAME: 591 case EXTRNL_NAME: 592 if( pTbl ) 593 { 594 fnFormel = &SwTableFormula::BoxNmsToRelNm; 595 pNd = GetNodeOfFormula(); 596 } 597 break; 598 case REL_NAME: 599 return; 600 } 601 sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); 602 eNmType = REL_NAME; 603 } 604 605 606 String SwTableFormula::ScanString( FnScanFormel fnFormel, const SwTable& rTbl, 607 void* pPara ) const 608 { 609 String aStr; 610 sal_uInt16 nFml = 0, nStt = 0, nEnd = 0, nTrenner; 611 612 do { 613 // falls der Formel ein Name vorangestellt ist, diese Tabelle 614 // benutzen !! 615 const SwTable* pTbl = &rTbl; 616 617 nStt = sFormel.Search( '<', nFml ); 618 if( STRING_NOTFOUND != nStt ) 619 { 620 while( STRING_NOTFOUND != nStt && 621 ( ' ' == sFormel.GetChar( nStt + 1 ) || 622 '=' == sFormel.GetChar( nStt + 1 ) ) ) 623 nStt = sFormel.Search( '<', nStt + 1 ); 624 625 if( STRING_NOTFOUND != nStt ) 626 nEnd = sFormel.Search( '>', nStt+1 ); 627 } 628 if( STRING_NOTFOUND == nStt || STRING_NOTFOUND == nEnd ) 629 { 630 // den Rest setzen und beenden 631 aStr.Insert( sFormel, nFml, sFormel.Len() - nFml ); 632 break; 633 } 634 aStr.Insert( sFormel, nFml, nStt - nFml ); // Anfang schreiben 635 636 if( fnFormel != NULL ) 637 { 638 // ist ein TabellenName vorangestellt ?? 639 // JP 16.02.99: SplitMergeBoxNm behandeln den Namen selbst 640 // JP 22.02.99: der CAST muss fuer den Linux-Compiler sein 641 // JP 28.06.99: rel. BoxName have no preceding tablename! 642 if( fnFormel != (FnScanFormel)&SwTableFormula::_SplitMergeBoxNm && 643 1 < sFormel.Len() && cRelKennung != sFormel.GetChar( 1 ) && 644 STRING_NOTFOUND != ( nTrenner = sFormel.Search( '.', nStt )) 645 && nTrenner < nEnd ) 646 { 647 String sTblNm( sFormel.Copy( nStt, nEnd - nStt )); 648 649 // falls im Namen schon die Punkte enthalten sind, 650 // treten diese immer paarig auf!!! (A1.1.1 !!) 651 if( (sTblNm.GetTokenCount( '.' ) - 1 ) & 1 ) 652 { 653 sTblNm.Erase( nTrenner - nStt ); 654 655 // beim Bauen der Formel ist der TabellenName unerwuenscht 656 //JP 22.02.99: der CAST muss fuer den Linux-Compiler sein 657 if( fnFormel != (FnScanFormel)&SwTableFormula::_MakeFormel ) 658 aStr += sTblNm; 659 nStt = nTrenner; 660 661 sTblNm.Erase( 0, 1 ); // Trenner loeschen 662 if( sTblNm != rTbl.GetFrmFmt()->GetName() ) 663 { 664 // dann suchen wir uns mal unsere Tabelle: 665 const SwTable* pFnd = FindTable( 666 *rTbl.GetFrmFmt()->GetDoc(), 667 sTblNm ); 668 if( pFnd ) 669 pTbl = pFnd; 670 // ?? 671 ASSERT( pFnd, "Tabelle nicht gefunden, was nun?" ); 672 } 673 } 674 } 675 676 String sBox( sFormel.Copy( nStt, nEnd - nStt + 1 )); 677 // ein Bereich in dieser Klammer ? 678 if( STRING_NOTFOUND != ( nTrenner = sFormel.Search( ':', nStt )) 679 && nTrenner < nEnd ) 680 { 681 // ohne die Anfangsklammer 682 String aFirstBox( sFormel.Copy( nStt+1, nTrenner - nStt - 1 )); 683 (this->*fnFormel)( *pTbl, aStr, sBox, &aFirstBox, pPara ); 684 } 685 else 686 (this->*fnFormel)( *pTbl, aStr, sBox, 0, pPara ); 687 } 688 689 nFml = nEnd+1; 690 } while( sal_True ); 691 return aStr; 692 } 693 694 const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const String& rNm ) const 695 { 696 const SwFrmFmts& rTblFmts = *rDoc.GetTblFrmFmts(); 697 const SwTable* pTmpTbl, *pRet = 0; 698 for( sal_uInt16 nFmtCnt = rTblFmts.Count(); nFmtCnt; ) 699 { 700 SwFrmFmt* pFmt = rTblFmts[ --nFmtCnt ]; 701 // falls wir von Sw3Writer gerufen werden, dann ist dem 702 // FormatNamen eine Nummer anhaengig 703 SwTableBox* pFBox; 704 if( COMPARE_EQUAL == rNm.CompareTo( pFmt->GetName(), 705 pFmt->GetName().Search( 0x0a ) ) && 706 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) && 707 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && 708 pFBox->GetSttNd() && 709 pFBox->GetSttNd()->GetNodes().IsDocNodes() ) 710 { 711 // eine Tabelle im normalen NodesArr 712 pRet = pTmpTbl; 713 break; 714 } 715 } 716 return pRet; 717 } 718 719 const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox ) 720 { 721 SwNodeIndex aIdx( *rBox.GetSttNd() ); 722 SwCntntNode* pCNd = aIdx.GetNodes().GoNext( &aIdx ); 723 ASSERT( pCNd, "Box hat keinen TextNode" ); 724 Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! 725 return pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, NULL, sal_False ); 726 } 727 728 long lcl_GetLongBoxNum( String& rStr ) 729 { 730 sal_uInt16 nPos; 731 long nRet; 732 if( STRING_NOTFOUND == ( nPos = rStr.Search( cRelTrenner ) )) 733 { 734 nRet = rStr.ToInt32(); 735 rStr.Erase(); 736 } 737 else 738 { 739 nRet = rStr.Copy( 0, nPos ).ToInt32(); 740 rStr.Erase( 0, nPos+1 ); 741 } 742 return nRet; 743 } 744 745 const SwTableBox* lcl_RelToBox( const SwTable& rTbl, 746 const SwTableBox* pRefBox, 747 const String& rGetName ) 748 { 749 // hole die Line 750 const SwTableBox* pBox = 0; 751 String sGetName( rGetName ); 752 753 // ist es denn wirklich eine relative Angabe?? 754 if( cRelKennung == sGetName.GetChar(0) ) // ja, ... 755 { 756 if( !pRefBox ) 757 return 0; 758 759 sGetName.Erase( 0, 1 ); 760 761 const SwTableLines* pLines = (SwTableLines*)&rTbl.GetTabLines(); 762 const SwTableBoxes* pBoxes; 763 const SwTableLine* pLine; 764 765 // bestimme erst mal die Start-Werte der Box: 766 pBox = (SwTableBox*)pRefBox; 767 pLine = pBox->GetUpper(); 768 while( pLine->GetUpper() ) 769 { 770 pBox = pLine->GetUpper(); 771 pLine = pBox->GetUpper(); 772 } 773 sal_uInt16 nSttBox = pLine->GetTabBoxes().GetPos( pBox ); 774 sal_uInt16 nSttLine = rTbl.GetTabLines().GetPos( pLine ); 775 776 long nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox; 777 long nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine; 778 779 if( nBoxOffset < 0 || nBoxOffset >= USHRT_MAX || 780 nLineOffset < 0 || nLineOffset >= USHRT_MAX ) 781 return 0; 782 783 if( nLineOffset >= long(pLines->Count()) ) 784 return 0; 785 786 pLine = (*pLines)[ sal_uInt16(nLineOffset) ]; 787 788 // dann suche die Box 789 pBoxes = &pLine->GetTabBoxes(); 790 if( nBoxOffset >= long(pBoxes->Count()) ) 791 return 0; 792 pBox = (*pBoxes)[ sal_uInt16(nBoxOffset) ]; 793 794 while( sGetName.Len() ) 795 { 796 nSttBox = SwTable::_GetBoxNum( sGetName ); 797 pLines = &pBox->GetTabLines(); 798 if( nSttBox ) 799 --nSttBox; 800 801 nSttLine = SwTable::_GetBoxNum( sGetName ); 802 803 // bestimme die Line 804 if( !nSttLine || nSttLine > pLines->Count() ) 805 break; 806 pLine = (*pLines)[ nSttLine-1 ]; 807 808 // bestimme die Box 809 pBoxes = &pLine->GetTabBoxes(); 810 if( nSttBox >= pBoxes->Count() ) 811 break; 812 pBox = (*pBoxes)[ nSttBox ]; 813 } 814 815 if( pBox ) 816 { 817 if( !pBox->GetSttNd() ) 818 // "herunterfallen lassen" bis zur ersten Box 819 while( pBox->GetTabLines().Count() ) 820 pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0]; 821 } 822 } 823 else 824 { 825 // sonst ist es eine absolute externe Darstellung: 826 pBox = rTbl.GetTblBox( sGetName ); 827 } 828 return pBox; 829 } 830 831 String lcl_BoxNmToRel( const SwTable& rTbl, const SwTableNode& rTblNd, 832 const String& rRefBoxNm, const String& rGetStr, 833 sal_Bool bExtrnlNm ) 834 { 835 String sCpy( rRefBoxNm ); 836 String sTmp( rGetStr ); 837 if( !bExtrnlNm ) 838 { 839 // in die Externe Darstellung umwandeln. 840 SwTableBox* pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(sTmp.ToInt64())); 841 if( !rTbl.GetTabSortBoxes().Seek_Entry( pBox )) 842 return '?'; 843 sTmp = pBox->GetName(); 844 } 845 846 // sollte die es eine Tabellen uebergreifende Formel sein, dann behalte 847 // die externe Darstellung bei: 848 if( &rTbl == &rTblNd.GetTable() ) 849 { 850 long nBox = SwTable::_GetBoxNum( sTmp, sal_True ); 851 nBox -= SwTable::_GetBoxNum( sCpy, sal_True ); 852 long nLine = SwTable::_GetBoxNum( sTmp ); 853 nLine -= SwTable::_GetBoxNum( sCpy ); 854 855 sCpy = sTmp; //JP 01.11.95: den Rest aus dem BoxNamen anhaengen 856 857 sTmp = cRelKennung; 858 sTmp += String::CreateFromInt32( nBox ); 859 sTmp += cRelTrenner; 860 sTmp += String::CreateFromInt32( nLine ); 861 862 if( sCpy.Len() ) 863 { 864 sTmp += cRelTrenner; 865 sTmp += sCpy; 866 } 867 } 868 869 if( sTmp.Len() && '>' == sTmp.GetChar( sTmp.Len() - 1 )) 870 sTmp.Erase( sTmp.Len()-1 ); 871 872 return sTmp; 873 } 874 875 sal_uInt16 SwTableFormula::GetBoxesOfFormula( const SwTable& rTbl, 876 SwSelBoxes& rBoxes ) 877 { 878 if( rBoxes.Count() ) 879 rBoxes.Remove( sal_uInt16(0), rBoxes.Count() ); 880 881 BoxNmToPtr( &rTbl ); 882 ScanString( &SwTableFormula::_GetFmlBoxes, rTbl, &rBoxes ); 883 return rBoxes.Count(); 884 } 885 886 void SwTableFormula::_GetFmlBoxes( const SwTable& rTbl, String& , 887 String& rFirstBox, String* pLastBox, void* pPara ) const 888 { 889 SwSelBoxes* pBoxes = (SwSelBoxes*)pPara; 890 SwTableBox* pSttBox, *pEndBox = 0; 891 892 rFirstBox.Erase(0,1); // Kennung fuer Box loeschen 893 // ein Bereich in dieser Klammer ? 894 if( pLastBox ) 895 { 896 pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); 897 898 // ist das ueberhaupt ein gueltiger Pointer ?? 899 if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox )) 900 pEndBox = 0; 901 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 902 } 903 904 pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); 905 // ist das ueberhaupt ein gueltiger Pointer ?? 906 if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox )) 907 pSttBox = 0; 908 909 if( pEndBox && pSttBox ) // Bereich ? 910 { 911 // ueber das Layout alle "selectierten" Boxen und berechne 912 // deren Werte 913 SwSelBoxes aBoxes; 914 GetBoxes( *pSttBox, *pEndBox, aBoxes ); 915 pBoxes->Insert( &aBoxes ); 916 } 917 else if( pSttBox ) // nur die StartBox ? 918 pBoxes->Insert( pSttBox ); 919 } 920 921 void SwTableFormula::GetBoxes( const SwTableBox& rSttBox, 922 const SwTableBox& rEndBox, 923 SwSelBoxes& rBoxes ) const 924 { 925 // hole ueber das Layout alle "selektierten" Boxen 926 const SwLayoutFrm *pStt, *pEnd; 927 const SwFrm* pFrm = lcl_GetBoxFrm( rSttBox ); 928 pStt = pFrm ? pFrm->GetUpper() : 0; 929 pEnd = ( 0 != (pFrm = lcl_GetBoxFrm( rEndBox ))) ? pFrm->GetUpper() : 0; 930 if( !pStt || !pEnd ) 931 return ; // no valid selection 932 933 GetTblSel( pStt, pEnd, rBoxes, 0 ); 934 935 const SwTable* pTbl = pStt->FindTabFrm()->GetTable(); 936 937 // filter die Kopfzeilen-Boxen heraus: 938 if( pTbl->GetRowsToRepeat() > 0 ) 939 { 940 do { // middle-check loop 941 const SwTableLine* pLine = rSttBox.GetUpper(); 942 while( pLine->GetUpper() ) 943 pLine = pLine->GetUpper()->GetUpper(); 944 945 if( pTbl->IsHeadline( *pLine ) ) 946 break; // Headline mit im Bereich ! 947 948 // vielleicht ist ja Start und Ende vertauscht 949 pLine = rEndBox.GetUpper(); 950 while ( pLine->GetUpper() ) 951 pLine = pLine->GetUpper()->GetUpper(); 952 953 if( pTbl->IsHeadline( *pLine ) ) 954 break; // Headline mit im Bereich ! 955 956 const SwTabFrm *pTable = pStt->FindTabFrm(); 957 const SwTabFrm *pEndTable = pEnd->FindTabFrm(); 958 959 if( pTable == pEndTable ) // keine gespl. Tabelle 960 break; 961 962 // dann mal die Tabellenkoepfe raus: 963 for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n ) 964 { 965 pLine = rBoxes[n]->GetUpper(); 966 while( pLine->GetUpper() ) 967 pLine = pLine->GetUpper()->GetUpper(); 968 969 if( pTbl->IsHeadline( *pLine ) ) 970 rBoxes.Remove( n--, 1 ); 971 } 972 } while( sal_False ); 973 } 974 } 975 976 // sind alle Boxen gueltig, auf die sich die Formel bezieht? 977 void SwTableFormula::_HasValidBoxes( const SwTable& rTbl, String& , 978 String& rFirstBox, String* pLastBox, void* pPara ) const 979 { 980 sal_Bool* pBValid = (sal_Bool*)pPara; 981 if( *pBValid ) // einmal falsch, immer falsch 982 { 983 SwTableBox* pSttBox = 0, *pEndBox = 0; 984 rFirstBox.Erase(0,1); // Kennung fuer Box loeschen 985 986 // ein Bereich in dieser Klammer ? 987 if( pLastBox ) 988 rFirstBox.Erase( 0, pLastBox->Len()+1 ); 989 990 switch( eNmType) 991 { 992 case INTRNL_NAME: 993 if( pLastBox ) 994 pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); 995 pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); 996 break; 997 998 case REL_NAME: 999 { 1000 const SwNode* pNd = GetNodeOfFormula(); 1001 const SwTableBox* pBox = !pNd ? 0 1002 : (SwTableBox *)rTbl.GetTblBox( 1003 pNd->FindTableBoxStartNode()->GetIndex() ); 1004 if( pLastBox ) 1005 pEndBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, *pLastBox ); 1006 pSttBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, rFirstBox ); 1007 } 1008 break; 1009 1010 case EXTRNL_NAME: 1011 if( pLastBox ) 1012 pEndBox = (SwTableBox*)rTbl.GetTblBox( *pLastBox ); 1013 pSttBox = (SwTableBox*)rTbl.GetTblBox( rFirstBox ); 1014 break; 1015 } 1016 1017 // sind das gueltige Pointer ? 1018 if( ( pLastBox && 1019 ( !pEndBox || !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ) ) ) || 1020 ( !pSttBox || !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ) ) ) 1021 *pBValid = sal_False; 1022 } 1023 } 1024 1025 sal_Bool SwTableFormula::HasValidBoxes() const 1026 { 1027 sal_Bool bRet = sal_True; 1028 const SwNode* pNd = GetNodeOfFormula(); 1029 if( pNd && 0 != ( pNd = pNd->FindTableNode() ) ) 1030 ScanString( &SwTableFormula::_HasValidBoxes, 1031 ((SwTableNode*)pNd)->GetTable(), &bRet ); 1032 return bRet; 1033 } 1034 1035 1036 sal_uInt16 SwTableFormula::GetLnPosInTbl( const SwTable& rTbl, const SwTableBox* pBox ) 1037 { 1038 sal_uInt16 nRet = USHRT_MAX; 1039 if( pBox ) 1040 { 1041 const SwTableLine* pLn = pBox->GetUpper(); 1042 while( pLn->GetUpper() ) 1043 pLn = pLn->GetUpper()->GetUpper(); 1044 nRet = rTbl.GetTabLines().GetPos( pLn ); 1045 } 1046 return nRet; 1047 } 1048 1049 void SwTableFormula::_SplitMergeBoxNm( const SwTable& rTbl, String& rNewStr, 1050 String& rFirstBox, String* pLastBox, void* pPara ) const 1051 { 1052 SwTableFmlUpdate& rTblUpd = *(SwTableFmlUpdate*)pPara; 1053 1054 rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten 1055 rFirstBox.Erase(0,1); 1056 1057 String sTblNm; 1058 const SwTable* pTbl = &rTbl; 1059 1060 String* pTblNmBox = pLastBox ? pLastBox : &rFirstBox; 1061 1062 sal_uInt16 nLastBoxLen = pTblNmBox->Len(); 1063 sal_uInt16 nTrenner = pTblNmBox->Search( '.' ); 1064 if( STRING_NOTFOUND != nTrenner && 1065 // falls im Namen schon die Punkte enthalten sind, 1066 // treten diese immer paarig auf!!! (A1.1.1 !!) 1067 (pTblNmBox->GetTokenCount( '.' ) - 1 ) & 1 ) 1068 { 1069 sTblNm = pTblNmBox->Copy( 0, nTrenner ); 1070 pTblNmBox->Erase( 0, nTrenner + 1);// den Punkt entfernen 1071 const SwTable* pFnd = FindTable( *rTbl.GetFrmFmt()->GetDoc(), sTblNm ); 1072 if( pFnd ) 1073 pTbl = pFnd; 1074 1075 if( TBL_MERGETBL == rTblUpd.eFlags ) 1076 { 1077 if( pFnd ) 1078 { 1079 if( pFnd == rTblUpd.DATA.pDelTbl ) 1080 { 1081 if( rTblUpd.pTbl != &rTbl ) // es ist nicht die akt. 1082 (rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) 1083 += '.'; // den neuen Tabellen Namen setzen 1084 rTblUpd.bModified = sal_True; 1085 } 1086 else if( pFnd != rTblUpd.pTbl || 1087 ( rTblUpd.pTbl != &rTbl && &rTbl != rTblUpd.DATA.pDelTbl)) 1088 (rNewStr += sTblNm ) += '.'; // den Tabellen Namen behalten 1089 else 1090 rTblUpd.bModified = sal_True; 1091 } 1092 else 1093 (rNewStr += sTblNm ) += '.'; // den Tabellen Namen behalten 1094 1095 } 1096 } 1097 if( pTblNmBox == pLastBox ) 1098 rFirstBox.Erase( 0, nLastBoxLen + 1 ); 1099 1100 SwTableBox* pSttBox = 0, *pEndBox = 0; 1101 switch( eNmType ) 1102 { 1103 case INTRNL_NAME: 1104 if( pLastBox ) 1105 pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); 1106 pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); 1107 break; 1108 1109 case REL_NAME: 1110 { 1111 const SwNode* pNd = GetNodeOfFormula(); 1112 const SwTableBox* pBox = pNd ? pTbl->GetTblBox( 1113 pNd->FindTableBoxStartNode()->GetIndex() ) : 0; 1114 if( pLastBox ) 1115 pEndBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, *pLastBox ); 1116 pSttBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, rFirstBox ); 1117 } 1118 break; 1119 1120 case EXTRNL_NAME: 1121 if( pLastBox ) 1122 pEndBox = (SwTableBox*)pTbl->GetTblBox( *pLastBox ); 1123 pSttBox = (SwTableBox*)pTbl->GetTblBox( rFirstBox ); 1124 break; 1125 } 1126 1127 if( pLastBox && !pTbl->GetTabSortBoxes().Seek_Entry( pEndBox )) 1128 pEndBox = 0; 1129 if( !pTbl->GetTabSortBoxes().Seek_Entry( pSttBox )) 1130 pSttBox = 0; 1131 1132 if( TBL_SPLITTBL == rTblUpd.eFlags ) 1133 { 1134 // wo liegen die Boxen, in der "alten" oder in der neuen Tabelle? 1135 sal_Bool bInNewTbl = sal_False; 1136 if( pLastBox ) 1137 { 1138 // das ist die "erste" Box in der Selektion. Die bestimmt ob die 1139 // Formel in der alten oder neuen Tabelle steht. 1140 sal_uInt16 nEndLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pEndBox ), 1141 nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox ); 1142 1143 if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos && 1144 ((rTblUpd.nSplitLine <= nSttLnPos) == 1145 (rTblUpd.nSplitLine <= nEndLnPos)) ) 1146 { 1147 // bleiben in der gleichen Tabelle 1148 bInNewTbl = rTblUpd.nSplitLine <= nEndLnPos && 1149 pTbl == rTblUpd.pTbl; 1150 } 1151 else 1152 { 1153 // das ist aufjedenfall eine ungueltige Formel, also fuers 1154 // Undo auf Modified setzen 1155 rTblUpd.bModified = sal_True; 1156 if( pEndBox ) 1157 bInNewTbl = USHRT_MAX != nEndLnPos && 1158 rTblUpd.nSplitLine <= nEndLnPos && 1159 pTbl == rTblUpd.pTbl; 1160 } 1161 } 1162 else 1163 { 1164 sal_uInt16 nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox ); 1165 // dann landet das Teil in der neuen Tabelle? 1166 bInNewTbl = USHRT_MAX != nSttLnPos && 1167 rTblUpd.nSplitLine <= nSttLnPos && 1168 pTbl == rTblUpd.pTbl; 1169 } 1170 1171 // wenn die Formel selbst in der neuen Tabellen landet 1172 if( rTblUpd.bBehindSplitLine ) 1173 { 1174 if( !bInNewTbl ) 1175 { 1176 rTblUpd.bModified = sal_True; 1177 ( rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) += '.'; 1178 } 1179 else if( sTblNm.Len() ) 1180 ( rNewStr += sTblNm ) += '.'; 1181 } 1182 else if( bInNewTbl ) 1183 { 1184 rTblUpd.bModified = sal_True; 1185 ( rNewStr += *rTblUpd.DATA.pNewTblNm ) += '.'; 1186 } 1187 else if( sTblNm.Len() ) 1188 ( rNewStr += sTblNm ) += '.'; 1189 } 1190 1191 if( pLastBox ) 1192 ( rNewStr += String::CreateFromInt64((sal_PtrDiff)pEndBox)) += ':'; 1193 ( rNewStr += String::CreateFromInt64((sal_PtrDiff)pSttBox)) 1194 += rFirstBox.GetChar( rFirstBox.Len() - 1 ); 1195 } 1196 1197 // erzeuge die externe Formel, beachte aber das die Formel 1198 // in einer gesplitteten/gemergten Tabelle landet 1199 void SwTableFormula::ToSplitMergeBoxNm( SwTableFmlUpdate& rTblUpd ) 1200 { 1201 const SwTable* pTbl; 1202 const SwNode* pNd = GetNodeOfFormula(); 1203 if( pNd && 0 != ( pNd = pNd->FindTableNode() )) 1204 pTbl = &((SwTableNode*)pNd)->GetTable(); 1205 else 1206 pTbl = rTblUpd.pTbl; 1207 1208 sFormel = ScanString( &SwTableFormula::_SplitMergeBoxNm, *pTbl, (void*)&rTblUpd ); 1209 eNmType = INTRNL_NAME; 1210 } 1211 1212 1213