LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/fields - cellfml.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 8 612 1.3 %
Date: 2013-07-09 Functions: 4 32 12.5 %
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             : const sal_uInt16 cMAXSTACKSIZE = 50;
      46             : 
      47             : static const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox );
      48             : static long lcl_GetLongBoxNum( String& rStr );
      49             : static const SwTableBox* lcl_RelToBox( const SwTable&, const SwTableBox*, const String& );
      50             : static String lcl_BoxNmToRel( const SwTable&, const SwTableNode&,
      51             :                         const String& , const String& , bool );
      52             : 
      53             : 
      54             : /** Get value of this box.
      55             :  *
      56             :  * The value is comes from the first TextNode. If it starts with a number/
      57             :  * formula then calculate it, if it starts with a field then get the value.
      58             :  * All other conditions return 0 (and an error?).
      59             :  */
      60           0 : double SwTableBox::GetValue( SwTblCalcPara& rCalcPara ) const
      61             : {
      62           0 :     double nRet = 0;
      63             : 
      64           0 :     if( rCalcPara.rCalc.IsCalcError() )
      65           0 :         return nRet;            // stop if there is already an error set
      66             : 
      67           0 :     rCalcPara.rCalc.SetCalcError( CALC_SYNTAX );    // default: error
      68             : 
      69             :     // no content box?
      70           0 :     if( !pSttNd  )
      71           0 :         return nRet;
      72             : 
      73           0 :     if( rCalcPara.IncStackCnt() )
      74           0 :         return nRet;
      75             : 
      76           0 :     rCalcPara.SetLastTblBox( this );
      77             : 
      78             :     // Does it create a recursion?
      79           0 :     SwTableBox* pBox = (SwTableBox*)this;
      80           0 :     if( rCalcPara.pBoxStk->find( pBox ) != rCalcPara.pBoxStk->end() )
      81           0 :         return nRet;            // already on the stack: error
      82             : 
      83             :     // re-start with this box
      84           0 :     rCalcPara.SetLastTblBox( this );
      85             : 
      86           0 :     rCalcPara.pBoxStk->insert( pBox );      // add
      87             :     do {        // Middle-Check-Loop, so that we can jump from here. Used so that the box pointer
      88             :                 // will be removed from stack at the end.
      89           0 :         SwDoc* pDoc = GetFrmFmt()->GetDoc();
      90             : 
      91             :         const SfxPoolItem* pItem;
      92           0 :         if( SFX_ITEM_SET == GetFrmFmt()->GetItemState(
      93           0 :                                 RES_BOXATR_FORMULA, sal_False, &pItem ) )
      94             :         {
      95           0 :             rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // reset status
      96           0 :             if( !((SwTblBoxFormula*)pItem)->IsValid() )
      97             :             {
      98             :                 // calculate
      99           0 :                 const SwTable* pTmp = rCalcPara.pTbl;
     100           0 :                 rCalcPara.pTbl = &pBox->GetSttNd()->FindTableNode()->GetTable();
     101           0 :                 ((SwTblBoxFormula*)pItem)->Calc( rCalcPara, nRet );
     102             : 
     103           0 :                 if( !rCalcPara.IsStackOverFlow() )
     104             :                 {
     105           0 :                     SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
     106           0 :                     SfxItemSet aTmp( pDoc->GetAttrPool(),
     107           0 :                                         RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
     108           0 :                     aTmp.Put( SwTblBoxValue( nRet ) );
     109           0 :                     if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
     110           0 :                         aTmp.Put( SwTblBoxNumFormat( 0 ));
     111           0 :                     pFmt->SetFmtAttr( aTmp );
     112             :                 }
     113           0 :                 rCalcPara.pTbl = pTmp;
     114             :             }
     115             :             else
     116           0 :                 nRet = GetFrmFmt()->GetTblBoxValue().GetValue();
     117           0 :             break;
     118             :         }
     119           0 :         else if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
     120           0 :                                 RES_BOXATR_VALUE, sal_False, &pItem ) )
     121             :         {
     122           0 :             rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // reset status
     123           0 :             nRet = ((SwTblBoxValue*)pItem)->GetValue();
     124           0 :             break;
     125             :         }
     126             : 
     127           0 :         SwTxtNode* pTxtNd = pDoc->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
     128           0 :         if( !pTxtNd )
     129           0 :             break;
     130             : 
     131           0 :         xub_StrLen nSttPos = 0;
     132           0 :         const String& rTxt = pTxtNd->GetTxt();
     133           0 :         while( nSttPos < rTxt.Len() &&
     134           0 :                 ( ' ' ==  rTxt.GetChar( nSttPos ) || '\t' ==  rTxt.GetChar( nSttPos ) ) )
     135           0 :             ++nSttPos;
     136             : 
     137             :         // if there is a calculation field at position 1, get the value of it
     138           0 :         sal_Unicode const Char = rTxt.GetChar(nSttPos);
     139           0 :         if ( nSttPos < rTxt.Len() &&
     140           0 :              ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char ) )
     141             :         {
     142           0 :             SwIndex aIdx( pTxtNd, nSttPos );
     143             :             SwTxtFld * const pTxtFld = static_cast<SwTxtFld*>(
     144           0 :                 pTxtNd->GetTxtAttrForCharAt(aIdx.GetIndex(), RES_TXTATR_FIELD));
     145           0 :             if( !pTxtFld )
     146           0 :                 break;
     147             : 
     148           0 :             rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // reset status
     149             : 
     150           0 :             const SwField* pFld = pTxtFld->GetFld().GetFld();
     151           0 :             switch( pFld->GetTyp()->Which()  )
     152             :             {
     153             :             case RES_SETEXPFLD:
     154           0 :                 nRet = ((SwSetExpField*)pFld)->GetValue();
     155           0 :                 break;
     156             :             case RES_USERFLD:
     157           0 :                 nRet = ((SwUserFieldType*)pFld)->GetValue();
     158           0 :                 break;
     159             :             case RES_TABLEFLD:
     160             :                 {
     161           0 :                     SwTblField* pTblFld = (SwTblField*)pFld;
     162           0 :                     if( !pTblFld->IsValid() )
     163             :                     {
     164             :                         // use the right table!
     165           0 :                         const SwTable* pTmp = rCalcPara.pTbl;
     166           0 :                         rCalcPara.pTbl = &pTxtNd->FindTableNode()->GetTable();
     167           0 :                         pTblFld->CalcField( rCalcPara );
     168           0 :                         rCalcPara.pTbl = pTmp;
     169             :                     }
     170           0 :                     nRet = pTblFld->GetValue();
     171             :                 }
     172           0 :                 break;
     173             : 
     174             :             case RES_DATETIMEFLD:
     175           0 :                 nRet = ((SwDateTimeField*)pFld)->GetValue();
     176           0 :                 break;
     177             : 
     178             :             case RES_JUMPEDITFLD:
     179             :                 //JP 14.09.98: Bug 56112 - placeholder never have the right content!
     180           0 :                 nRet = 0;
     181           0 :                 break;
     182             : 
     183             :             default:
     184           0 :                 String const value(pFld->ExpandField(true));
     185           0 :                 nRet = rCalcPara.rCalc.Calculate(value).GetDouble();
     186           0 :             }
     187             :         }
     188             :         else
     189             :         {
     190             :             // result is 0 but no error!
     191           0 :             rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // reset status
     192             : 
     193             :             double aNum;
     194           0 :             String sTxt( rTxt.Copy( nSttPos ) );
     195           0 :             sal_uInt32 nFmtIndex = GetFrmFmt()->GetTblBoxNumFmt().GetValue();
     196             : 
     197           0 :             SvNumberFormatter* pNumFmtr = pDoc->GetNumberFormatter();
     198             : 
     199           0 :             if( NUMBERFORMAT_TEXT == nFmtIndex )
     200           0 :                 nFmtIndex = 0;
     201             :             // JP 22.04.98: Bug 49659 - special treatment for percentages
     202           0 :             else if( sTxt.Len() &&
     203           0 :                     NUMBERFORMAT_PERCENT == pNumFmtr->GetType( nFmtIndex ))
     204             :             {
     205           0 :                 sal_uInt32 nTmpFmt = 0;
     206           0 :                 if( pNumFmtr->IsNumberFormat( sTxt, nTmpFmt, aNum ) &&
     207           0 :                     NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt ))
     208           0 :                     sTxt += '%';
     209             :             }
     210             : 
     211           0 :             if( pNumFmtr->IsNumberFormat( sTxt, nFmtIndex, aNum ))
     212           0 :                 nRet = aNum;
     213           0 :         }
     214             :         // ?? otherwise it is an error
     215             :     } while( false );
     216             : 
     217           0 :     if( !rCalcPara.IsStackOverFlow() )
     218             :     {
     219           0 :         rCalcPara.pBoxStk->erase( pBox );      // remove from stack
     220           0 :         rCalcPara.DecStackCnt();
     221             :     }
     222             : 
     223             :     //JP 12.01.99: error detection, Bug 60794
     224           0 :     if( DBL_MAX == nRet )
     225           0 :         rCalcPara.rCalc.SetCalcError( CALC_SYNTAX ); // set error
     226             : 
     227           0 :     return nRet;
     228             : }
     229             : 
     230             : // structure needed for calculation of tables
     231             : 
     232           0 : SwTblCalcPara::SwTblCalcPara( SwCalc& rCalculator, const SwTable& rTable )
     233             :     : pLastTblBox( 0 ), nStackCnt( 0 ), nMaxSize( cMAXSTACKSIZE ),
     234           0 :     rCalc( rCalculator ), pTbl( &rTable )
     235             : {
     236           0 :     pBoxStk = new SwTableSortBoxes;
     237           0 : }
     238             : 
     239           0 : SwTblCalcPara::~SwTblCalcPara()
     240             : {
     241           0 :     delete pBoxStk;
     242           0 : }
     243             : 
     244           0 : sal_Bool SwTblCalcPara::CalcWithStackOverflow()
     245             : {
     246             :     // If a stack overflow was detected, redo with last box.
     247           0 :     sal_uInt16 nSaveMaxSize = nMaxSize;
     248             : 
     249           0 :     nMaxSize = cMAXSTACKSIZE - 5;
     250           0 :     sal_uInt16 nCnt = 0;
     251           0 :     SwTableBoxes aStackOverFlows;
     252           0 :     do {
     253           0 :         SwTableBox* pBox = (SwTableBox*)pLastTblBox;
     254           0 :         nStackCnt = 0;
     255           0 :         rCalc.SetCalcError( CALC_NOERR );
     256           0 :         aStackOverFlows.insert( aStackOverFlows.begin() + nCnt++, pBox );
     257             : 
     258           0 :         pBoxStk->erase( pBox );
     259           0 :         pBox->GetValue( *this );
     260           0 :     } while( IsStackOverFlow() );
     261             : 
     262           0 :     nMaxSize = cMAXSTACKSIZE - 3; // decrease at least one level
     263             : 
     264             :     // if recursion was detected
     265           0 :     nStackCnt = 0;
     266           0 :     rCalc.SetCalcError( CALC_NOERR );
     267           0 :     pBoxStk->clear();
     268             : 
     269           0 :     while( !rCalc.IsCalcError() && nCnt )
     270             :     {
     271           0 :         aStackOverFlows[ --nCnt ]->GetValue( *this );
     272           0 :         if( IsStackOverFlow() && !CalcWithStackOverflow() )
     273           0 :             break;
     274             :     }
     275             : 
     276           0 :     nMaxSize = nSaveMaxSize;
     277           0 :     aStackOverFlows.clear();
     278           0 :     return !rCalc.IsCalcError();
     279             : }
     280             : 
     281          33 : SwTableFormula::SwTableFormula( const String& rFormel )
     282          33 :     : sFormel( rFormel )
     283             : {
     284          33 :     eNmType = EXTRNL_NAME;
     285          33 :     bValidValue = false;
     286          33 : }
     287             : 
     288          33 : SwTableFormula::~SwTableFormula()
     289             : {
     290          33 : }
     291             : 
     292           0 : void SwTableFormula::_MakeFormula( const SwTable& rTbl, String& rNewStr,
     293             :                     String& rFirstBox, String* pLastBox, void* pPara ) const
     294             : {
     295           0 :     SwTblCalcPara* pCalcPara = (SwTblCalcPara*)pPara;
     296           0 :     if( pCalcPara->rCalc.IsCalcError() )        // istop if there is already an error set
     297           0 :         return;
     298             : 
     299           0 :     SwTableBox* pSttBox, *pEndBox = 0;
     300             : 
     301           0 :     rFirstBox.Erase(0,1); // erase label of this box
     302             :     // a region in this area?
     303           0 :     if( pLastBox )
     304             :     {
     305           0 :         pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
     306             : 
     307             :         // Is it actually a valid pointer?
     308           0 :         if( rTbl.GetTabSortBoxes().find( pEndBox ) == rTbl.GetTabSortBoxes().end() )
     309           0 :             pEndBox = 0;
     310           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     311             :     }
     312           0 :     pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
     313             :     // Is it actually a valid pointer?
     314           0 :     if( rTbl.GetTabSortBoxes().find( pSttBox ) == rTbl.GetTabSortBoxes().end() )
     315           0 :         pSttBox = 0;
     316             : 
     317           0 :     rNewStr += ' ';
     318           0 :     if( pEndBox && pSttBox )    // area?
     319             :     {
     320             :         // get all selected boxes via layout and calculate their values
     321           0 :         SwSelBoxes aBoxes;
     322           0 :         GetBoxes( *pSttBox, *pEndBox, aBoxes );
     323             : 
     324           0 :         rNewStr += '(';
     325           0 :         bool bDelim = false;
     326           0 :         for (size_t n = 0; n < aBoxes.size() &&
     327           0 :                            !pCalcPara->rCalc.IsCalcError(); ++n)
     328             :         {
     329           0 :             const SwTableBox* pTblBox = aBoxes[n];
     330           0 :             if ( pTblBox->getRowSpan() >= 1 )
     331             :             {
     332           0 :                 if( bDelim )
     333           0 :                     rNewStr += cListDelim;
     334           0 :                 bDelim = true;
     335           0 :                 rNewStr += pCalcPara->rCalc.GetStrResult(
     336           0 :                             pTblBox->GetValue( *pCalcPara ), sal_False );
     337             :             }
     338             :         }
     339           0 :         rNewStr += ')';
     340             :     }
     341           0 :     else if( pSttBox && !pLastBox ) // only the StartBox?
     342             :     {
     343             :         // JP 12.01.99: and no EndBox in the formula!
     344             :         // calculate the value of the box
     345           0 :         if ( pSttBox->getRowSpan() >= 1 )
     346             :         {
     347           0 :             rNewStr += pCalcPara->rCalc.GetStrResult(
     348           0 :                             pSttBox->GetValue( *pCalcPara ), sal_False );
     349             :         }
     350             :     }
     351             :     else
     352           0 :         pCalcPara->rCalc.SetCalcError( CALC_SYNTAX );   // set error
     353           0 :     rNewStr += ' ';
     354             : }
     355             : 
     356           0 : void SwTableFormula::RelNmsToBoxNms( const SwTable& rTbl, String& rNewStr,
     357             :             String& rFirstBox, String* pLastBox, void* pPara ) const
     358             : {
     359             :     // relative name w.r.t. box name (external presentation)
     360           0 :     SwNode* pNd = (SwNode*)pPara;
     361             :     OSL_ENSURE( pNd, "Feld steht in keinem TextNode" );
     362             :     const SwTableBox *pRelBox, *pBox = (SwTableBox *)rTbl.GetTblBox(
     363           0 :                     pNd->FindTableBoxStartNode()->GetIndex() );
     364             : 
     365           0 :     rNewStr += rFirstBox.Copy(0,1); // get label for the box
     366           0 :     rFirstBox.Erase(0,1);
     367           0 :     if( pLastBox )
     368             :     {
     369           0 :         if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
     370           0 :             rNewStr += pRelBox->GetName();
     371             :         else
     372           0 :             rNewStr.AppendAscii("A1");
     373           0 :         rNewStr += ':';
     374           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     375             :     }
     376             : 
     377           0 :     if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
     378           0 :         rNewStr += pRelBox->GetName();
     379             :     else
     380           0 :         rNewStr.AppendAscii("A1");
     381             : 
     382             :     // get label for the box
     383           0 :     rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
     384           0 : }
     385             : 
     386           0 : void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
     387             :             String& rFirstBox, String* pLastBox, void* pPara ) const
     388             : {
     389             :     // relative name w.r.t. box name (internal presentation)
     390           0 :     SwNode* pNd = (SwNode*)pPara;
     391             :     OSL_ENSURE( pNd, "Field not placed in any Node" );
     392             :     const SwTableBox *pRelBox, *pBox = (SwTableBox*)rTbl.GetTblBox(
     393           0 :                     pNd->FindTableBoxStartNode()->GetIndex() );
     394             : 
     395           0 :     rNewStr += rFirstBox.Copy(0,1); // get label for the box
     396           0 :     rFirstBox.Erase(0,1);
     397           0 :     if( pLastBox )
     398             :     {
     399           0 :         if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
     400           0 :             rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pRelBox));
     401             :         else
     402           0 :             rNewStr += '0';
     403           0 :         rNewStr += ':';
     404           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     405             :     }
     406             : 
     407           0 :     if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
     408           0 :         rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pRelBox));
     409             :     else
     410           0 :         rNewStr += '0';
     411             : 
     412             :     // get label for the box
     413           0 :     rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
     414           0 : }
     415             : 
     416           0 : void SwTableFormula::BoxNmsToRelNm( const SwTable& rTbl, String& rNewStr,
     417             :                     String& rFirstBox, String* pLastBox, void* pPara ) const
     418             : {
     419             :     // box name (external presentation) w.r.t. relative name
     420           0 :     SwNode* pNd = (SwNode*)pPara;
     421             :     OSL_ENSURE( pNd, "Field not placed in any Node" );
     422           0 :     const SwTableNode* pTblNd = pNd->FindTableNode();
     423             : 
     424           0 :     String sRefBoxNm;
     425           0 :     if( &pTblNd->GetTable() == &rTbl )
     426             :     {
     427             :         const SwTableBox *pBox = rTbl.GetTblBox(
     428           0 :                 pNd->FindTableBoxStartNode()->GetIndex() );
     429             :         OSL_ENSURE( pBox, "Field not placed in any Table" );
     430           0 :         sRefBoxNm = pBox->GetName();
     431             :     }
     432             : 
     433           0 :     rNewStr += rFirstBox.Copy(0,1); // get label for the box
     434           0 :     rFirstBox.Erase(0,1);
     435           0 :     if( pLastBox )
     436             :     {
     437           0 :         rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, *pLastBox,
     438           0 :                                 eNmType == EXTRNL_NAME );
     439           0 :         rNewStr += ':';
     440           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     441             :     }
     442             : 
     443           0 :     rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, rFirstBox,
     444           0 :                             eNmType == EXTRNL_NAME );
     445             : 
     446             :     // get label for the box
     447           0 :     rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
     448           0 : }
     449             : 
     450             : 
     451           0 : void SwTableFormula::PtrToBoxNms( const SwTable& rTbl, String& rNewStr,
     452             :                         String& rFirstBox, String* pLastBox, void* ) const
     453             : {
     454             :     // area in these parentheses?
     455             :     SwTableBox* pBox;
     456             : 
     457           0 :     rNewStr += rFirstBox.Copy(0,1); // get label for the box
     458           0 :     rFirstBox.Erase(0,1);
     459           0 :     if( pLastBox )
     460             :     {
     461           0 :         pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
     462             : 
     463             :         // Is it actually a valid pointer?
     464           0 :         if( rTbl.GetTabSortBoxes().find( pBox ) != rTbl.GetTabSortBoxes().end() )
     465           0 :             rNewStr += pBox->GetName();
     466             :         else
     467           0 :             rNewStr += '?';
     468           0 :         rNewStr += ':';
     469           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     470             :     }
     471             : 
     472           0 :     pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
     473             :     // Is it actually a valid pointer?
     474           0 :     if( rTbl.GetTabSortBoxes().find( pBox ) != rTbl.GetTabSortBoxes().end() )
     475           0 :         rNewStr += pBox->GetName();
     476             :     else
     477           0 :         rNewStr += '?';
     478             : 
     479             :     // get label for the box
     480           0 :     rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
     481           0 : }
     482             : 
     483           0 : void SwTableFormula::BoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
     484             :                         String& rFirstBox, String* pLastBox, void* ) const
     485             : {
     486             :     // area in these parentheses?
     487             :     const SwTableBox* pBox;
     488             : 
     489           0 :     rNewStr += rFirstBox.Copy(0,1); // get label for the box
     490           0 :     rFirstBox.Erase(0,1);
     491           0 :     if( pLastBox )
     492             :     {
     493           0 :         pBox = rTbl.GetTblBox( *pLastBox );
     494           0 :         rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pBox));
     495           0 :         rNewStr += ':';
     496           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     497             :     }
     498             : 
     499           0 :     pBox = rTbl.GetTblBox( rFirstBox );
     500           0 :     rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pBox));
     501             : 
     502             :     // get label for the box
     503           0 :     rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
     504           0 : }
     505             : 
     506             : /// create external formula (for UI)
     507           0 : void SwTableFormula::PtrToBoxNm( const SwTable* pTbl )
     508             : {
     509           0 :     const SwNode* pNd = 0;
     510           0 :     FnScanFormel fnFormel = 0;
     511           0 :     switch( eNmType)
     512             :     {
     513             :     case INTRNL_NAME:
     514           0 :         if( pTbl )
     515           0 :             fnFormel = &SwTableFormula::PtrToBoxNms;
     516           0 :         break;
     517             :     case REL_NAME:
     518           0 :         if( pTbl )
     519             :         {
     520           0 :             fnFormel = &SwTableFormula::RelNmsToBoxNms;
     521           0 :             pNd = GetNodeOfFormula();
     522             :         }
     523           0 :         break;
     524             :     case EXTRNL_NAME:
     525           0 :         return;
     526             :     }
     527           0 :     sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
     528           0 :     eNmType = EXTRNL_NAME;
     529             : }
     530             : 
     531             : /// create internal formula (in CORE)
     532           0 : void SwTableFormula::BoxNmToPtr( const SwTable* pTbl )
     533             : {
     534           0 :     const SwNode* pNd = 0;
     535           0 :     FnScanFormel fnFormel = 0;
     536           0 :     switch( eNmType)
     537             :     {
     538             :     case EXTRNL_NAME:
     539           0 :         if( pTbl )
     540           0 :             fnFormel = &SwTableFormula::BoxNmsToPtr;
     541           0 :         break;
     542             :     case REL_NAME:
     543           0 :         if( pTbl )
     544             :         {
     545           0 :             fnFormel = &SwTableFormula::RelBoxNmsToPtr;
     546           0 :             pNd = GetNodeOfFormula();
     547             :         }
     548           0 :         break;
     549             :     case INTRNL_NAME:
     550           0 :         return;
     551             :     }
     552           0 :     sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
     553           0 :     eNmType = INTRNL_NAME;
     554             : }
     555             : 
     556             : /// create relative formula (for copy)
     557           0 : void SwTableFormula::ToRelBoxNm( const SwTable* pTbl )
     558             : {
     559           0 :     const SwNode* pNd = 0;
     560           0 :     FnScanFormel fnFormel = 0;
     561           0 :     switch( eNmType)
     562             :     {
     563             :     case INTRNL_NAME:
     564             :     case EXTRNL_NAME:
     565           0 :         if( pTbl )
     566             :         {
     567           0 :             fnFormel = &SwTableFormula::BoxNmsToRelNm;
     568           0 :             pNd = GetNodeOfFormula();
     569             :         }
     570           0 :         break;
     571             :     case REL_NAME:
     572           0 :         return;
     573             :     }
     574           0 :     sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
     575           0 :     eNmType = REL_NAME;
     576             : }
     577             : 
     578           0 : String SwTableFormula::ScanString( FnScanFormel fnFormel, const SwTable& rTbl,
     579             :                                     void* pPara ) const
     580             : {
     581           0 :     String aStr;
     582           0 :     sal_uInt16 nFml = 0, nStt = 0, nEnd = 0, nTrenner;
     583             : 
     584             :     do {
     585             :         // If the formula is preceded by a name, use this table!
     586           0 :         const SwTable* pTbl = &rTbl;
     587             : 
     588           0 :         nStt = sFormel.Search( '<', nFml );
     589           0 :         if( STRING_NOTFOUND != nStt )
     590             :         {
     591           0 :             while( STRING_NOTFOUND != nStt &&
     592           0 :                 ( ' ' == sFormel.GetChar( nStt + 1 ) ||
     593           0 :                   '=' == sFormel.GetChar( nStt + 1 ) ) )
     594           0 :                 nStt = sFormel.Search( '<', nStt + 1 );
     595             : 
     596           0 :             if( STRING_NOTFOUND != nStt )
     597           0 :                 nEnd = sFormel.Search( '>', nStt+1 );
     598             :         }
     599           0 :         if( STRING_NOTFOUND == nStt || STRING_NOTFOUND == nEnd )
     600             :         {
     601             :             // set the rest and finish
     602           0 :             aStr.Insert( sFormel, nFml, sFormel.Len() - nFml );
     603           0 :             break;
     604             :         }
     605           0 :         aStr.Insert( sFormel, nFml, nStt - nFml );  // write beginning
     606             : 
     607           0 :         if( fnFormel != 0 )
     608             :         {
     609             :             // Is a table name preceded?
     610             :             // JP 16.02.99: SplitMergeBoxNm take care of the name themself
     611             :             // JP 22.02.99: Linux compiler needs cast
     612             :             // JP 28.06.99: rel. BoxName has no preceding tablename!
     613           0 :             if( fnFormel != (FnScanFormel)&SwTableFormula::_SplitMergeBoxNm &&
     614           0 :                 1 < sFormel.Len() && cRelKennung != sFormel.GetChar( 1 ) &&
     615           0 :                 STRING_NOTFOUND != ( nTrenner = sFormel.Search( '.', nStt ))
     616           0 :                 && nTrenner < nEnd )
     617             :             {
     618           0 :                 String sTblNm( sFormel.Copy( nStt, nEnd - nStt ));
     619             : 
     620             :                 // If there are dots in the name, than these appear in pairs (e.g. A1.1.1)!
     621           0 :                 if( (comphelper::string::getTokenCount(sTblNm, '.') - 1) & 1 )
     622             :                 {
     623           0 :                     sTblNm.Erase( nTrenner - nStt );
     624             : 
     625             :                     // when creating a formula the table name is unwanted
     626           0 :                     if( fnFormel != (FnScanFormel)&SwTableFormula::_MakeFormula )
     627           0 :                         aStr += sTblNm;
     628           0 :                     nStt = nTrenner;
     629             : 
     630           0 :                     sTblNm.Erase( 0, 1 );   // delete separator
     631           0 :                     if( sTblNm != rTbl.GetFrmFmt()->GetName() )
     632             :                     {
     633             :                         // then search for table
     634             :                         const SwTable* pFnd = FindTable(
     635           0 :                                                 *rTbl.GetFrmFmt()->GetDoc(),
     636           0 :                                                 sTblNm );
     637           0 :                         if( pFnd )
     638           0 :                             pTbl = pFnd;
     639             :                         // ??
     640             :                         OSL_ENSURE( pFnd, "No table found. What now?" );
     641             :                     }
     642           0 :                 }
     643             :             }
     644             : 
     645           0 :             String sBox( sFormel.Copy( nStt, nEnd - nStt + 1 ));
     646             :             // area in these parentheses?
     647           0 :             if( STRING_NOTFOUND != ( nTrenner = sFormel.Search( ':', nStt ))
     648           0 :                 && nTrenner < nEnd )
     649             :             {
     650             :                 // without opening parenthesis
     651           0 :                 String aFirstBox( sFormel.Copy( nStt+1, nTrenner - nStt - 1 ));
     652           0 :                 (this->*fnFormel)( *pTbl, aStr, sBox, &aFirstBox, pPara );
     653             :             }
     654             :             else
     655           0 :                 (this->*fnFormel)( *pTbl, aStr, sBox, 0, pPara );
     656             :         }
     657             : 
     658           0 :         nFml = nEnd+1;
     659             :     } while( true );
     660           0 :     return aStr;
     661             : }
     662             : 
     663           0 : const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const String& rNm ) const
     664             : {
     665           0 :     const SwFrmFmts& rTblFmts = *rDoc.GetTblFrmFmts();
     666           0 :     const SwTable* pTmpTbl, *pRet = 0;
     667           0 :     for( sal_uInt16 nFmtCnt = rTblFmts.size(); nFmtCnt; )
     668             :     {
     669           0 :         SwFrmFmt* pFmt = rTblFmts[ --nFmtCnt ];
     670             :         // if we are called from Sw3Writer, a number is dependent on the format name
     671             :         SwTableBox* pFBox;
     672           0 :         if( COMPARE_EQUAL == rNm.CompareTo( pFmt->GetName(),
     673           0 :                                         pFmt->GetName().Search( 0x0a ) ) &&
     674           0 :             0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
     675           0 :             0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
     676           0 :             pFBox->GetSttNd() &&
     677           0 :             pFBox->GetSttNd()->GetNodes().IsDocNodes() )
     678             :         {
     679             :             // a table in the normal NodesArr
     680           0 :             pRet = pTmpTbl;
     681           0 :             break;
     682             :         }
     683             :     }
     684           0 :     return pRet;
     685             : }
     686             : 
     687           0 : static const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox )
     688             : {
     689           0 :     SwNodeIndex aIdx( *rBox.GetSttNd() );
     690           0 :     SwCntntNode* pCNd = aIdx.GetNodes().GoNext( &aIdx );
     691             :     OSL_ENSURE( pCNd, "Box has no TextNode" );
     692           0 :     Point aPt;      // get the first frame of the layout - table headline
     693           0 :     return pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, NULL, sal_False );
     694             : }
     695             : 
     696           0 : static long lcl_GetLongBoxNum( String& rStr )
     697             : {
     698             :     sal_uInt16 nPos;
     699             :     long nRet;
     700           0 :     if( STRING_NOTFOUND == ( nPos = rStr.Search( cRelTrenner ) ))
     701             :     {
     702           0 :         nRet = rStr.ToInt32();
     703           0 :         rStr.Erase();
     704             :     }
     705             :     else
     706             :     {
     707           0 :         nRet = rStr.Copy( 0, nPos ).ToInt32();
     708           0 :         rStr.Erase( 0, nPos+1 );
     709             :     }
     710           0 :     return nRet;
     711             : }
     712             : 
     713           0 : static const SwTableBox* lcl_RelToBox( const SwTable& rTbl,
     714             :                                     const SwTableBox* pRefBox,
     715             :                                     const String& rGetName )
     716             : {
     717             :     // get line
     718           0 :     const SwTableBox* pBox = 0;
     719           0 :     String sGetName( rGetName );
     720             : 
     721             :     // Is it really a relative value?
     722           0 :     if( cRelKennung == sGetName.GetChar(0) ) // yes
     723             :     {
     724           0 :         if( !pRefBox )
     725           0 :             return 0;
     726             : 
     727           0 :         sGetName.Erase( 0, 1 );
     728             : 
     729           0 :         const SwTableLines* pLines = (SwTableLines*)&rTbl.GetTabLines();
     730             :         const SwTableBoxes* pBoxes;
     731             :         const SwTableLine* pLine;
     732             : 
     733             :         // determine starting values of the box,...
     734           0 :         pBox = (SwTableBox*)pRefBox;
     735           0 :         pLine = pBox->GetUpper();
     736           0 :         while( pLine->GetUpper() )
     737             :         {
     738           0 :             pBox = pLine->GetUpper();
     739           0 :             pLine = pBox->GetUpper();
     740             :         }
     741           0 :         sal_uInt16 nSttBox = pLine->GetTabBoxes().GetPos( pBox );
     742           0 :         sal_uInt16 nSttLine = rTbl.GetTabLines().GetPos( pLine );
     743             : 
     744           0 :         long nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox;
     745           0 :         long nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine;
     746             : 
     747           0 :         if( nBoxOffset < 0 || nBoxOffset >= USHRT_MAX ||
     748           0 :             nLineOffset < 0 || nLineOffset >= USHRT_MAX )
     749           0 :             return 0;
     750             : 
     751           0 :         if( nLineOffset >= long(pLines->size()) )
     752           0 :             return 0;
     753             : 
     754           0 :         pLine = (*pLines)[ sal_uInt16(nLineOffset) ];
     755             : 
     756             :         // ... then serach the box
     757           0 :         pBoxes = &pLine->GetTabBoxes();
     758           0 :         if( nBoxOffset >= long(pBoxes->size()) )
     759           0 :             return 0;
     760           0 :         pBox = (*pBoxes)[ sal_uInt16(nBoxOffset) ];
     761             : 
     762           0 :         while( sGetName.Len() )
     763             :         {
     764           0 :             nSttBox = SwTable::_GetBoxNum( sGetName );
     765           0 :             pLines = &pBox->GetTabLines();
     766           0 :             if( nSttBox )
     767           0 :                 --nSttBox;
     768             : 
     769           0 :             nSttLine = SwTable::_GetBoxNum( sGetName );
     770             : 
     771             :             // determine line
     772           0 :             if( !nSttLine || nSttLine > pLines->size() )
     773           0 :                 break;
     774           0 :             pLine = (*pLines)[ nSttLine-1 ];
     775             : 
     776             :             // determine box
     777           0 :             pBoxes = &pLine->GetTabBoxes();
     778           0 :             if( nSttBox >= pBoxes->size() )
     779           0 :                 break;
     780           0 :             pBox = (*pBoxes)[ nSttBox ];
     781             :         }
     782             : 
     783           0 :         if( pBox )
     784             :         {
     785           0 :             if( !pBox->GetSttNd() )
     786             :                 // "bubble up" to first box
     787           0 :                 while( !pBox->GetTabLines().empty() )
     788           0 :                     pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
     789             :         }
     790             :     }
     791             :     else
     792             :     {
     793             :         // otherwise it is an absolute external presentation
     794           0 :         pBox = rTbl.GetTblBox( sGetName );
     795             :     }
     796           0 :     return pBox;
     797             : }
     798             : 
     799           0 : static String lcl_BoxNmToRel( const SwTable& rTbl, const SwTableNode& rTblNd,
     800             :                             const String& rRefBoxNm, const String& rGetStr,
     801             :                             bool bExtrnlNm )
     802             : {
     803           0 :     String sCpy( rRefBoxNm );
     804           0 :     String sTmp( rGetStr );
     805           0 :     if( !bExtrnlNm )
     806             :     {
     807             :         // convert into external presentation
     808           0 :         SwTableBox* pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(sTmp.ToInt64()));
     809           0 :         if( rTbl.GetTabSortBoxes().find( pBox ) == rTbl.GetTabSortBoxes().end() )
     810           0 :             return OUString('?');
     811           0 :         sTmp = pBox->GetName();
     812             :     }
     813             : 
     814             :     // If the formula is spanning over a table then keep external presentation
     815           0 :     if( &rTbl == &rTblNd.GetTable() )
     816             :     {
     817           0 :         long nBox = SwTable::_GetBoxNum( sTmp, sal_True );
     818           0 :         nBox -= SwTable::_GetBoxNum( sCpy, sal_True );
     819           0 :         long nLine = SwTable::_GetBoxNum( sTmp );
     820           0 :         nLine -= SwTable::_GetBoxNum( sCpy );
     821             : 
     822           0 :         sCpy = sTmp;        //JP 01.11.95: add rest from box name
     823             : 
     824           0 :         sTmp = cRelKennung;
     825           0 :         sTmp += OUString::number( nBox );
     826           0 :         sTmp += cRelTrenner;
     827           0 :         sTmp += OUString::number( nLine );
     828             : 
     829           0 :         if( sCpy.Len() )
     830             :         {
     831           0 :             sTmp += cRelTrenner;
     832           0 :             sTmp += sCpy;
     833             :         }
     834             :     }
     835             : 
     836           0 :     if( sTmp.Len() && '>' == sTmp.GetChar( sTmp.Len() - 1 ))
     837           0 :         sTmp.Erase( sTmp.Len()-1 );
     838             : 
     839           0 :     return sTmp;
     840             : }
     841             : 
     842           0 : void SwTableFormula::GetBoxesOfFormula( const SwTable& rTbl,
     843             :                                         SwSelBoxes& rBoxes )
     844             : {
     845           0 :     rBoxes.clear();
     846             : 
     847           0 :     BoxNmToPtr( &rTbl );
     848           0 :     ScanString( &SwTableFormula::_GetFmlBoxes, rTbl, &rBoxes );
     849           0 : }
     850             : 
     851           0 : void SwTableFormula::_GetFmlBoxes( const SwTable& rTbl, String& ,
     852             :                     String& rFirstBox, String* pLastBox, void* pPara ) const
     853             : {
     854           0 :     SwSelBoxes* pBoxes = (SwSelBoxes*)pPara;
     855           0 :     SwTableBox* pSttBox, *pEndBox = 0;
     856             : 
     857           0 :     rFirstBox.Erase(0,1); // delete box label
     858             :     // area in these parentheses?
     859           0 :     if( pLastBox )
     860             :     {
     861           0 :         pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
     862             : 
     863             :         // Is it actually a valid pointer?
     864           0 :         if( rTbl.GetTabSortBoxes().find( pEndBox ) == rTbl.GetTabSortBoxes().end() )
     865           0 :             pEndBox = 0;
     866           0 :         rFirstBox.Erase( 0, pLastBox->Len()+1 );
     867             :     }
     868             : 
     869           0 :     pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
     870             :     // Is it actually a valid pointer?
     871           0 :     if( rTbl.GetTabSortBoxes().find( pSttBox ) == rTbl.GetTabSortBoxes().end() )
     872           0 :         pSttBox = 0;
     873             : 
     874           0 :     if( pEndBox && pSttBox ) // area?
     875             :     {
     876             :         // get all selected boxes via layout and calculate their values
     877           0 :         SwSelBoxes aBoxes;
     878           0 :         GetBoxes( *pSttBox, *pEndBox, aBoxes );
     879           0 :         pBoxes->insert( aBoxes );
     880             :     }
     881           0 :     else if( pSttBox )          // only the StartBox?
     882           0 :         pBoxes->insert( pSttBox );
     883           0 : }
     884             : 
     885           0 : void SwTableFormula::GetBoxes( const SwTableBox& rSttBox,
     886             :                                 const SwTableBox& rEndBox,
     887             :                                 SwSelBoxes& rBoxes ) const
     888             : {
     889             :     // get all selected boxes via layout
     890             :     const SwLayoutFrm *pStt, *pEnd;
     891           0 :     const SwFrm* pFrm = lcl_GetBoxFrm( rSttBox );
     892           0 :     pStt = pFrm ? pFrm->GetUpper() : 0;
     893           0 :     pEnd = ( 0 != (pFrm = lcl_GetBoxFrm( rEndBox ))) ? pFrm->GetUpper() : 0;
     894           0 :     if( !pStt || !pEnd )
     895           0 :         return ;                        // no valid selection
     896             : 
     897           0 :     GetTblSel( pStt, pEnd, rBoxes, 0 );
     898             : 
     899           0 :     const SwTable* pTbl = pStt->FindTabFrm()->GetTable();
     900             : 
     901             :     // filter headline boxes
     902           0 :     if( pTbl->GetRowsToRepeat() > 0 )
     903             :     {
     904             :         do {    // middle-check loop
     905           0 :             const SwTableLine* pLine = rSttBox.GetUpper();
     906           0 :             while( pLine->GetUpper() )
     907           0 :                 pLine = pLine->GetUpper()->GetUpper();
     908             : 
     909           0 :             if( pTbl->IsHeadline( *pLine ) )
     910           0 :                 break;      // headline in this area!
     911             : 
     912             :             // maybe start and end are swapped
     913           0 :             pLine = rEndBox.GetUpper();
     914           0 :             while ( pLine->GetUpper() )
     915           0 :                 pLine = pLine->GetUpper()->GetUpper();
     916             : 
     917           0 :             if( pTbl->IsHeadline( *pLine ) )
     918           0 :                 break;      // headline in this area!
     919             : 
     920           0 :             const SwTabFrm *pTable = pStt->FindTabFrm();
     921           0 :             const SwTabFrm *pEndTable = pEnd->FindTabFrm();
     922             : 
     923           0 :             if( pTable == pEndTable ) // no split table
     924           0 :                 break;
     925             : 
     926             :             // then remove table headers
     927           0 :             for (size_t n = 0; n < rBoxes.size(); ++n)
     928             :             {
     929           0 :                 pLine = rBoxes[n]->GetUpper();
     930           0 :                 while( pLine->GetUpper() )
     931           0 :                     pLine = pLine->GetUpper()->GetUpper();
     932             : 
     933           0 :                 if( pTbl->IsHeadline( *pLine ) )
     934           0 :                     rBoxes.erase( rBoxes.begin() + n-- );
     935             :             }
     936             :         } while( false );
     937             :     }
     938             : }
     939             : 
     940             : /// Are all boxes valid that are referenced by the formula?
     941           0 : void SwTableFormula::_HasValidBoxes( const SwTable& rTbl, String& ,
     942             :                     String& rFirstBox, String* pLastBox, void* pPara ) const
     943             : {
     944           0 :     bool* pBValid = (bool*)pPara;
     945           0 :     if( *pBValid )      // wrong is wrong
     946             :     {
     947           0 :         SwTableBox* pSttBox = 0, *pEndBox = 0;
     948           0 :         rFirstBox.Erase(0,1);       // Kennung fuer Box loeschen
     949             : 
     950             :         // area in this parenthesis?
     951           0 :         if( pLastBox )
     952           0 :             rFirstBox.Erase( 0, pLastBox->Len()+1 );
     953             : 
     954           0 :         switch( eNmType)
     955             :         {
     956             :         case INTRNL_NAME:
     957           0 :             if( pLastBox )
     958           0 :                 pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
     959           0 :             pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
     960           0 :             break;
     961             : 
     962             :         case REL_NAME:
     963             :             {
     964           0 :                 const SwNode* pNd = GetNodeOfFormula();
     965             :                 const SwTableBox* pBox = !pNd ? 0
     966             :                                                : (SwTableBox *)rTbl.GetTblBox(
     967           0 :                                     pNd->FindTableBoxStartNode()->GetIndex() );
     968           0 :                 if( pLastBox )
     969           0 :                     pEndBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, *pLastBox );
     970           0 :                 pSttBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, rFirstBox );
     971             :             }
     972           0 :             break;
     973             : 
     974             :         case EXTRNL_NAME:
     975           0 :             if( pLastBox )
     976           0 :                 pEndBox = (SwTableBox*)rTbl.GetTblBox( *pLastBox );
     977           0 :             pSttBox = (SwTableBox*)rTbl.GetTblBox( rFirstBox );
     978           0 :             break;
     979             :         }
     980             : 
     981             :         // Are these valid pointers?
     982           0 :         if( ( pLastBox &&
     983           0 :               ( !pEndBox || rTbl.GetTabSortBoxes().find( pEndBox ) == rTbl.GetTabSortBoxes().end() ) ) ||
     984           0 :             ( !pSttBox || rTbl.GetTabSortBoxes().find( pSttBox ) == rTbl.GetTabSortBoxes().end() ) )
     985           0 :                 *pBValid = false;
     986             :     }
     987           0 : }
     988             : 
     989           0 : bool SwTableFormula::HasValidBoxes() const
     990             : {
     991           0 :     bool bRet = true;
     992           0 :     const SwNode* pNd = GetNodeOfFormula();
     993           0 :     if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
     994             :         ScanString( &SwTableFormula::_HasValidBoxes,
     995           0 :                         ((SwTableNode*)pNd)->GetTable(), &bRet );
     996           0 :     return bRet;
     997             : }
     998             : 
     999           0 : sal_uInt16 SwTableFormula::GetLnPosInTbl( const SwTable& rTbl, const SwTableBox* pBox )
    1000             : {
    1001           0 :     sal_uInt16 nRet = USHRT_MAX;
    1002           0 :     if( pBox )
    1003             :     {
    1004           0 :         const SwTableLine* pLn = pBox->GetUpper();
    1005           0 :         while( pLn->GetUpper() )
    1006           0 :             pLn = pLn->GetUpper()->GetUpper();
    1007           0 :         nRet = rTbl.GetTabLines().GetPos( pLn );
    1008             :     }
    1009           0 :     return nRet;
    1010             : }
    1011             : 
    1012           0 : void SwTableFormula::_SplitMergeBoxNm( const SwTable& rTbl, String& rNewStr,
    1013             :                     String& rFirstBox, String* pLastBox, void* pPara ) const
    1014             : {
    1015           0 :     SwTableFmlUpdate& rTblUpd = *(SwTableFmlUpdate*)pPara;
    1016             : 
    1017           0 :     rNewStr += rFirstBox.Copy(0,1);     // get label for the box
    1018           0 :     rFirstBox.Erase(0,1);
    1019             : 
    1020           0 :     String sTblNm;
    1021           0 :     const SwTable* pTbl = &rTbl;
    1022             : 
    1023           0 :     String* pTblNmBox = pLastBox ? pLastBox : &rFirstBox;
    1024             : 
    1025           0 :     sal_uInt16 nLastBoxLen = pTblNmBox->Len();
    1026           0 :     sal_uInt16 nTrenner = pTblNmBox->Search( '.' );
    1027           0 :     if( STRING_NOTFOUND != nTrenner &&
    1028             :         // If there are dots in the name, than these appear in pairs (e.g. A1.1.1)!
    1029           0 :         (comphelper::string::getTokenCount(*pTblNmBox, '.') - 1) & 1 )
    1030             :     {
    1031           0 :         sTblNm = pTblNmBox->Copy( 0, nTrenner );
    1032           0 :         pTblNmBox->Erase( 0, nTrenner + 1); // remove dot
    1033           0 :         const SwTable* pFnd = FindTable( *rTbl.GetFrmFmt()->GetDoc(), sTblNm );
    1034           0 :         if( pFnd )
    1035           0 :             pTbl = pFnd;
    1036             : 
    1037           0 :         if( TBL_MERGETBL == rTblUpd.eFlags )
    1038             :         {
    1039           0 :             if( pFnd )
    1040             :             {
    1041           0 :                 if( pFnd == rTblUpd.DATA.pDelTbl )
    1042             :                 {
    1043           0 :                     if( rTblUpd.pTbl != &rTbl ) // not the current one
    1044           0 :                         (rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() )
    1045           0 :                             += '.'; // set new table name
    1046           0 :                     rTblUpd.bModified = sal_True;
    1047             :                 }
    1048           0 :                 else if( pFnd != rTblUpd.pTbl ||
    1049           0 :                     ( rTblUpd.pTbl != &rTbl && &rTbl != rTblUpd.DATA.pDelTbl))
    1050           0 :                     (rNewStr += sTblNm ) += '.'; // keep table name
    1051             :                 else
    1052           0 :                     rTblUpd.bModified = sal_True;
    1053             :             }
    1054             :             else
    1055           0 :                 (rNewStr += sTblNm ) += '.';     // keep table name
    1056             :         }
    1057             :     }
    1058           0 :     if( pTblNmBox == pLastBox )
    1059           0 :         rFirstBox.Erase( 0, nLastBoxLen + 1 );
    1060             : 
    1061           0 :     SwTableBox* pSttBox = 0, *pEndBox = 0;
    1062           0 :     switch( eNmType )
    1063             :     {
    1064             :     case INTRNL_NAME:
    1065           0 :         if( pLastBox )
    1066           0 :             pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
    1067           0 :         pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
    1068           0 :         break;
    1069             : 
    1070             :     case REL_NAME:
    1071             :         {
    1072           0 :             const SwNode* pNd = GetNodeOfFormula();
    1073             :             const SwTableBox* pBox = pNd ? pTbl->GetTblBox(
    1074           0 :                             pNd->FindTableBoxStartNode()->GetIndex() ) : 0;
    1075           0 :             if( pLastBox )
    1076           0 :                 pEndBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, *pLastBox );
    1077           0 :             pSttBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, rFirstBox );
    1078             :         }
    1079           0 :         break;
    1080             : 
    1081             :     case EXTRNL_NAME:
    1082           0 :         if( pLastBox )
    1083           0 :             pEndBox = (SwTableBox*)pTbl->GetTblBox( *pLastBox );
    1084           0 :         pSttBox = (SwTableBox*)pTbl->GetTblBox( rFirstBox );
    1085           0 :         break;
    1086             :     }
    1087             : 
    1088           0 :     if( pLastBox && pTbl->GetTabSortBoxes().find( pEndBox ) == pTbl->GetTabSortBoxes().end() )
    1089           0 :         pEndBox = 0;
    1090           0 :     if( pTbl->GetTabSortBoxes().find( pSttBox ) == pTbl->GetTabSortBoxes().end() )
    1091           0 :         pSttBox = 0;
    1092             : 
    1093           0 :     if( TBL_SPLITTBL == rTblUpd.eFlags )
    1094             :     {
    1095             :         // Where are the boxes - in the old or in the new table?
    1096           0 :         bool bInNewTbl = false;
    1097           0 :         if( pLastBox )
    1098             :         {
    1099             :             // It is the "first" box in this selection. It determines if the formula is placed in
    1100             :             // the new or the old table.
    1101           0 :             sal_uInt16 nEndLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pEndBox ),
    1102           0 :                     nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );
    1103             : 
    1104           0 :             if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos &&
    1105           0 :                 ((rTblUpd.nSplitLine <= nSttLnPos) ==
    1106             :                 (rTblUpd.nSplitLine <= nEndLnPos)) )
    1107             :             {
    1108             :                 // stay in same table
    1109           0 :                 bInNewTbl = rTblUpd.nSplitLine <= nEndLnPos &&
    1110           0 :                                     pTbl == rTblUpd.pTbl;
    1111             :             }
    1112             :             else
    1113             :             {
    1114             :                 // this is definitely an invalid formula, also mark as modified for Undo
    1115           0 :                 rTblUpd.bModified = sal_True;
    1116           0 :                 if( pEndBox )
    1117           0 :                     bInNewTbl = USHRT_MAX != nEndLnPos &&
    1118           0 :                                     rTblUpd.nSplitLine <= nEndLnPos &&
    1119           0 :                                     pTbl == rTblUpd.pTbl;
    1120             :             }
    1121             :         }
    1122             :         else
    1123             :         {
    1124           0 :             sal_uInt16 nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );
    1125             :             // Put it in the new table?
    1126           0 :             bInNewTbl = USHRT_MAX != nSttLnPos &&
    1127           0 :                             rTblUpd.nSplitLine <= nSttLnPos &&
    1128           0 :                             pTbl == rTblUpd.pTbl;
    1129             :         }
    1130             : 
    1131             :         // formula goes into new table
    1132           0 :         if( rTblUpd.bBehindSplitLine )
    1133             :         {
    1134           0 :             if( !bInNewTbl )
    1135             :             {
    1136           0 :                 rTblUpd.bModified = sal_True;
    1137           0 :                 ( rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) += '.';
    1138             :             }
    1139           0 :             else if( sTblNm.Len() )
    1140           0 :                 ( rNewStr += sTblNm ) += '.';
    1141             :         }
    1142           0 :         else if( bInNewTbl )
    1143             :         {
    1144           0 :             rTblUpd.bModified = sal_True;
    1145           0 :             ( rNewStr += *rTblUpd.DATA.pNewTblNm ) += '.';
    1146             :         }
    1147           0 :         else if( sTblNm.Len() )
    1148           0 :             ( rNewStr += sTblNm ) += '.';
    1149             :     }
    1150             : 
    1151           0 :     if( pLastBox )
    1152           0 :         ( rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pEndBox)) ) += ':';
    1153           0 :     ( rNewStr += OUString::valueOf(static_cast<sal_Int64>((sal_PtrDiff)pSttBox)) )
    1154           0 :               += rFirstBox.GetChar( rFirstBox.Len() - 1 );
    1155           0 : }
    1156             : 
    1157             : /// Create external formula but remember that the formula is placed in a split/merged table
    1158           0 : void SwTableFormula::ToSplitMergeBoxNm( SwTableFmlUpdate& rTblUpd )
    1159             : {
    1160             :     const SwTable* pTbl;
    1161           0 :     const SwNode* pNd = GetNodeOfFormula();
    1162           0 :     if( pNd && 0 != ( pNd = pNd->FindTableNode() ))
    1163           0 :         pTbl = &((SwTableNode*)pNd)->GetTable();
    1164             :     else
    1165           0 :         pTbl = rTblUpd.pTbl;
    1166             : 
    1167           0 :     sFormel = ScanString( &SwTableFormula::_SplitMergeBoxNm, *pTbl, (void*)&rTblUpd );
    1168           0 :     eNmType = INTRNL_NAME;
    1169          99 : }
    1170             : 
    1171             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10