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

Generated by: LCOV version 1.10