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