LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/fields - cellfml.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 7 587 1.2 %
Date: 2012-12-27 Functions: 2 30 6.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10