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

Generated by: LCOV version 1.10