xref: /trunk/main/sw/source/core/table/swtable.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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 #include <ctype.h>
28cdf0e10cSrcweir #include <float.h>
29cdf0e10cSrcweir #include <hintids.hxx>
30cdf0e10cSrcweir #include <hints.hxx>    // fuer SwAttrSetChg
31cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
32cdf0e10cSrcweir #include <editeng/shaditem.hxx>
33cdf0e10cSrcweir #include <editeng/adjitem.hxx>
34cdf0e10cSrcweir #include <editeng/colritem.hxx>
35cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
36cdf0e10cSrcweir #include <editeng/boxitem.hxx>
37cdf0e10cSrcweir #include <fmtfsize.hxx>
38cdf0e10cSrcweir #include <fmtornt.hxx>
39cdf0e10cSrcweir #include <fmtpdsc.hxx>
40cdf0e10cSrcweir #include <fldbas.hxx>
41cdf0e10cSrcweir #include <fmtfld.hxx>
42cdf0e10cSrcweir #include <frmatr.hxx>
43cdf0e10cSrcweir #include <doc.hxx>
44cdf0e10cSrcweir #include <docary.hxx>   // fuer RedlineTbl()
45cdf0e10cSrcweir #include <frame.hxx>
46cdf0e10cSrcweir #include <swtable.hxx>
47cdf0e10cSrcweir #include <ndtxt.hxx>
48cdf0e10cSrcweir #include <tabcol.hxx>
49cdf0e10cSrcweir #include <tabfrm.hxx>
50cdf0e10cSrcweir #include <cellfrm.hxx>
51cdf0e10cSrcweir #include <rowfrm.hxx>
52cdf0e10cSrcweir #include <swserv.hxx>
53cdf0e10cSrcweir #include <expfld.hxx>
54cdf0e10cSrcweir #include <mdiexp.hxx>
55cdf0e10cSrcweir #include <cellatr.hxx>
56cdf0e10cSrcweir #include <txatbase.hxx>
57cdf0e10cSrcweir #include <htmltbl.hxx>
58cdf0e10cSrcweir #include <swtblfmt.hxx>
59cdf0e10cSrcweir #include <ndindex.hxx>
60cdf0e10cSrcweir #include <tblrwcl.hxx>
61cdf0e10cSrcweir #include <shellres.hxx>
62cdf0e10cSrcweir #include <viewsh.hxx>
63cdf0e10cSrcweir #include <redline.hxx>
64cdf0e10cSrcweir #include <list>
65cdf0e10cSrcweir #include <switerator.hxx>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #ifndef DBG_UTIL
68cdf0e10cSrcweir #define CHECK_TABLE(t)
69cdf0e10cSrcweir #else
70cdf0e10cSrcweir #ifdef DEBUG
71cdf0e10cSrcweir #define CHECK_TABLE(t) (t).CheckConsistency();
72cdf0e10cSrcweir #else
73cdf0e10cSrcweir #define CHECK_TABLE(t)
74cdf0e10cSrcweir #endif
75cdf0e10cSrcweir #endif
76cdf0e10cSrcweir 
77cdf0e10cSrcweir using namespace com::sun::star;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir TYPEINIT1( SwTable, SwClient );
80cdf0e10cSrcweir TYPEINIT1( SwTableBox, SwClient );
81cdf0e10cSrcweir TYPEINIT1( SwTableLine, SwClient );
82*28160478SArmin Le Grand 
83*28160478SArmin Le Grand //UUUU
84cdf0e10cSrcweir TYPEINIT1( SwTableFmt, SwFrmFmt );
85*28160478SArmin Le Grand 
SwTableFmt(SwAttrPool & rPool,const sal_Char * pFmtNm,SwFrmFmt * pDrvdFrm)86*28160478SArmin Le Grand SwTableFmt::SwTableFmt(SwAttrPool& rPool,const sal_Char* pFmtNm, SwFrmFmt *pDrvdFrm)
87*28160478SArmin Le Grand :   SwFrmFmt(rPool,pFmtNm,pDrvdFrm,RES_FRMFMT,aTableSetRange)
88*28160478SArmin Le Grand {
89*28160478SArmin Le Grand }
90*28160478SArmin Le Grand 
SwTableFmt(SwAttrPool & rPool,const String & rFmtNm,SwFrmFmt * pDrvdFrm)91*28160478SArmin Le Grand SwTableFmt::SwTableFmt(SwAttrPool& rPool,const String &rFmtNm, SwFrmFmt *pDrvdFrm)
92*28160478SArmin Le Grand :   SwFrmFmt(rPool,rFmtNm,pDrvdFrm,RES_FRMFMT,aTableSetRange)
93*28160478SArmin Le Grand {
94*28160478SArmin Le Grand }
95*28160478SArmin Le Grand 
~SwTableFmt()96*28160478SArmin Le Grand SwTableFmt::~SwTableFmt()
97*28160478SArmin Le Grand {
98*28160478SArmin Le Grand }
99*28160478SArmin Le Grand 
100*28160478SArmin Le Grand //UUUU Do not support for table frames - may change later if support will be added
supportsFullDrawingLayerFillAttributeSet() const101*28160478SArmin Le Grand bool SwTableFmt::supportsFullDrawingLayerFillAttributeSet() const
102*28160478SArmin Le Grand {
103*28160478SArmin Le Grand     return false;
104*28160478SArmin Le Grand }
105*28160478SArmin Le Grand 
106*28160478SArmin Le Grand //UUUU
107cdf0e10cSrcweir TYPEINIT1( SwTableBoxFmt, SwFrmFmt );
108*28160478SArmin Le Grand 
SwTableBoxFmt(SwAttrPool & rPool,const sal_Char * pFmtNm,SwFrmFmt * pDrvdFrm)109*28160478SArmin Le Grand SwTableBoxFmt::SwTableBoxFmt(SwAttrPool& rPool,const sal_Char* pFmtNm, SwFrmFmt *pDrvdFrm)
110*28160478SArmin Le Grand : SwFrmFmt(rPool,pFmtNm,pDrvdFrm,RES_FRMFMT,aTableBoxSetRange)
111*28160478SArmin Le Grand {
112*28160478SArmin Le Grand }
113*28160478SArmin Le Grand 
SwTableBoxFmt(SwAttrPool & rPool,const String & rFmtNm,SwFrmFmt * pDrvdFrm)114*28160478SArmin Le Grand SwTableBoxFmt::SwTableBoxFmt(SwAttrPool& rPool,const String &rFmtNm, SwFrmFmt *pDrvdFrm)
115*28160478SArmin Le Grand :   SwFrmFmt(rPool,rFmtNm,pDrvdFrm,RES_FRMFMT,aTableBoxSetRange)
116*28160478SArmin Le Grand {
117*28160478SArmin Le Grand }
118*28160478SArmin Le Grand 
~SwTableBoxFmt()119*28160478SArmin Le Grand SwTableBoxFmt::~SwTableBoxFmt()
120*28160478SArmin Le Grand {
121*28160478SArmin Le Grand }
122*28160478SArmin Le Grand 
123*28160478SArmin Le Grand //UUUU Do not support for table frames - may change later if support will be added
supportsFullDrawingLayerFillAttributeSet() const124*28160478SArmin Le Grand bool SwTableBoxFmt::supportsFullDrawingLayerFillAttributeSet() const
125*28160478SArmin Le Grand {
126*28160478SArmin Le Grand     return false;
127*28160478SArmin Le Grand }
128*28160478SArmin Le Grand 
129*28160478SArmin Le Grand //UUUU
130cdf0e10cSrcweir TYPEINIT1( SwTableLineFmt, SwFrmFmt );
131cdf0e10cSrcweir 
SwTableLineFmt(SwAttrPool & rPool,const sal_Char * pFmtNm,SwFrmFmt * pDrvdFrm)132*28160478SArmin Le Grand SwTableLineFmt::SwTableLineFmt(SwAttrPool& rPool,const sal_Char* pFmtNm, SwFrmFmt *pDrvdFrm)
133*28160478SArmin Le Grand :   SwFrmFmt(rPool,pFmtNm,pDrvdFrm,RES_FRMFMT,aTableLineSetRange)
134*28160478SArmin Le Grand {
135*28160478SArmin Le Grand }
136*28160478SArmin Le Grand 
SwTableLineFmt(SwAttrPool & rPool,const String & rFmtNm,SwFrmFmt * pDrvdFrm)137*28160478SArmin Le Grand SwTableLineFmt::SwTableLineFmt(SwAttrPool& rPool,const String &rFmtNm, SwFrmFmt *pDrvdFrm)
138*28160478SArmin Le Grand :   SwFrmFmt(rPool,rFmtNm,pDrvdFrm,RES_FRMFMT,aTableLineSetRange)
139*28160478SArmin Le Grand {
140*28160478SArmin Le Grand }
141*28160478SArmin Le Grand 
~SwTableLineFmt()142*28160478SArmin Le Grand SwTableLineFmt::~SwTableLineFmt()
143*28160478SArmin Le Grand {
144*28160478SArmin Le Grand }
145*28160478SArmin Le Grand 
146*28160478SArmin Le Grand //UUUU Do not support for table frames - may change later if support will be added
supportsFullDrawingLayerFillAttributeSet() const147*28160478SArmin Le Grand bool SwTableLineFmt::supportsFullDrawingLayerFillAttributeSet() const
148*28160478SArmin Le Grand {
149*28160478SArmin Le Grand     return false;
150*28160478SArmin Le Grand }
151*28160478SArmin Le Grand 
152cdf0e10cSrcweir SV_IMPL_PTRARR(SwTableLines,SwTableLine*);
153cdf0e10cSrcweir SV_IMPL_PTRARR(SwTableBoxes,SwTableBox*);
154cdf0e10cSrcweir SV_IMPL_PTRARR_SORT(SwTableSortBoxes,SwTableBoxPtr);
155cdf0e10cSrcweir 
156cdf0e10cSrcweir SV_IMPL_REF( SwServerObject )
157cdf0e10cSrcweir 
158cdf0e10cSrcweir #define COLFUZZY 20
159cdf0e10cSrcweir 
160cdf0e10cSrcweir void ChgTextToNum( SwTableBox& rBox, const String& rTxt, const Color* pCol,
161cdf0e10cSrcweir                     sal_Bool bChgAlign,sal_uLong nNdPos );
162cdf0e10cSrcweir //----------------------------------
163cdf0e10cSrcweir 
164cdf0e10cSrcweir class SwTableBox_Impl
165cdf0e10cSrcweir {
166cdf0e10cSrcweir     Color *mpUserColor, *mpNumFmtColor;
167cdf0e10cSrcweir     long mnRowSpan;
168cdf0e10cSrcweir     bool mbDummyFlag;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     void SetNewCol( Color** ppCol, const Color* pNewCol );
171cdf0e10cSrcweir public:
SwTableBox_Impl()172cdf0e10cSrcweir     SwTableBox_Impl() : mpUserColor(0), mpNumFmtColor(0), mnRowSpan(1),
173cdf0e10cSrcweir         mbDummyFlag( false ) {}
~SwTableBox_Impl()174cdf0e10cSrcweir     ~SwTableBox_Impl() { delete mpUserColor; delete mpNumFmtColor; }
175cdf0e10cSrcweir 
GetSaveUserColor() const176cdf0e10cSrcweir     const Color* GetSaveUserColor() const       { return mpUserColor; }
GetSaveNumFmtColor() const177cdf0e10cSrcweir     const Color* GetSaveNumFmtColor() const     { return mpNumFmtColor; }
SetSaveUserColor(const Color * p)178cdf0e10cSrcweir     void SetSaveUserColor(const Color* p )      { SetNewCol( &mpUserColor, p ); }
SetSaveNumFmtColor(const Color * p)179cdf0e10cSrcweir     void SetSaveNumFmtColor( const Color* p )   { SetNewCol( &mpNumFmtColor, p ); }
getRowSpan() const180cdf0e10cSrcweir     long getRowSpan() const { return mnRowSpan; }
setRowSpan(long nNewRowSpan)181cdf0e10cSrcweir     void setRowSpan( long nNewRowSpan ) { mnRowSpan = nNewRowSpan; }
getDummyFlag() const182cdf0e10cSrcweir     bool getDummyFlag() const { return mbDummyFlag; }
setDummyFlag(bool bDummy)183cdf0e10cSrcweir     void setDummyFlag( bool bDummy ) { mbDummyFlag = bDummy; }
184cdf0e10cSrcweir };
185cdf0e10cSrcweir 
186cdf0e10cSrcweir // ----------- Inlines -----------------------------
187cdf0e10cSrcweir 
GetSaveUserColor() const188cdf0e10cSrcweir inline const Color* SwTableBox::GetSaveUserColor() const
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     return pImpl ? pImpl->GetSaveUserColor() : 0;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir 
GetSaveNumFmtColor() const193cdf0e10cSrcweir inline const Color* SwTableBox::GetSaveNumFmtColor() const
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     return pImpl ? pImpl->GetSaveNumFmtColor() : 0;
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
SetSaveUserColor(const Color * p)198cdf0e10cSrcweir inline void SwTableBox::SetSaveUserColor(const Color* p )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir     if( pImpl )
201cdf0e10cSrcweir         pImpl->SetSaveUserColor( p );
202cdf0e10cSrcweir     else if( p )
203cdf0e10cSrcweir         ( pImpl = new SwTableBox_Impl ) ->SetSaveUserColor( p );
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
SetSaveNumFmtColor(const Color * p)206cdf0e10cSrcweir inline void SwTableBox::SetSaveNumFmtColor( const Color* p )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     if( pImpl )
209cdf0e10cSrcweir         pImpl->SetSaveNumFmtColor( p );
210cdf0e10cSrcweir     else if( p )
211cdf0e10cSrcweir         ( pImpl = new SwTableBox_Impl )->SetSaveNumFmtColor( p );
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
getRowSpan() const214cdf0e10cSrcweir long SwTableBox::getRowSpan() const
215cdf0e10cSrcweir {
216cdf0e10cSrcweir     return pImpl ? pImpl->getRowSpan() : 1;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
setRowSpan(long nNewRowSpan)219cdf0e10cSrcweir void SwTableBox::setRowSpan( long nNewRowSpan )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     if( !pImpl )
222cdf0e10cSrcweir     {
223cdf0e10cSrcweir         if( nNewRowSpan == 1 )
224cdf0e10cSrcweir             return;
225cdf0e10cSrcweir         pImpl = new SwTableBox_Impl();
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir     pImpl->setRowSpan( nNewRowSpan );
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
getDummyFlag() const230cdf0e10cSrcweir bool SwTableBox::getDummyFlag() const
231cdf0e10cSrcweir {
232cdf0e10cSrcweir     return pImpl ? pImpl->getDummyFlag() : false;
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
setDummyFlag(bool bDummy)235cdf0e10cSrcweir void SwTableBox::setDummyFlag( bool bDummy )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     if( !pImpl )
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         if( !bDummy )
240cdf0e10cSrcweir             return;
241cdf0e10cSrcweir         pImpl = new SwTableBox_Impl();
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir     pImpl->setDummyFlag( bDummy );
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir //JP 15.09.98: Bug 55741 - Tabs beibehalten (vorne und hinten)
lcl_TabToBlankAtSttEnd(String & rTxt)247cdf0e10cSrcweir String& lcl_TabToBlankAtSttEnd( String& rTxt )
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     sal_Unicode c;
250cdf0e10cSrcweir     xub_StrLen n;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     for( n = 0; n < rTxt.Len() && ' ' >= ( c = rTxt.GetChar( n )); ++n )
253cdf0e10cSrcweir         if( '\x9' == c )
254cdf0e10cSrcweir             rTxt.SetChar( n, ' ' );
255cdf0e10cSrcweir     for( n = rTxt.Len(); n && ' ' >= ( c = rTxt.GetChar( --n )); )
256cdf0e10cSrcweir         if( '\x9' == c )
257cdf0e10cSrcweir             rTxt.SetChar( n, ' ' );
258cdf0e10cSrcweir     return rTxt;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
lcl_DelTabsAtSttEnd(String & rTxt)261cdf0e10cSrcweir String& lcl_DelTabsAtSttEnd( String& rTxt )
262cdf0e10cSrcweir {
263cdf0e10cSrcweir     sal_Unicode c;
264cdf0e10cSrcweir     xub_StrLen n;
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     for( n = 0; n < rTxt.Len() && ' ' >= ( c = rTxt.GetChar( n )); ++n )
267cdf0e10cSrcweir         if( '\x9' == c )
268cdf0e10cSrcweir             rTxt.Erase( n--, 1 );
269cdf0e10cSrcweir     for( n = rTxt.Len(); n && ' ' >= ( c = rTxt.GetChar( --n )); )
270cdf0e10cSrcweir         if( '\x9' == c )
271cdf0e10cSrcweir             rTxt.Erase( n, 1 );
272cdf0e10cSrcweir     return rTxt;
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
_InsTblBox(SwDoc * pDoc,SwTableNode * pTblNd,SwTableLine * pLine,SwTableBoxFmt * pBoxFrmFmt,SwTableBox * pBox,sal_uInt16 nInsPos,sal_uInt16 nCnt)275cdf0e10cSrcweir void _InsTblBox( SwDoc* pDoc, SwTableNode* pTblNd,
276cdf0e10cSrcweir                         SwTableLine* pLine, SwTableBoxFmt* pBoxFrmFmt,
277cdf0e10cSrcweir                         SwTableBox* pBox,
278cdf0e10cSrcweir                         sal_uInt16 nInsPos, sal_uInt16 nCnt )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     ASSERT( pBox->GetSttNd(), "Box ohne Start-Node" );
281cdf0e10cSrcweir     SwNodeIndex aIdx( *pBox->GetSttNd(), +1 );
282cdf0e10cSrcweir     SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
283cdf0e10cSrcweir     if( !pCNd )
284cdf0e10cSrcweir         pCNd = pDoc->GetNodes().GoNext( &aIdx );
285cdf0e10cSrcweir     ASSERT( pCNd, "Box ohne ContentNode" );
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     if( pCNd->IsTxtNode() )
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         if( pBox->GetSaveNumFmtColor() && pCNd->GetpSwAttrSet() )
290cdf0e10cSrcweir         {
291cdf0e10cSrcweir             SwAttrSet aAttrSet( *pCNd->GetpSwAttrSet() );
292cdf0e10cSrcweir             if( pBox->GetSaveUserColor() )
293cdf0e10cSrcweir                 aAttrSet.Put( SvxColorItem( *pBox->GetSaveUserColor(), RES_CHRATR_COLOR ));
294cdf0e10cSrcweir             else
295cdf0e10cSrcweir                 aAttrSet.ClearItem( RES_CHRATR_COLOR );
296cdf0e10cSrcweir             pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
297cdf0e10cSrcweir                                     ((SwTxtNode*)pCNd)->GetTxtColl(),
298cdf0e10cSrcweir                                     &aAttrSet, nInsPos, nCnt );
299cdf0e10cSrcweir         }
300cdf0e10cSrcweir         else
301cdf0e10cSrcweir             pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
302cdf0e10cSrcweir                                     ((SwTxtNode*)pCNd)->GetTxtColl(),
303cdf0e10cSrcweir                                     pCNd->GetpSwAttrSet(),
304cdf0e10cSrcweir                                     nInsPos, nCnt );
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir     else
307cdf0e10cSrcweir         pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
308cdf0e10cSrcweir                 (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
309cdf0e10cSrcweir                 nInsPos, nCnt );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     long nRowSpan = pBox->getRowSpan();
312cdf0e10cSrcweir     if( nRowSpan != 1 )
313cdf0e10cSrcweir     {
314cdf0e10cSrcweir         SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
315cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < nCnt; ++i )
316cdf0e10cSrcweir         {
317cdf0e10cSrcweir             pBox = rTblBoxes[ i + nInsPos ];
318cdf0e10cSrcweir             pBox->setRowSpan( nRowSpan );
319cdf0e10cSrcweir         }
320cdf0e10cSrcweir     }
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir /*************************************************************************
324cdf0e10cSrcweir |*
325cdf0e10cSrcweir |*  SwTable::SwTable()
326cdf0e10cSrcweir |*
327cdf0e10cSrcweir |*************************************************************************/
SwTable(SwTableFmt * pFmt)328cdf0e10cSrcweir SwTable::SwTable( SwTableFmt* pFmt )
329cdf0e10cSrcweir     : SwClient( pFmt ),
330cdf0e10cSrcweir     pHTMLLayout( 0 ),
331cdf0e10cSrcweir     pTableNode( 0 ),
332cdf0e10cSrcweir     nGrfsThatResize( 0 ),
333cdf0e10cSrcweir     nRowsToRepeat( 1 ),
334cdf0e10cSrcweir     bModifyLocked( sal_False ),
335cdf0e10cSrcweir     bNewModel( sal_True )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir     // default Wert aus den Optionen setzen
338cdf0e10cSrcweir     eTblChgMode = (TblChgMode)GetTblChgDefaultMode();
339cdf0e10cSrcweir }
340cdf0e10cSrcweir 
SwTable(const SwTable & rTable)341cdf0e10cSrcweir SwTable::SwTable( const SwTable& rTable )
342cdf0e10cSrcweir     : SwClient( rTable.GetFrmFmt() ),
343cdf0e10cSrcweir     pHTMLLayout( 0 ),
344cdf0e10cSrcweir     pTableNode( 0 ),
345cdf0e10cSrcweir     eTblChgMode( rTable.eTblChgMode ),
346cdf0e10cSrcweir     nGrfsThatResize( 0 ),
347cdf0e10cSrcweir     nRowsToRepeat( rTable.GetRowsToRepeat() ),
348cdf0e10cSrcweir     bModifyLocked( sal_False ),
349cdf0e10cSrcweir     bNewModel( rTable.bNewModel )
350cdf0e10cSrcweir {
351cdf0e10cSrcweir }
352cdf0e10cSrcweir 
DelBoxNode(SwTableSortBoxes & rSortCntBoxes)353cdf0e10cSrcweir void DelBoxNode( SwTableSortBoxes& rSortCntBoxes )
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < rSortCntBoxes.Count(); ++n )
356cdf0e10cSrcweir         rSortCntBoxes[ n ]->pSttNd = 0;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir 
~SwTable()359cdf0e10cSrcweir SwTable::~SwTable()
360cdf0e10cSrcweir {
361cdf0e10cSrcweir     if( refObj.Is() )
362cdf0e10cSrcweir     {
363cdf0e10cSrcweir         SwDoc* pDoc = GetFrmFmt()->GetDoc();
364cdf0e10cSrcweir         if( !pDoc->IsInDtor() )         // dann aus der Liste entfernen
365cdf0e10cSrcweir             pDoc->GetLinkManager().RemoveServer( &refObj );
366cdf0e10cSrcweir 
367cdf0e10cSrcweir         refObj->Closed();
368cdf0e10cSrcweir     }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir     // ist die Tabelle der letzte Client im FrameFormat, kann dieses
371cdf0e10cSrcweir     // geloescht werden
372cdf0e10cSrcweir     SwTableFmt* pFmt = (SwTableFmt*)GetFrmFmt();
373cdf0e10cSrcweir     pFmt->Remove( this );               // austragen,
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     if( !pFmt->GetDepends() )
376cdf0e10cSrcweir         pFmt->GetDoc()->DelTblFrmFmt( pFmt );   // und loeschen
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     // Loesche die Pointer aus dem SortArray der Boxen, die
379cdf0e10cSrcweir     // Objecte bleiben erhalten und werden vom DTOR der Lines/Boxes
380cdf0e10cSrcweir     // Arrays geloescht.
381cdf0e10cSrcweir     //JP: reicht leider nicht, es muessen die Pointer auf den StartNode
382cdf0e10cSrcweir     //  der Section geloescht werden
383cdf0e10cSrcweir     DelBoxNode( aSortCntBoxes );
384cdf0e10cSrcweir     aSortCntBoxes.Remove( (sal_uInt16)0, aSortCntBoxes.Count() );
385cdf0e10cSrcweir     delete pHTMLLayout;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir /*************************************************************************
389cdf0e10cSrcweir |*
390cdf0e10cSrcweir |*  SwTable::Modify()
391cdf0e10cSrcweir |*
392cdf0e10cSrcweir |*************************************************************************/
FmtInArr(SvPtrarr & rFmtArr,SwFmt * pBoxFmt)393cdf0e10cSrcweir inline void FmtInArr( SvPtrarr& rFmtArr, SwFmt* pBoxFmt )
394cdf0e10cSrcweir {
395cdf0e10cSrcweir     sal_Bool bRet = USHRT_MAX != rFmtArr.GetPos( (VoidPtr)pBoxFmt );
396cdf0e10cSrcweir     if( !bRet )
397cdf0e10cSrcweir         rFmtArr.Insert( (VoidPtr)pBoxFmt, rFmtArr.Count() );
398cdf0e10cSrcweir }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir void lcl_ModifyBoxes( SwTableBoxes &rBoxes, const long nOld,
401cdf0e10cSrcweir                          const long nNew, SvPtrarr& rFmtArr );
402cdf0e10cSrcweir 
lcl_ModifyLines(SwTableLines & rLines,const long nOld,const long nNew,SvPtrarr & rFmtArr,const bool bCheckSum)403cdf0e10cSrcweir void lcl_ModifyLines( SwTableLines &rLines, const long nOld,
404cdf0e10cSrcweir                          const long nNew, SvPtrarr& rFmtArr, const bool bCheckSum )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
407cdf0e10cSrcweir         ::lcl_ModifyBoxes( rLines[i]->GetTabBoxes(), nOld, nNew, rFmtArr );
408cdf0e10cSrcweir     if( bCheckSum )
409cdf0e10cSrcweir     {
410cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < rFmtArr.Count(); ++i )
411cdf0e10cSrcweir         {
412cdf0e10cSrcweir             SwFmt* pFmt = (SwFmt*)rFmtArr[i];
413cdf0e10cSrcweir             sal_uInt64 nBox = pFmt->GetFrmSize().GetWidth();
414cdf0e10cSrcweir             nBox *= nNew;
415cdf0e10cSrcweir             nBox /= nOld;
416cdf0e10cSrcweir             SwFmtFrmSize aNewBox( ATT_VAR_SIZE, SwTwips(nBox), 0 );
417cdf0e10cSrcweir             pFmt->LockModify();
418cdf0e10cSrcweir             pFmt->SetFmtAttr( aNewBox );
419cdf0e10cSrcweir             pFmt->UnlockModify();
420cdf0e10cSrcweir         }
421cdf0e10cSrcweir     }
422cdf0e10cSrcweir }
423cdf0e10cSrcweir 
lcl_ModifyBoxes(SwTableBoxes & rBoxes,const long nOld,const long nNew,SvPtrarr & rFmtArr)424cdf0e10cSrcweir void lcl_ModifyBoxes( SwTableBoxes &rBoxes, const long nOld,
425cdf0e10cSrcweir                          const long nNew, SvPtrarr& rFmtArr )
426cdf0e10cSrcweir {
427cdf0e10cSrcweir     sal_uInt64 nSum = 0; // To avoid rounding errors we summarize all box widths
428cdf0e10cSrcweir     sal_uInt64 nOriginalSum = 0; // Sum of original widths
429cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir         SwTableBox &rBox = *rBoxes[i];
432cdf0e10cSrcweir         if ( rBox.GetTabLines().Count() )
433cdf0e10cSrcweir         {
434cdf0e10cSrcweir             // For SubTables the rounding problem will not be solved :-(
435cdf0e10cSrcweir             ::lcl_ModifyLines( rBox.GetTabLines(), nOld, nNew, rFmtArr, false );
436cdf0e10cSrcweir         }
437cdf0e10cSrcweir         //Die Box anpassen
438cdf0e10cSrcweir         SwFrmFmt *pFmt = rBox.GetFrmFmt();
439cdf0e10cSrcweir         sal_uInt64 nBox = pFmt->GetFrmSize().GetWidth();
440cdf0e10cSrcweir         nOriginalSum += nBox;
441cdf0e10cSrcweir         nBox *= nNew;
442cdf0e10cSrcweir         nBox /= nOld;
443cdf0e10cSrcweir         sal_uInt64 nWishedSum = nOriginalSum;
444cdf0e10cSrcweir         nWishedSum *= nNew;
445cdf0e10cSrcweir         nWishedSum /= nOld;
446cdf0e10cSrcweir         nWishedSum -= nSum;
447cdf0e10cSrcweir         if( nWishedSum > 0 )
448cdf0e10cSrcweir         {
449cdf0e10cSrcweir             if( nBox == nWishedSum )
450cdf0e10cSrcweir                 FmtInArr( rFmtArr, pFmt );
451cdf0e10cSrcweir             else
452cdf0e10cSrcweir             {
453cdf0e10cSrcweir                 nBox = nWishedSum;
454cdf0e10cSrcweir                 pFmt = rBox.ClaimFrmFmt();
455cdf0e10cSrcweir                 SwFmtFrmSize aNewBox( ATT_VAR_SIZE, static_cast< SwTwips >(nBox), 0 );
456cdf0e10cSrcweir                 pFmt->LockModify();
457cdf0e10cSrcweir                 pFmt->SetFmtAttr( aNewBox );
458cdf0e10cSrcweir                 pFmt->UnlockModify();
459cdf0e10cSrcweir             }
460cdf0e10cSrcweir         }
461cdf0e10cSrcweir         else {
462cdf0e10cSrcweir             ASSERT( false, "Rounding error" );
463cdf0e10cSrcweir         }
464cdf0e10cSrcweir         nSum += nBox;
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)468cdf0e10cSrcweir void SwTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir     // fange SSize Aenderungen ab, um die Lines/Boxen anzupassen
471cdf0e10cSrcweir     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
472cdf0e10cSrcweir     const SwFmtFrmSize* pNewSize = 0, *pOldSize = 0;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     if( RES_ATTRSET_CHG == nWhich )
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
477cdf0e10cSrcweir             RES_FRM_SIZE, sal_False, (const SfxPoolItem**)&pNewSize ))
478cdf0e10cSrcweir             pOldSize = &((SwAttrSetChg*)pOld)->GetChgSet()->GetFrmSize();
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir     else if( RES_FRM_SIZE == nWhich )
481cdf0e10cSrcweir     {
482cdf0e10cSrcweir         pOldSize = (const SwFmtFrmSize*)pOld;
483cdf0e10cSrcweir         pNewSize = (const SwFmtFrmSize*)pNew;
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir     else
486cdf0e10cSrcweir         CheckRegistration( pOld, pNew );
487cdf0e10cSrcweir 
488cdf0e10cSrcweir     if( pOldSize || pNewSize )
489cdf0e10cSrcweir     {
490cdf0e10cSrcweir         if ( !IsModifyLocked() )
491cdf0e10cSrcweir         {
492cdf0e10cSrcweir             ASSERT( pOldSize && pOldSize->Which() == RES_FRM_SIZE &&
493cdf0e10cSrcweir                     pNewSize && pNewSize->Which() == RES_FRM_SIZE,
494cdf0e10cSrcweir                     "Kein Old oder New fuer FmtFrmSize-Modify der SwTable." );
495cdf0e10cSrcweir             AdjustWidths( pOldSize->GetWidth(), pNewSize->GetWidth() );
496cdf0e10cSrcweir         }
497cdf0e10cSrcweir     }
498cdf0e10cSrcweir }
499cdf0e10cSrcweir 
AdjustWidths(const long nOld,const long nNew)500cdf0e10cSrcweir void SwTable::AdjustWidths( const long nOld, const long nNew )
501cdf0e10cSrcweir {
502cdf0e10cSrcweir     SvPtrarr aFmtArr( (sal_uInt8)aLines[0]->GetTabBoxes().Count(), 1 );
503cdf0e10cSrcweir     ::lcl_ModifyLines( aLines, nOld, nNew, aFmtArr, true );
504cdf0e10cSrcweir }
505cdf0e10cSrcweir 
506cdf0e10cSrcweir /*************************************************************************
507cdf0e10cSrcweir |*
508cdf0e10cSrcweir |*  SwTable::GetTabCols()
509cdf0e10cSrcweir |*
510cdf0e10cSrcweir |*************************************************************************/
lcl_RefreshHidden(SwTabCols & rToFill,sal_uInt16 nPos)511cdf0e10cSrcweir void lcl_RefreshHidden( SwTabCols &rToFill, sal_uInt16 nPos )
512cdf0e10cSrcweir {
513cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rToFill.Count(); ++i )
514cdf0e10cSrcweir     {
515cdf0e10cSrcweir         if ( Abs((long)(nPos - rToFill[i])) <= COLFUZZY )
516cdf0e10cSrcweir         {
517cdf0e10cSrcweir             rToFill.SetHidden( i, sal_False );
518cdf0e10cSrcweir             break;
519cdf0e10cSrcweir         }
520cdf0e10cSrcweir     }
521cdf0e10cSrcweir }
522cdf0e10cSrcweir 
lcl_SortedTabColInsert(SwTabCols & rToFill,const SwTableBox * pBox,const SwFrmFmt * pTabFmt,const sal_Bool bHidden,const FASTBOOL bRefreshHidden)523cdf0e10cSrcweir void lcl_SortedTabColInsert( SwTabCols &rToFill, const SwTableBox *pBox,
524cdf0e10cSrcweir                    const SwFrmFmt *pTabFmt, const sal_Bool bHidden,
525cdf0e10cSrcweir                    const FASTBOOL bRefreshHidden )
526cdf0e10cSrcweir {
527cdf0e10cSrcweir     const long nWish = pTabFmt->GetFrmSize().GetWidth();
528cdf0e10cSrcweir     const long nAct  = rToFill.GetRight() - rToFill.GetLeft();  // +1 why?
529cdf0e10cSrcweir 
530cdf0e10cSrcweir     //Der Wert fuer die linke Kante der Box errechnet sich aus den
531cdf0e10cSrcweir     //Breiten der vorhergehenden Boxen.
532cdf0e10cSrcweir     sal_uInt16 nPos = 0;
533cdf0e10cSrcweir     sal_uInt16 nSum = 0;
534cdf0e10cSrcweir     sal_uInt16 nLeftMin = 0;
535cdf0e10cSrcweir     sal_uInt16 nRightMax = 0;
536cdf0e10cSrcweir     const SwTableBox  *pCur  = pBox;
537cdf0e10cSrcweir     const SwTableLine *pLine = pBox->GetUpper();
538cdf0e10cSrcweir     while ( pLine )
539cdf0e10cSrcweir     {   const SwTableBoxes &rBoxes = pLine->GetTabBoxes();
540cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
541cdf0e10cSrcweir         {
542cdf0e10cSrcweir             SwTwips nWidth = rBoxes[i]->GetFrmFmt()->GetFrmSize().GetWidth();
543cdf0e10cSrcweir             nSum = (sal_uInt16)(nSum + nWidth);
544cdf0e10cSrcweir             sal_uInt64 nTmp = nSum;
545cdf0e10cSrcweir             nTmp *= nAct;
546cdf0e10cSrcweir             nTmp /= nWish;
547cdf0e10cSrcweir             if (rBoxes[i] != pCur)
548cdf0e10cSrcweir             {
549cdf0e10cSrcweir                 if ( pLine == pBox->GetUpper() || 0 == nLeftMin )
550cdf0e10cSrcweir                     nLeftMin = (sal_uInt16)(nTmp - nPos);
551cdf0e10cSrcweir                 nPos = (sal_uInt16)nTmp;
552cdf0e10cSrcweir             }
553cdf0e10cSrcweir             else
554cdf0e10cSrcweir             {
555cdf0e10cSrcweir                 nSum = (sal_uInt16)(nSum - nWidth);
556cdf0e10cSrcweir                 if ( 0 == nRightMax )
557cdf0e10cSrcweir                     nRightMax = (sal_uInt16)(nTmp - nPos);
558cdf0e10cSrcweir                 break;
559cdf0e10cSrcweir             }
560cdf0e10cSrcweir         }
561cdf0e10cSrcweir         pCur  = pLine->GetUpper();
562cdf0e10cSrcweir         pLine = pCur ? pCur->GetUpper() : 0;
563cdf0e10cSrcweir     }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir     sal_Bool bInsert = !bRefreshHidden;
566cdf0e10cSrcweir     for ( sal_uInt16 j = 0; bInsert && (j < rToFill.Count()); ++j )
567cdf0e10cSrcweir     {
568cdf0e10cSrcweir         long nCmp = rToFill[j];
569cdf0e10cSrcweir         if ( (nPos >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
570cdf0e10cSrcweir              (nPos <= (nCmp + COLFUZZY)) )
571cdf0e10cSrcweir         {
572cdf0e10cSrcweir             bInsert = sal_False;        //Hat ihn schon.
573cdf0e10cSrcweir         }
574cdf0e10cSrcweir         else if ( nPos < nCmp )
575cdf0e10cSrcweir         {
576cdf0e10cSrcweir             bInsert = sal_False;
577cdf0e10cSrcweir             rToFill.Insert( nPos, bHidden, j );
578cdf0e10cSrcweir         }
579cdf0e10cSrcweir     }
580cdf0e10cSrcweir     if ( bInsert )
581cdf0e10cSrcweir         rToFill.Insert( nPos, bHidden, rToFill.Count() );
582cdf0e10cSrcweir     else if ( bRefreshHidden )
583cdf0e10cSrcweir         ::lcl_RefreshHidden( rToFill, nPos );
584cdf0e10cSrcweir 
585cdf0e10cSrcweir     if ( bHidden && !bRefreshHidden )
586cdf0e10cSrcweir     {
587cdf0e10cSrcweir         // calculate minimum/maximum values for the existing entries:
588cdf0e10cSrcweir         nLeftMin = nPos - nLeftMin;
589cdf0e10cSrcweir         nRightMax = nPos + nRightMax;
590cdf0e10cSrcweir 
591cdf0e10cSrcweir         // check if nPos is entry:
592cdf0e10cSrcweir         bool bFoundPos = false;
593cdf0e10cSrcweir         bool bFoundMax = false;
594cdf0e10cSrcweir         for ( sal_uInt16 j = 0; !(bFoundPos && bFoundMax ) && j < rToFill.Count(); ++j )
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             SwTabColsEntry& rEntry = rToFill.GetEntry( j );
597cdf0e10cSrcweir             long nCmp = rToFill[j];
598cdf0e10cSrcweir 
599cdf0e10cSrcweir             if ( (nPos >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
600cdf0e10cSrcweir                  (nPos <= (nCmp + COLFUZZY)) )
601cdf0e10cSrcweir             {
602cdf0e10cSrcweir                 // check if nLeftMin is > old minimum for entry nPos:
603cdf0e10cSrcweir                 const long nOldMin = rEntry.nMin;
604cdf0e10cSrcweir                 if ( nLeftMin > nOldMin )
605cdf0e10cSrcweir                     rEntry.nMin = nLeftMin;
606cdf0e10cSrcweir                 // check if nRightMin is < old maximum for entry nPos:
607cdf0e10cSrcweir                 const long nOldMax = rEntry.nMax;
608cdf0e10cSrcweir                 if ( nRightMax < nOldMax )
609cdf0e10cSrcweir                     rEntry.nMax = nRightMax;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir                 bFoundPos = true;
612cdf0e10cSrcweir             }
613cdf0e10cSrcweir             else if ( (nRightMax >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
614cdf0e10cSrcweir                       (nRightMax <= (nCmp + COLFUZZY)) )
615cdf0e10cSrcweir             {
616cdf0e10cSrcweir                 // check if nPos is > old minimum for entry nRightMax:
617cdf0e10cSrcweir                 const long nOldMin = rEntry.nMin;
618cdf0e10cSrcweir                 if ( nPos > nOldMin )
619cdf0e10cSrcweir                     rEntry.nMin = nPos;
620cdf0e10cSrcweir 
621cdf0e10cSrcweir                 bFoundMax = true;
622cdf0e10cSrcweir             }
623cdf0e10cSrcweir         }
624cdf0e10cSrcweir     }
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
lcl_ProcessBoxGet(const SwTableBox * pBox,SwTabCols & rToFill,const SwFrmFmt * pTabFmt,FASTBOOL bRefreshHidden)627cdf0e10cSrcweir void lcl_ProcessBoxGet( const SwTableBox *pBox, SwTabCols &rToFill,
628cdf0e10cSrcweir                         const SwFrmFmt *pTabFmt, FASTBOOL bRefreshHidden )
629cdf0e10cSrcweir {
630cdf0e10cSrcweir     if ( pBox->GetTabLines().Count() )
631cdf0e10cSrcweir     {
632cdf0e10cSrcweir         const SwTableLines &rLines = pBox->GetTabLines();
633cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
634cdf0e10cSrcweir         {   const SwTableBoxes &rBoxes = rLines[i]->GetTabBoxes();
635cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < rBoxes.Count(); ++j )
636cdf0e10cSrcweir                 ::lcl_ProcessBoxGet( rBoxes[j], rToFill, pTabFmt, bRefreshHidden);
637cdf0e10cSrcweir         }
638cdf0e10cSrcweir     }
639cdf0e10cSrcweir     else
640cdf0e10cSrcweir         ::lcl_SortedTabColInsert( rToFill, pBox, pTabFmt, sal_False, bRefreshHidden );
641cdf0e10cSrcweir }
642cdf0e10cSrcweir 
lcl_ProcessLineGet(const SwTableLine * pLine,SwTabCols & rToFill,const SwFrmFmt * pTabFmt)643cdf0e10cSrcweir void lcl_ProcessLineGet( const SwTableLine *pLine, SwTabCols &rToFill,
644cdf0e10cSrcweir                          const SwFrmFmt *pTabFmt )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < pLine->GetTabBoxes().Count(); ++i )
647cdf0e10cSrcweir     {
648cdf0e10cSrcweir         const SwTableBox *pBox = pLine->GetTabBoxes()[i];
649cdf0e10cSrcweir         if ( pBox->GetSttNd() )
650cdf0e10cSrcweir             ::lcl_SortedTabColInsert( rToFill, pBox, pTabFmt, sal_True, sal_False );
651cdf0e10cSrcweir         else
652cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < pBox->GetTabLines().Count(); ++j )
653cdf0e10cSrcweir                 ::lcl_ProcessLineGet( pBox->GetTabLines()[j], rToFill, pTabFmt );
654cdf0e10cSrcweir     }
655cdf0e10cSrcweir }
656cdf0e10cSrcweir 
657cdf0e10cSrcweir // MS: Sonst Absturz auf der DEC-Kiste
658cdf0e10cSrcweir //
659cdf0e10cSrcweir #if defined(ALPHA) && defined(WNT)
660cdf0e10cSrcweir #pragma optimize("", off)
661cdf0e10cSrcweir #endif
662cdf0e10cSrcweir 
GetTabCols(SwTabCols & rToFill,const SwTableBox * pStart,sal_Bool bRefreshHidden,sal_Bool bCurRowOnly) const663cdf0e10cSrcweir void SwTable::GetTabCols( SwTabCols &rToFill, const SwTableBox *pStart,
664cdf0e10cSrcweir               sal_Bool bRefreshHidden, sal_Bool bCurRowOnly ) const
665cdf0e10cSrcweir {
666cdf0e10cSrcweir     //MA 30. Nov. 95: Opt: wenn bHidden gesetzt ist, wird nur das Hidden
667cdf0e10cSrcweir     //Array aktualisiert.
668cdf0e10cSrcweir     if ( bRefreshHidden )
669cdf0e10cSrcweir     {
670cdf0e10cSrcweir         //Korrekturen entfernen
671cdf0e10cSrcweir         sal_uInt16 i;
672cdf0e10cSrcweir         for ( i = 0; i < rToFill.Count(); ++i )
673cdf0e10cSrcweir         {
674cdf0e10cSrcweir             SwTabColsEntry& rEntry = rToFill.GetEntry( i );
675cdf0e10cSrcweir             rEntry.nPos -= rToFill.GetLeft();
676cdf0e10cSrcweir             rEntry.nMin -= rToFill.GetLeft();
677cdf0e10cSrcweir             rEntry.nMax -= rToFill.GetLeft();
678cdf0e10cSrcweir         }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir         //Alle sind hidden, dann die sichtbaren eintragen.
681cdf0e10cSrcweir         for ( i = 0; i < rToFill.Count(); ++i )
682cdf0e10cSrcweir             rToFill.SetHidden( i, sal_True );
683cdf0e10cSrcweir     }
684cdf0e10cSrcweir     else
685cdf0e10cSrcweir     {
686cdf0e10cSrcweir         rToFill.Remove( 0, rToFill.Count() );
687cdf0e10cSrcweir     }
688cdf0e10cSrcweir 
689cdf0e10cSrcweir     //Eingetragen werden:
690cdf0e10cSrcweir     //1. Alle Boxen unterhalb der dem Start uebergeordneten Line sowie
691cdf0e10cSrcweir     //   deren untergeordnete Boxen falls vorhanden.
692cdf0e10cSrcweir     //2. Ausgehend von der Line die uebergeordnete Box sowie deren Nachbarn;
693cdf0e10cSrcweir     //   nicht aber deren untergeordnete.
694cdf0e10cSrcweir     //3. Mit der der Boxenkette uebergeordneten Line wieder wie 2. bis einer
695cdf0e10cSrcweir     //   Line keine Box (sondern die Table) uebergeordnet ist.
696cdf0e10cSrcweir     //Es werden nur diejenigen Boxen eingetragen, die keine weiteren Zeilen
697cdf0e10cSrcweir     //enhalten. Die eintragende Funktion sorgt dafuer, dass keine doppelten
698cdf0e10cSrcweir     //eingetragen werden. Um dies zu gewaehrleisten wird mit einer gewissen
699cdf0e10cSrcweir     //Unschaerfe gearbeitet (um Rundungsfehler auszuschalten).
700cdf0e10cSrcweir     //Es werden nur die linken Kanten der Boxen eingetragen.
701cdf0e10cSrcweir     //Am Schluss wird der Erste wieder ausgetragen denn er ist bereits vom
702cdf0e10cSrcweir     //Rand abgedeckt.
703cdf0e10cSrcweir 
704cdf0e10cSrcweir     //4. Nochmalige abscannen der Tabelle und eintragen _aller_ Boxen,
705cdf0e10cSrcweir     //   jetzt aber als Hidden.
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     const SwFrmFmt *pTabFmt = GetFrmFmt();
708cdf0e10cSrcweir 
709cdf0e10cSrcweir     //1.
710cdf0e10cSrcweir     const SwTableBoxes &rBoxes = pStart->GetUpper()->GetTabBoxes();
711cdf0e10cSrcweir 
712cdf0e10cSrcweir     sal_uInt16 i;
713cdf0e10cSrcweir     for ( i = 0; i < rBoxes.Count(); ++i )
714cdf0e10cSrcweir         ::lcl_ProcessBoxGet( rBoxes[i], rToFill, pTabFmt, bRefreshHidden );
715cdf0e10cSrcweir 
716cdf0e10cSrcweir     //2. und 3.
717cdf0e10cSrcweir     const SwTableLine *pLine = pStart->GetUpper()->GetUpper() ?
718cdf0e10cSrcweir                                 pStart->GetUpper()->GetUpper()->GetUpper() : 0;
719cdf0e10cSrcweir     while ( pLine )
720cdf0e10cSrcweir     {
721cdf0e10cSrcweir         const SwTableBoxes &rBoxes2 = pLine->GetTabBoxes();
722cdf0e10cSrcweir         for ( sal_uInt16 k = 0; k < rBoxes2.Count(); ++k )
723cdf0e10cSrcweir             ::lcl_SortedTabColInsert( rToFill, rBoxes2[k],
724cdf0e10cSrcweir                                       pTabFmt, sal_False, bRefreshHidden );
725cdf0e10cSrcweir         pLine = pLine->GetUpper() ? pLine->GetUpper()->GetUpper() : 0;
726cdf0e10cSrcweir     }
727cdf0e10cSrcweir 
728cdf0e10cSrcweir     if ( !bRefreshHidden )
729cdf0e10cSrcweir     {
730cdf0e10cSrcweir         //4.
731cdf0e10cSrcweir         if ( !bCurRowOnly )
732cdf0e10cSrcweir         {
733cdf0e10cSrcweir             for ( i = 0; i < aLines.Count(); ++i )
734cdf0e10cSrcweir                 ::lcl_ProcessLineGet( aLines[i], rToFill, pTabFmt );
735cdf0e10cSrcweir         }
736cdf0e10cSrcweir 
737cdf0e10cSrcweir         rToFill.Remove( 0, 1 );
738cdf0e10cSrcweir     }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir     //Die Koordinaten sind jetzt relativ zum linken Rand der Tabelle - also
741cdf0e10cSrcweir     //relativ zum nLeft vom SwTabCols. Die Werte werden aber relativ zum
742cdf0e10cSrcweir     //linken Rand - also nLeftMin vom SwTabCols - erwartet.
743cdf0e10cSrcweir     //Alle Werte muessen also um nLeft erweitert werden.
744cdf0e10cSrcweir     for ( i = 0; i < rToFill.Count(); ++i )
745cdf0e10cSrcweir     {
746cdf0e10cSrcweir         SwTabColsEntry& rEntry = rToFill.GetEntry( i );
747cdf0e10cSrcweir         rEntry.nPos += rToFill.GetLeft();
748cdf0e10cSrcweir         rEntry.nMin += rToFill.GetLeft();
749cdf0e10cSrcweir         rEntry.nMax += rToFill.GetLeft();
750cdf0e10cSrcweir     }
751cdf0e10cSrcweir }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir #if defined(ALPHA) && defined(WNT)
754cdf0e10cSrcweir #pragma optimize("", on)
755cdf0e10cSrcweir #endif
756cdf0e10cSrcweir 
757cdf0e10cSrcweir /*************************************************************************
758cdf0e10cSrcweir |*
759cdf0e10cSrcweir |*  SwTable::SetTabCols()
760cdf0e10cSrcweir |*
761cdf0e10cSrcweir |*************************************************************************/
762cdf0e10cSrcweir //Struktur zur Parameteruebergabe
763cdf0e10cSrcweir struct Parm
764cdf0e10cSrcweir {
765cdf0e10cSrcweir     const SwTabCols &rNew;
766cdf0e10cSrcweir     const SwTabCols &rOld;
767cdf0e10cSrcweir     long nNewWish,
768cdf0e10cSrcweir          nOldWish;
769cdf0e10cSrcweir     SvPtrarr aBoxArr;
770cdf0e10cSrcweir     SwShareBoxFmts aShareFmts;
771cdf0e10cSrcweir 
ParmParm772cdf0e10cSrcweir     Parm( const SwTabCols &rN, const SwTabCols &rO ) :
773cdf0e10cSrcweir         rNew( rN ), rOld( rO ), aBoxArr( 10, 1 ) {}
774cdf0e10cSrcweir };
BoxInArr(SvPtrarr & rArr,SwTableBox * pBox)775cdf0e10cSrcweir inline sal_Bool BoxInArr( SvPtrarr& rArr, SwTableBox* pBox )
776cdf0e10cSrcweir {
777cdf0e10cSrcweir     sal_Bool bRet = USHRT_MAX != rArr.GetPos( (VoidPtr)pBox );
778cdf0e10cSrcweir     if( !bRet )
779cdf0e10cSrcweir         rArr.Insert( (VoidPtr)pBox, rArr.Count() );
780cdf0e10cSrcweir     return bRet;
781cdf0e10cSrcweir }
782cdf0e10cSrcweir 
783cdf0e10cSrcweir void lcl_ProcessBoxSet( SwTableBox *pBox, Parm &rParm );
784cdf0e10cSrcweir 
lcl_ProcessLine(SwTableLine * pLine,Parm & rParm)785cdf0e10cSrcweir void lcl_ProcessLine( SwTableLine *pLine, Parm &rParm )
786cdf0e10cSrcweir {
787cdf0e10cSrcweir     SwTableBoxes &rBoxes = pLine->GetTabBoxes();
788cdf0e10cSrcweir     for ( int i = rBoxes.Count()-1; i >= 0; --i )
789cdf0e10cSrcweir         ::lcl_ProcessBoxSet( rBoxes[ static_cast< sal_uInt16 >(i) ], rParm );
790cdf0e10cSrcweir }
791cdf0e10cSrcweir 
lcl_ProcessBoxSet(SwTableBox * pBox,Parm & rParm)792cdf0e10cSrcweir void lcl_ProcessBoxSet( SwTableBox *pBox, Parm &rParm )
793cdf0e10cSrcweir {
794cdf0e10cSrcweir     if ( pBox->GetTabLines().Count() )
795cdf0e10cSrcweir     {   SwTableLines &rLines = pBox->GetTabLines();
796cdf0e10cSrcweir         for ( int i = rLines.Count()-1; i >= 0; --i )
797cdf0e10cSrcweir             lcl_ProcessLine( rLines[ static_cast< sal_uInt16 >(i) ], rParm );
798cdf0e10cSrcweir     }
799cdf0e10cSrcweir     else
800cdf0e10cSrcweir     {
801cdf0e10cSrcweir         //Aktuelle Position (linke und rechte Kante berechnen) und im
802cdf0e10cSrcweir         //alten TabCols suchen. Im neuen TabCols die Werte vergleichen und
803cdf0e10cSrcweir         //wenn es Unterschiede gibt die Box entsprechend anpassen.
804cdf0e10cSrcweir         //Wenn an der veraenderten Kante kein Nachbar existiert werden auch
805cdf0e10cSrcweir         //alle uebergeordneten Boxen angepasst.
806cdf0e10cSrcweir 
807cdf0e10cSrcweir         const long nOldAct = rParm.rOld.GetRight() -
808cdf0e10cSrcweir                              rParm.rOld.GetLeft(); // +1 why?
809cdf0e10cSrcweir 
810cdf0e10cSrcweir         //Der Wert fuer die linke Kante der Box errechnet sich aus den
811cdf0e10cSrcweir         //Breiten der vorhergehenden Boxen plus dem linken Rand
812cdf0e10cSrcweir         long nLeft = rParm.rOld.GetLeft();
813cdf0e10cSrcweir         const  SwTableBox  *pCur  = pBox;
814cdf0e10cSrcweir         const  SwTableLine *pLine = pBox->GetUpper();
815cdf0e10cSrcweir 
816cdf0e10cSrcweir         while ( pLine )
817cdf0e10cSrcweir         {   const SwTableBoxes &rBoxes = pLine->GetTabBoxes();
818cdf0e10cSrcweir             for ( sal_uInt16 i = 0; (i < rBoxes.Count()) && (rBoxes[i] != pCur); ++i)
819cdf0e10cSrcweir             {
820cdf0e10cSrcweir                 sal_uInt64 nWidth = rBoxes[i]->GetFrmFmt()->
821cdf0e10cSrcweir                                         GetFrmSize().GetWidth();
822cdf0e10cSrcweir                 nWidth *= nOldAct;
823cdf0e10cSrcweir                 nWidth /= rParm.nOldWish;
824cdf0e10cSrcweir                 nLeft += (sal_uInt16)nWidth;
825cdf0e10cSrcweir             }
826cdf0e10cSrcweir             pCur  = pLine->GetUpper();
827cdf0e10cSrcweir             pLine = pCur ? pCur->GetUpper() : 0;
828cdf0e10cSrcweir         }
829cdf0e10cSrcweir         long nLeftDiff;
830cdf0e10cSrcweir         long nRightDiff = 0;
831cdf0e10cSrcweir         if ( nLeft != rParm.rOld.GetLeft() ) //Es gibt noch Boxen davor.
832cdf0e10cSrcweir         {
833cdf0e10cSrcweir             //Rechte Kante ist linke Kante plus Breite.
834cdf0e10cSrcweir             sal_uInt64 nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
835cdf0e10cSrcweir             nWidth *= nOldAct;
836cdf0e10cSrcweir             nWidth /= rParm.nOldWish;
837cdf0e10cSrcweir             long nRight = nLeft + (long)nWidth;
838cdf0e10cSrcweir             sal_uInt16 nLeftPos  = USHRT_MAX,
839cdf0e10cSrcweir                    nRightPos = USHRT_MAX;
840cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < rParm.rOld.Count(); ++i )
841cdf0e10cSrcweir             {
842cdf0e10cSrcweir                 if ( nLeft >= (rParm.rOld[i] - COLFUZZY) &&
843cdf0e10cSrcweir                      nLeft <= (rParm.rOld[i] + COLFUZZY) )
844cdf0e10cSrcweir                     nLeftPos = i;
845cdf0e10cSrcweir                 else if ( nRight >= (rParm.rOld[i] - COLFUZZY) &&
846cdf0e10cSrcweir                           nRight <= (rParm.rOld[i] + COLFUZZY) )
847cdf0e10cSrcweir                     nRightPos = i;
848cdf0e10cSrcweir             }
849cdf0e10cSrcweir             nLeftDiff = nLeftPos != USHRT_MAX ?
850cdf0e10cSrcweir                     (int)rParm.rOld[nLeftPos] - (int)rParm.rNew[nLeftPos] : 0;
851cdf0e10cSrcweir             nRightDiff= nRightPos!= USHRT_MAX ?
852cdf0e10cSrcweir                     (int)rParm.rNew[nRightPos] - (int)rParm.rOld[nRightPos] : 0;
853cdf0e10cSrcweir         }
854cdf0e10cSrcweir         else    //Die erste Box.
855cdf0e10cSrcweir         {
856cdf0e10cSrcweir             nLeftDiff = (long)rParm.rOld.GetLeft() - (long)rParm.rNew.GetLeft();
857cdf0e10cSrcweir             if ( rParm.rOld.Count() )
858cdf0e10cSrcweir             {
859cdf0e10cSrcweir                 //Differnz zu der Kante berechnen, von der die erste Box
860cdf0e10cSrcweir                 //beruehrt wird.
861cdf0e10cSrcweir                 sal_uInt64 nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
862cdf0e10cSrcweir                 nWidth *= nOldAct;
863cdf0e10cSrcweir                 nWidth /= rParm.nOldWish;
864cdf0e10cSrcweir                 long nTmp = (long)nWidth;
865cdf0e10cSrcweir                 nTmp += rParm.rOld.GetLeft();
866cdf0e10cSrcweir                 sal_uInt16 nLeftPos = USHRT_MAX;
867cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < rParm.rOld.Count() &&
868cdf0e10cSrcweir                                     nLeftPos == USHRT_MAX; ++i )
869cdf0e10cSrcweir                 {
870cdf0e10cSrcweir                     if ( nTmp >= (rParm.rOld[i] - COLFUZZY) &&
871cdf0e10cSrcweir                          nTmp <= (rParm.rOld[i] + COLFUZZY) )
872cdf0e10cSrcweir                         nLeftPos = i;
873cdf0e10cSrcweir                 }
874cdf0e10cSrcweir                 if ( nLeftPos != USHRT_MAX )
875cdf0e10cSrcweir                     nRightDiff = (long)rParm.rNew[nLeftPos] -
876cdf0e10cSrcweir                                  (long)rParm.rOld[nLeftPos];
877cdf0e10cSrcweir             }
878cdf0e10cSrcweir //MA 11. Feb. 99: #61577# 0 sollte doch gerade richtig sein, weil die
879cdf0e10cSrcweir //Kante doch schon in SetTabCols() korrigiert wurde.
880cdf0e10cSrcweir //          else
881cdf0e10cSrcweir //              nRightDiff = (long)rParm.rNew.GetRight() -
882cdf0e10cSrcweir //                           (long)rParm.rOld.GetRight();
883cdf0e10cSrcweir         }
884cdf0e10cSrcweir 
885cdf0e10cSrcweir         if( pBox->getRowSpan() == 1 )
886cdf0e10cSrcweir         {
887cdf0e10cSrcweir             SwTableBoxes& rTblBoxes = pBox->GetUpper()->GetTabBoxes();
888cdf0e10cSrcweir             sal_uInt16 nPos = rTblBoxes.C40_GETPOS( SwTableBox, pBox );
889cdf0e10cSrcweir             if( nPos && rTblBoxes[ nPos - 1 ]->getRowSpan() != 1 )
890cdf0e10cSrcweir                 nLeftDiff = 0;
891cdf0e10cSrcweir             if( nPos + 1 < rTblBoxes.Count() &&
892cdf0e10cSrcweir                 rTblBoxes[ nPos + 1 ]->getRowSpan() != 1 )
893cdf0e10cSrcweir                 nRightDiff = 0;
894cdf0e10cSrcweir         }
895cdf0e10cSrcweir         else
896cdf0e10cSrcweir             nLeftDiff = nRightDiff = 0;
897cdf0e10cSrcweir 
898cdf0e10cSrcweir         if ( nLeftDiff || nRightDiff )
899cdf0e10cSrcweir         {
900cdf0e10cSrcweir             //Die Differenz ist der tatsaechliche Differenzbetrag; die
901cdf0e10cSrcweir             //Attribute der Boxen um diesen Betrag anzupassen macht keinen
902cdf0e10cSrcweir             //Sinn wenn die Tabelle gestrecht ist. Der Differenzbetrag muss
903cdf0e10cSrcweir             //entsprechend umgerechnet werden.
904cdf0e10cSrcweir             long nTmp = rParm.rNew.GetRight() - rParm.rNew.GetLeft(); // +1 why?
905cdf0e10cSrcweir             nLeftDiff *= rParm.nNewWish;
906cdf0e10cSrcweir             nLeftDiff /= nTmp;
907cdf0e10cSrcweir             nRightDiff *= rParm.nNewWish;
908cdf0e10cSrcweir             nRightDiff /= nTmp;
909cdf0e10cSrcweir             long nDiff = nLeftDiff + nRightDiff;
910cdf0e10cSrcweir 
911cdf0e10cSrcweir             //Box und alle uebergeordneten um den Differenzbetrag anpassen.
912cdf0e10cSrcweir             while ( pBox )
913cdf0e10cSrcweir             {
914cdf0e10cSrcweir                 SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
915cdf0e10cSrcweir                 aFmtFrmSize.SetWidth( aFmtFrmSize.GetWidth() + nDiff );
916cdf0e10cSrcweir                 if ( aFmtFrmSize.GetWidth() < 0 )
917cdf0e10cSrcweir                     aFmtFrmSize.SetWidth( -aFmtFrmSize.GetWidth() );
918cdf0e10cSrcweir                 rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
919cdf0e10cSrcweir 
920cdf0e10cSrcweir                 // The outer cells of the last row are responsible to adjust a surrounding cell.
921cdf0e10cSrcweir                 // Last line check:
922cdf0e10cSrcweir                 if ( pBox->GetUpper()->GetUpper() &&
923cdf0e10cSrcweir                      pBox->GetUpper() != pBox->GetUpper()->GetUpper()->GetTabLines()
924cdf0e10cSrcweir                         [pBox->GetUpper()->GetUpper()->GetTabLines().Count()-1])
925cdf0e10cSrcweir                 {
926cdf0e10cSrcweir                    pBox = 0;
927cdf0e10cSrcweir                 }
928cdf0e10cSrcweir                 else
929cdf0e10cSrcweir                 {
930cdf0e10cSrcweir                     // Middle cell check:
931cdf0e10cSrcweir                     if ( pBox != pBox->GetUpper()->GetTabBoxes()[0] )
932cdf0e10cSrcweir                         nDiff = nRightDiff;
933cdf0e10cSrcweir 
934cdf0e10cSrcweir                     if ( pBox != pBox->GetUpper()->GetTabBoxes()
935cdf0e10cSrcweir                                 [pBox->GetUpper()->GetTabBoxes().Count()-1] )
936cdf0e10cSrcweir                         nDiff -= nRightDiff;
937cdf0e10cSrcweir 
938cdf0e10cSrcweir                     pBox = nDiff ? pBox->GetUpper()->GetUpper() : 0;
939cdf0e10cSrcweir                 }
940cdf0e10cSrcweir             }
941cdf0e10cSrcweir         }
942cdf0e10cSrcweir     }
943cdf0e10cSrcweir }
944cdf0e10cSrcweir 
lcl_ProcessBoxPtr(SwTableBox * pBox,SvPtrarr & rBoxArr,sal_Bool bBefore)945cdf0e10cSrcweir void lcl_ProcessBoxPtr( SwTableBox *pBox, SvPtrarr &rBoxArr,
946cdf0e10cSrcweir                            sal_Bool bBefore )
947cdf0e10cSrcweir {
948cdf0e10cSrcweir     if ( pBox->GetTabLines().Count() )
949cdf0e10cSrcweir     {
950cdf0e10cSrcweir         const SwTableLines &rLines = pBox->GetTabLines();
951cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
952cdf0e10cSrcweir         {
953cdf0e10cSrcweir             const SwTableBoxes &rBoxes = rLines[i]->GetTabBoxes();
954cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < rBoxes.Count(); ++j )
955cdf0e10cSrcweir                 ::lcl_ProcessBoxPtr( rBoxes[j], rBoxArr, bBefore );
956cdf0e10cSrcweir         }
957cdf0e10cSrcweir     }
958cdf0e10cSrcweir     else if ( bBefore )
959cdf0e10cSrcweir         rBoxArr.Insert( (VoidPtr)pBox, 0 );
960cdf0e10cSrcweir     else
961cdf0e10cSrcweir         rBoxArr.Insert( (VoidPtr)pBox, rBoxArr.Count() );
962cdf0e10cSrcweir }
963cdf0e10cSrcweir 
964cdf0e10cSrcweir void lcl_AdjustBox( SwTableBox *pBox, const long nDiff, Parm &rParm );
965cdf0e10cSrcweir 
lcl_AdjustLines(SwTableLines & rLines,const long nDiff,Parm & rParm)966cdf0e10cSrcweir void lcl_AdjustLines( SwTableLines &rLines, const long nDiff, Parm &rParm )
967cdf0e10cSrcweir {
968cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
969cdf0e10cSrcweir     {
970cdf0e10cSrcweir         SwTableBox *pBox = rLines[i]->GetTabBoxes()
971cdf0e10cSrcweir                                 [rLines[i]->GetTabBoxes().Count()-1];
972cdf0e10cSrcweir         lcl_AdjustBox( pBox, nDiff, rParm );
973cdf0e10cSrcweir     }
974cdf0e10cSrcweir }
975cdf0e10cSrcweir 
lcl_AdjustBox(SwTableBox * pBox,const long nDiff,Parm & rParm)976cdf0e10cSrcweir void lcl_AdjustBox( SwTableBox *pBox, const long nDiff, Parm &rParm )
977cdf0e10cSrcweir {
978cdf0e10cSrcweir     if ( pBox->GetTabLines().Count() )
979cdf0e10cSrcweir         ::lcl_AdjustLines( pBox->GetTabLines(), nDiff, rParm );
980cdf0e10cSrcweir 
981cdf0e10cSrcweir     //Groesse der Box anpassen.
982cdf0e10cSrcweir     SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
983cdf0e10cSrcweir     aFmtFrmSize.SetWidth( aFmtFrmSize.GetWidth() + nDiff );
984cdf0e10cSrcweir //#30009#       if ( aFmtFrmSize.GetWidth() < 0 )
985cdf0e10cSrcweir //          aFmtFrmSize.SetWidth( -aFmtFrmSize.GetWidth() );
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
988cdf0e10cSrcweir }
989cdf0e10cSrcweir 
SetTabCols(const SwTabCols & rNew,const SwTabCols & rOld,const SwTableBox * pStart,sal_Bool bCurRowOnly)990cdf0e10cSrcweir void SwTable::SetTabCols( const SwTabCols &rNew, const SwTabCols &rOld,
991cdf0e10cSrcweir                           const SwTableBox *pStart, sal_Bool bCurRowOnly )
992cdf0e10cSrcweir {
993cdf0e10cSrcweir     CHECK_TABLE( *this )
994cdf0e10cSrcweir 
995cdf0e10cSrcweir     SetHTMLTableLayout( 0 );    // MIB 9.7.97: HTML-Layout loeschen
996cdf0e10cSrcweir 
997cdf0e10cSrcweir     // FME: Made rOld const. The caller is responsible for passing correct
998cdf0e10cSrcweir     // values of rOld. Therefore we do not have to call GetTabCols anymore:
999cdf0e10cSrcweir     //GetTabCols( rOld, pStart );
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir     Parm aParm( rNew, rOld );
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir     ASSERT( rOld.Count() == rNew.Count(), "Columnanzahl veraendert.");
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir     //Raender verarbeiten. Groesse der Tabelle und ein paar Boxen mussen
1006cdf0e10cSrcweir     //angepasst werden. Bei der Groesseneinstellung darf allerdings das
1007cdf0e10cSrcweir     //Modify nicht verarbeitet werden - dieses wuerde alle Boxen anpassen
1008cdf0e10cSrcweir     //und das koennen wir ueberhaupt nicht gebrauchen.
1009cdf0e10cSrcweir     SwFrmFmt *pFmt = GetFrmFmt();
1010cdf0e10cSrcweir     aParm.nOldWish = aParm.nNewWish = pFmt->GetFrmSize().GetWidth();
1011cdf0e10cSrcweir     if ( (rOld.GetLeft() != rNew.GetLeft()) ||
1012cdf0e10cSrcweir          (rOld.GetRight()!= rNew.GetRight()) )
1013cdf0e10cSrcweir     {
1014cdf0e10cSrcweir         LockModify();
1015cdf0e10cSrcweir         {
1016cdf0e10cSrcweir             SvxLRSpaceItem aLR( pFmt->GetLRSpace() );
1017cdf0e10cSrcweir             SvxShadowItem aSh( pFmt->GetShadow() );
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir             SwTwips nShRight = aSh.CalcShadowSpace( SHADOW_RIGHT );
1020cdf0e10cSrcweir             SwTwips nShLeft = aSh.CalcShadowSpace( SHADOW_LEFT );
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir             aLR.SetLeft ( rNew.GetLeft() - nShLeft );
1023cdf0e10cSrcweir             aLR.SetRight( rNew.GetRightMax() - rNew.GetRight() - nShRight );
1024cdf0e10cSrcweir             pFmt->SetFmtAttr( aLR );
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir             //Die Ausrichtung der Tabelle muss entsprechend angepasst werden,
1027cdf0e10cSrcweir             //das geschieht so, dass die Tabelle genauso stehenbleibt wie der
1028cdf0e10cSrcweir             //Anwender sie gerade hingezuppelt hat.
1029cdf0e10cSrcweir             SwFmtHoriOrient aOri( pFmt->GetHoriOrient() );
1030cdf0e10cSrcweir             if(text::HoriOrientation::NONE != aOri.GetHoriOrient())
1031cdf0e10cSrcweir             {
1032cdf0e10cSrcweir                 const sal_Bool bLeftDist = rNew.GetLeft() != nShLeft;
1033cdf0e10cSrcweir                 const sal_Bool bRightDist = rNew.GetRight() + nShRight != rNew.GetRightMax();
1034cdf0e10cSrcweir                 if(!bLeftDist && !bRightDist)
1035cdf0e10cSrcweir                     aOri.SetHoriOrient( text::HoriOrientation::FULL );
1036cdf0e10cSrcweir                 else if(!bRightDist && rNew.GetLeft() > nShLeft )
1037cdf0e10cSrcweir                     aOri.SetHoriOrient( text::HoriOrientation::RIGHT );
1038cdf0e10cSrcweir                 else if(!bLeftDist && rNew.GetRight() + nShRight < rNew.GetRightMax())
1039cdf0e10cSrcweir                     aOri.SetHoriOrient( text::HoriOrientation::LEFT );
1040cdf0e10cSrcweir                 else
1041cdf0e10cSrcweir                     aOri.SetHoriOrient( text::HoriOrientation::NONE );
1042cdf0e10cSrcweir             }
1043cdf0e10cSrcweir             pFmt->SetFmtAttr( aOri );
1044cdf0e10cSrcweir         }
1045cdf0e10cSrcweir         const long nAct = rOld.GetRight() - rOld.GetLeft(); // +1 why?
1046cdf0e10cSrcweir         long nTabDiff = 0;
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir         if ( rOld.GetLeft() != rNew.GetLeft() )
1049cdf0e10cSrcweir         {
1050cdf0e10cSrcweir             nTabDiff = rOld.GetLeft() - rNew.GetLeft();
1051cdf0e10cSrcweir             nTabDiff *= aParm.nOldWish;
1052cdf0e10cSrcweir             nTabDiff /= nAct;
1053cdf0e10cSrcweir         }
1054cdf0e10cSrcweir         if ( rOld.GetRight() != rNew.GetRight() )
1055cdf0e10cSrcweir         {
1056cdf0e10cSrcweir             long nDiff = rNew.GetRight() - rOld.GetRight();
1057cdf0e10cSrcweir             nDiff *= aParm.nOldWish;
1058cdf0e10cSrcweir             nDiff /= nAct;
1059cdf0e10cSrcweir             nTabDiff += nDiff;
1060cdf0e10cSrcweir             if( !IsNewModel() )
1061cdf0e10cSrcweir                 ::lcl_AdjustLines( GetTabLines(), nDiff, aParm );
1062cdf0e10cSrcweir         }
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir         //Groesse der Tabelle anpassen. Es muss beachtet werden, das die
1065cdf0e10cSrcweir         //Tabelle gestrecht sein kann.
1066cdf0e10cSrcweir         if ( nTabDiff )
1067cdf0e10cSrcweir         {
1068cdf0e10cSrcweir             aParm.nNewWish += nTabDiff;
1069cdf0e10cSrcweir             if ( aParm.nNewWish < 0 )
1070cdf0e10cSrcweir                 aParm.nNewWish = USHRT_MAX; //Uuups! Eine Rolle rueckwaerts.
1071cdf0e10cSrcweir             SwFmtFrmSize aSz( pFmt->GetFrmSize() );
1072cdf0e10cSrcweir             if ( aSz.GetWidth() != aParm.nNewWish )
1073cdf0e10cSrcweir             {
1074cdf0e10cSrcweir                 aSz.SetWidth( aParm.nNewWish );
1075cdf0e10cSrcweir                 aSz.SetWidthPercent( 0 );
1076cdf0e10cSrcweir                 pFmt->SetFmtAttr( aSz );
1077cdf0e10cSrcweir             }
1078cdf0e10cSrcweir         }
1079cdf0e10cSrcweir         UnlockModify();
1080cdf0e10cSrcweir     }
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir     if( IsNewModel() )
1083cdf0e10cSrcweir         NewSetTabCols( aParm, rNew, rOld, pStart, bCurRowOnly );
1084cdf0e10cSrcweir     else
1085cdf0e10cSrcweir     {
1086cdf0e10cSrcweir         if ( bCurRowOnly )
1087cdf0e10cSrcweir         {
1088cdf0e10cSrcweir             //Um die aktuelle Zeile anzupassen muessen wir analog zu dem
1089cdf0e10cSrcweir             //Verfahren zum fuellen der TabCols (siehe GetTabCols()) die
1090cdf0e10cSrcweir             //Boxen der aktuellen Zeile abklappern.
1091cdf0e10cSrcweir             //Leider muessen wir auch hier dafuer sorgen, dass die Boxen von
1092cdf0e10cSrcweir             //hinten nach vorne bzw. von innen nach aussen veraendert werden.
1093cdf0e10cSrcweir             //Der beste Weg hierzu scheint mir darin zu liegen die
1094cdf0e10cSrcweir             //entsprechenden Boxen in einem PtrArray vorzumerken.
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir             const SwTableBoxes &rBoxes = pStart->GetUpper()->GetTabBoxes();
1097cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
1098cdf0e10cSrcweir                 ::lcl_ProcessBoxPtr( rBoxes[i], aParm.aBoxArr, sal_False );
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir             const SwTableLine *pLine = pStart->GetUpper()->GetUpper() ?
1101cdf0e10cSrcweir                                     pStart->GetUpper()->GetUpper()->GetUpper() : 0;
1102cdf0e10cSrcweir             const SwTableBox  *pExcl = pStart->GetUpper()->GetUpper();
1103cdf0e10cSrcweir             while ( pLine )
1104cdf0e10cSrcweir             {
1105cdf0e10cSrcweir                 const SwTableBoxes &rBoxes2 = pLine->GetTabBoxes();
1106cdf0e10cSrcweir                 sal_Bool bBefore = sal_True;
1107cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < rBoxes2.Count(); ++i )
1108cdf0e10cSrcweir                 {
1109cdf0e10cSrcweir                     if ( rBoxes2[i] != pExcl )
1110cdf0e10cSrcweir                         ::lcl_ProcessBoxPtr( rBoxes2[i], aParm.aBoxArr, bBefore );
1111cdf0e10cSrcweir                     else
1112cdf0e10cSrcweir                         bBefore = sal_False;
1113cdf0e10cSrcweir                 }
1114cdf0e10cSrcweir                 pExcl = pLine->GetUpper();
1115cdf0e10cSrcweir                 pLine = pLine->GetUpper() ? pLine->GetUpper()->GetUpper() : 0;
1116cdf0e10cSrcweir             }
1117cdf0e10cSrcweir             //Nachdem wir haufenweise Boxen (hoffentlich alle und in der richtigen
1118cdf0e10cSrcweir             //Reihenfolge) eingetragen haben, brauchen diese nur noch rueckwaerts
1119cdf0e10cSrcweir             //verarbeitet zu werden.
1120cdf0e10cSrcweir             for ( int j = aParm.aBoxArr.Count()-1; j >= 0; --j )
1121cdf0e10cSrcweir             {
1122cdf0e10cSrcweir                 SwTableBox *pBox = (SwTableBox*)aParm.aBoxArr[ static_cast< sal_uInt16 >(j)];
1123cdf0e10cSrcweir                 ::lcl_ProcessBoxSet( pBox, aParm );
1124cdf0e10cSrcweir             }
1125cdf0e10cSrcweir         }
1126cdf0e10cSrcweir         else
1127cdf0e10cSrcweir         {   //Die gesamte Tabelle anzupassen ist 'einfach'.
1128cdf0e10cSrcweir             //Es werden alle Boxen, die keine Lines mehr enthalten angepasst.
1129cdf0e10cSrcweir             //Diese Boxen passen alle uebergeordneten Boxen entsprechend mit an.
1130cdf0e10cSrcweir             //Um uns nicht selbst hereinzulegen muss natuerlich rueckwaerst
1131cdf0e10cSrcweir             //gearbeitet werden!
1132cdf0e10cSrcweir             SwTableLines &rLines = GetTabLines();
1133cdf0e10cSrcweir             for ( int i = rLines.Count()-1; i >= 0; --i )
1134cdf0e10cSrcweir                 ::lcl_ProcessLine( rLines[ static_cast< sal_uInt16 >(i) ], aParm );
1135cdf0e10cSrcweir         }
1136cdf0e10cSrcweir     }
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir #ifdef DBG_UTIL
1139cdf0e10cSrcweir     {
1140cdf0e10cSrcweir // steht im tblrwcl.cxx
1141cdf0e10cSrcweir extern void _CheckBoxWidth( const SwTableLine&, SwTwips );
1142cdf0e10cSrcweir         // checke doch mal ob die Tabellen korrekte Breiten haben
1143cdf0e10cSrcweir         SwTwips nSize = GetFrmFmt()->GetFrmSize().GetWidth();
1144cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < aLines.Count(); ++n  )
1145cdf0e10cSrcweir             _CheckBoxWidth( *aLines[ n ], nSize );
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir #endif
1148cdf0e10cSrcweir }
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir typedef std::pair<sal_uInt16, sal_uInt16> ColChange;
1151cdf0e10cSrcweir typedef std::list< ColChange > ChangeList;
1152cdf0e10cSrcweir 
lcl_AdjustWidthsInLine(SwTableLine * pLine,ChangeList & rOldNew,Parm & rParm,sal_uInt16 nColFuzzy)1153cdf0e10cSrcweir static void lcl_AdjustWidthsInLine( SwTableLine* pLine, ChangeList& rOldNew,
1154cdf0e10cSrcweir     Parm& rParm, sal_uInt16 nColFuzzy )
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir     ChangeList::iterator pCurr = rOldNew.begin();
1157cdf0e10cSrcweir     if( pCurr == rOldNew.end() )
1158cdf0e10cSrcweir         return;
1159cdf0e10cSrcweir     sal_uInt16 nCount = pLine->GetTabBoxes().Count();
1160cdf0e10cSrcweir     sal_uInt16 i = 0;
1161cdf0e10cSrcweir     SwTwips nBorder = 0;
1162cdf0e10cSrcweir     SwTwips nRest = 0;
1163cdf0e10cSrcweir     while( i < nCount )
1164cdf0e10cSrcweir     {
1165cdf0e10cSrcweir         SwTableBox* pBox = pLine->GetTabBoxes()[i++];
1166cdf0e10cSrcweir         SwTwips nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
1167cdf0e10cSrcweir         SwTwips nNewWidth = nWidth - nRest;
1168cdf0e10cSrcweir         nRest = 0;
1169cdf0e10cSrcweir         nBorder += nWidth;
1170cdf0e10cSrcweir         if( pCurr != rOldNew.end() && nBorder + nColFuzzy >= pCurr->first )
1171cdf0e10cSrcweir         {
1172cdf0e10cSrcweir             nBorder -= nColFuzzy;
1173cdf0e10cSrcweir             while( pCurr != rOldNew.end() && nBorder > pCurr->first )
1174cdf0e10cSrcweir                 ++pCurr;
1175cdf0e10cSrcweir             if( pCurr != rOldNew.end() )
1176cdf0e10cSrcweir             {
1177cdf0e10cSrcweir                 nBorder += nColFuzzy;
1178cdf0e10cSrcweir                 if( nBorder + nColFuzzy >= pCurr->first )
1179cdf0e10cSrcweir                 {
1180cdf0e10cSrcweir                     if( pCurr->second == pCurr->first )
1181cdf0e10cSrcweir                         nRest = 0;
1182cdf0e10cSrcweir                     else
1183cdf0e10cSrcweir                         nRest = pCurr->second - nBorder;
1184cdf0e10cSrcweir                     nNewWidth += nRest;
1185cdf0e10cSrcweir                     ++pCurr;
1186cdf0e10cSrcweir                 }
1187cdf0e10cSrcweir             }
1188cdf0e10cSrcweir         }
1189cdf0e10cSrcweir         if( nNewWidth != nWidth )
1190cdf0e10cSrcweir         {
1191cdf0e10cSrcweir             if( nNewWidth < 0 )
1192cdf0e10cSrcweir             {
1193cdf0e10cSrcweir                 nRest += 1 - nNewWidth;
1194cdf0e10cSrcweir                 nNewWidth = 1;
1195cdf0e10cSrcweir             }
1196cdf0e10cSrcweir             SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
1197cdf0e10cSrcweir             aFmtFrmSize.SetWidth( nNewWidth );
1198cdf0e10cSrcweir             rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
1199cdf0e10cSrcweir         }
1200cdf0e10cSrcweir     }
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir 
lcl_CalcNewWidths(std::list<sal_uInt16> & rSpanPos,ChangeList & rChanges,SwTableLine * pLine,long nWish,long nWidth,bool bTop)1203cdf0e10cSrcweir static void lcl_CalcNewWidths( std::list<sal_uInt16> &rSpanPos, ChangeList& rChanges,
1204cdf0e10cSrcweir     SwTableLine* pLine, long nWish, long nWidth, bool bTop )
1205cdf0e10cSrcweir {
1206cdf0e10cSrcweir     if( !rChanges.size() )
1207cdf0e10cSrcweir     {
1208cdf0e10cSrcweir         rSpanPos.clear();
1209cdf0e10cSrcweir         return;
1210cdf0e10cSrcweir     }
1211cdf0e10cSrcweir     if( !rSpanPos.size() )
1212cdf0e10cSrcweir     {
1213cdf0e10cSrcweir         rChanges.clear();
1214cdf0e10cSrcweir         return;
1215cdf0e10cSrcweir     }
1216cdf0e10cSrcweir     std::list<sal_uInt16> aNewSpanPos;
1217cdf0e10cSrcweir     ChangeList aNewChanges;
1218cdf0e10cSrcweir     ChangeList::iterator pCurr = rChanges.begin();
1219cdf0e10cSrcweir     aNewChanges.push_back( *pCurr ); // Nullposition
1220cdf0e10cSrcweir     std::list<sal_uInt16>::iterator pSpan = rSpanPos.begin();
1221cdf0e10cSrcweir     sal_uInt16 nCurr = 0;
1222cdf0e10cSrcweir     sal_uInt16 nOrgSum = 0;
1223cdf0e10cSrcweir     bool bRowSpan = false;
1224cdf0e10cSrcweir     sal_uInt16 nRowSpanCount = 0;
1225cdf0e10cSrcweir     sal_uInt16 nCount = pLine->GetTabBoxes().Count();
1226cdf0e10cSrcweir     for( sal_uInt16 nCurrBox = 0; nCurrBox < nCount; ++nCurrBox )
1227cdf0e10cSrcweir     {
1228cdf0e10cSrcweir         SwTableBox* pBox = pLine->GetTabBoxes()[nCurrBox];
1229cdf0e10cSrcweir         SwTwips nCurrWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
1230cdf0e10cSrcweir         const long nRowSpan = pBox->getRowSpan();
1231cdf0e10cSrcweir         const bool bCurrRowSpan = bTop ? nRowSpan < 0 :
1232cdf0e10cSrcweir             ( nRowSpan > 1 || nRowSpan < -1 );
1233cdf0e10cSrcweir         if( bRowSpan || bCurrRowSpan )
1234cdf0e10cSrcweir             aNewSpanPos.push_back( nRowSpanCount );
1235cdf0e10cSrcweir         bRowSpan = bCurrRowSpan;
1236cdf0e10cSrcweir         nOrgSum = (sal_uInt16)(nOrgSum + nCurrWidth);
1237cdf0e10cSrcweir         sal_uInt64 nSum = nOrgSum;
1238cdf0e10cSrcweir         nSum *= nWidth;
1239cdf0e10cSrcweir         nSum /= nWish;
1240cdf0e10cSrcweir         nSum *= nWish;
1241cdf0e10cSrcweir         nSum /= nWidth;
1242cdf0e10cSrcweir         sal_uInt16 nPos = (sal_uInt16)nSum;
1243cdf0e10cSrcweir         while( pCurr != rChanges.end() && pCurr->first < nPos )
1244cdf0e10cSrcweir         {
1245cdf0e10cSrcweir #ifdef DBG_UTIL
1246cdf0e10cSrcweir             sal_uInt16 nTemp = pCurr->first;
1247cdf0e10cSrcweir             nTemp = pCurr->second;
1248cdf0e10cSrcweir #endif
1249cdf0e10cSrcweir             ++nCurr;
1250cdf0e10cSrcweir             ++pCurr;
1251cdf0e10cSrcweir         }
1252cdf0e10cSrcweir         bool bNew = true;
1253cdf0e10cSrcweir         if( pCurr != rChanges.end() && pCurr->first <= nPos &&
1254cdf0e10cSrcweir             pCurr->first != pCurr->second )
1255cdf0e10cSrcweir         {
1256cdf0e10cSrcweir             while( pSpan != rSpanPos.end() && *pSpan < nCurr )
1257cdf0e10cSrcweir                 ++pSpan;
1258cdf0e10cSrcweir             if( pSpan != rSpanPos.end() && *pSpan == nCurr )
1259cdf0e10cSrcweir             {
1260cdf0e10cSrcweir                 aNewChanges.push_back( *pCurr );
1261cdf0e10cSrcweir                 ++nRowSpanCount;
1262cdf0e10cSrcweir                 bNew = false;
1263cdf0e10cSrcweir             }
1264cdf0e10cSrcweir         }
1265cdf0e10cSrcweir         if( bNew )
1266cdf0e10cSrcweir         {
1267cdf0e10cSrcweir             ColChange aTmp( nPos, nPos );
1268cdf0e10cSrcweir             aNewChanges.push_back( aTmp );
1269cdf0e10cSrcweir             ++nRowSpanCount;
1270cdf0e10cSrcweir         }
1271cdf0e10cSrcweir     }
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir     pCurr = aNewChanges.begin();
1274cdf0e10cSrcweir     ChangeList::iterator pLast = pCurr;
1275cdf0e10cSrcweir     ChangeList::iterator pLeftMove = pCurr;
1276cdf0e10cSrcweir     while( pCurr != aNewChanges.end() )
1277cdf0e10cSrcweir     {
1278cdf0e10cSrcweir         if( pLeftMove == pCurr )
1279cdf0e10cSrcweir         {
1280cdf0e10cSrcweir             while( ++pLeftMove != aNewChanges.end() && pLeftMove->first <= pLeftMove->second )
1281cdf0e10cSrcweir                 ;
1282cdf0e10cSrcweir         }
1283cdf0e10cSrcweir         if( pCurr->second == pCurr->first )
1284cdf0e10cSrcweir         {
1285cdf0e10cSrcweir             if( pLeftMove != aNewChanges.end() && pCurr->second > pLeftMove->second )
1286cdf0e10cSrcweir             {
1287cdf0e10cSrcweir                 if( pLeftMove->first == pLast->first )
1288cdf0e10cSrcweir                     pCurr->second = pLeftMove->second;
1289cdf0e10cSrcweir                 else
1290cdf0e10cSrcweir                 {
1291cdf0e10cSrcweir                     sal_uInt64 nTmp = pCurr->first - pLast->first;
1292cdf0e10cSrcweir                     nTmp *= pLeftMove->second - pLast->second;
1293cdf0e10cSrcweir                     nTmp /= pLeftMove->first - pLast->first;
1294cdf0e10cSrcweir                     nTmp += pLast->second;
1295cdf0e10cSrcweir                     pCurr->second = (sal_uInt16)nTmp;
1296cdf0e10cSrcweir                 }
1297cdf0e10cSrcweir             }
1298cdf0e10cSrcweir             pLast = pCurr;
1299cdf0e10cSrcweir             ++pCurr;
1300cdf0e10cSrcweir         }
1301cdf0e10cSrcweir         else if( pCurr->second > pCurr->first )
1302cdf0e10cSrcweir         {
1303cdf0e10cSrcweir             pLast = pCurr;
1304cdf0e10cSrcweir             ++pCurr;
1305cdf0e10cSrcweir             ChangeList::iterator pNext = pCurr;
1306cdf0e10cSrcweir             while( pNext != pLeftMove && pNext->second == pNext->first &&
1307cdf0e10cSrcweir                 pNext->second < pLast->second )
1308cdf0e10cSrcweir                 ++pNext;
1309cdf0e10cSrcweir             while( pCurr != pNext )
1310cdf0e10cSrcweir             {
1311cdf0e10cSrcweir                 if( pNext == aNewChanges.end() || pNext->first == pLast->first )
1312cdf0e10cSrcweir                     pCurr->second = pLast->second;
1313cdf0e10cSrcweir                 else
1314cdf0e10cSrcweir                 {
1315cdf0e10cSrcweir                     sal_uInt64 nTmp = pCurr->first - pLast->first;
1316cdf0e10cSrcweir                     nTmp *= pNext->second - pLast->second;
1317cdf0e10cSrcweir                     nTmp /= pNext->first - pLast->first;
1318cdf0e10cSrcweir                     nTmp += pLast->second;
1319cdf0e10cSrcweir                     pCurr->second = (sal_uInt16)nTmp;
1320cdf0e10cSrcweir                 }
1321cdf0e10cSrcweir                 ++pCurr;
1322cdf0e10cSrcweir             }
1323cdf0e10cSrcweir             pLast = pCurr;
1324cdf0e10cSrcweir         }
1325cdf0e10cSrcweir         else
1326cdf0e10cSrcweir         {
1327cdf0e10cSrcweir             pLast = pCurr;
1328cdf0e10cSrcweir             ++pCurr;
1329cdf0e10cSrcweir         }
1330cdf0e10cSrcweir     }
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir     rChanges.clear();
1333cdf0e10cSrcweir     ChangeList::iterator pCopy = aNewChanges.begin();
1334cdf0e10cSrcweir     while( pCopy != aNewChanges.end() )
1335cdf0e10cSrcweir         rChanges.push_back( *pCopy++ );
1336cdf0e10cSrcweir     rSpanPos.clear();
1337cdf0e10cSrcweir     std::list<sal_uInt16>::iterator pSpCopy = aNewSpanPos.begin();
1338cdf0e10cSrcweir     while( pSpCopy != aNewSpanPos.end() )
1339cdf0e10cSrcweir         rSpanPos.push_back( *pSpCopy++ );
1340cdf0e10cSrcweir }
1341cdf0e10cSrcweir 
NewSetTabCols(Parm & rParm,const SwTabCols & rNew,const SwTabCols & rOld,const SwTableBox * pStart,sal_Bool bCurRowOnly)1342cdf0e10cSrcweir void SwTable::NewSetTabCols( Parm &rParm, const SwTabCols &rNew,
1343cdf0e10cSrcweir     const SwTabCols &rOld, const SwTableBox *pStart, sal_Bool bCurRowOnly )
1344cdf0e10cSrcweir {
1345cdf0e10cSrcweir #ifdef DBG_UTIL
1346cdf0e10cSrcweir     static int nCallCount = 0;
1347cdf0e10cSrcweir     ++nCallCount;
1348cdf0e10cSrcweir #endif
1349cdf0e10cSrcweir     // First step: evaluate which lines have been moved/which widths changed
1350cdf0e10cSrcweir     ChangeList aOldNew;
1351cdf0e10cSrcweir     const long nNewWidth = rParm.rNew.GetRight() - rParm.rNew.GetLeft();
1352cdf0e10cSrcweir     const long nOldWidth = rParm.rOld.GetRight() - rParm.rOld.GetLeft();
1353cdf0e10cSrcweir     if( nNewWidth < 1 || nOldWidth < 1 )
1354cdf0e10cSrcweir         return;
1355cdf0e10cSrcweir     for( sal_uInt16 i = 0; i <= rOld.Count(); ++i )
1356cdf0e10cSrcweir     {
1357cdf0e10cSrcweir         sal_uInt64 nNewPos;
1358cdf0e10cSrcweir         sal_uInt64 nOldPos;
1359cdf0e10cSrcweir         if( i == rOld.Count() )
1360cdf0e10cSrcweir         {
1361cdf0e10cSrcweir             nOldPos = rParm.rOld.GetRight() - rParm.rOld.GetLeft();
1362cdf0e10cSrcweir             nNewPos = rParm.rNew.GetRight() - rParm.rNew.GetLeft();
1363cdf0e10cSrcweir         }
1364cdf0e10cSrcweir         else
1365cdf0e10cSrcweir         {
1366cdf0e10cSrcweir             nOldPos = rOld[i] - rParm.rOld.GetLeft();
1367cdf0e10cSrcweir             nNewPos = rNew[i] - rParm.rNew.GetLeft();
1368cdf0e10cSrcweir         }
1369cdf0e10cSrcweir         nNewPos *= rParm.nNewWish;
1370cdf0e10cSrcweir         nNewPos /= nNewWidth;
1371cdf0e10cSrcweir         nOldPos *= rParm.nOldWish;
1372cdf0e10cSrcweir         nOldPos /= nOldWidth;
1373cdf0e10cSrcweir         if( nOldPos != nNewPos && nNewPos > 0 && nOldPos > 0 )
1374cdf0e10cSrcweir         {
1375cdf0e10cSrcweir             ColChange aChg( (sal_uInt16)nOldPos, (sal_uInt16)nNewPos );
1376cdf0e10cSrcweir             aOldNew.push_back( aChg );
1377cdf0e10cSrcweir         }
1378cdf0e10cSrcweir     }
1379cdf0e10cSrcweir     // Finished first step
1380cdf0e10cSrcweir     int nCount = aOldNew.size();
1381cdf0e10cSrcweir     if( !nCount )
1382cdf0e10cSrcweir         return; // no change, nothing to do
1383cdf0e10cSrcweir     SwTableLines &rLines = GetTabLines();
1384cdf0e10cSrcweir     if( bCurRowOnly )
1385cdf0e10cSrcweir     {
1386cdf0e10cSrcweir         const SwTableLine* pCurrLine = pStart->GetUpper();
1387cdf0e10cSrcweir         sal_uInt16 nCurr = rLines.C40_GETPOS( SwTableLine, pCurrLine );
1388cdf0e10cSrcweir         if( nCurr >= USHRT_MAX )
1389cdf0e10cSrcweir             return;
1390cdf0e10cSrcweir 
1391cdf0e10cSrcweir         ColChange aChg( 0, 0 );
1392cdf0e10cSrcweir         aOldNew.push_front( aChg );
1393cdf0e10cSrcweir         std::list<sal_uInt16> aRowSpanPos;
1394cdf0e10cSrcweir         if( nCurr )
1395cdf0e10cSrcweir         {
1396cdf0e10cSrcweir             ChangeList aCopy;
1397cdf0e10cSrcweir             ChangeList::iterator pCop = aOldNew.begin();
1398cdf0e10cSrcweir             sal_uInt16 nPos = 0;
1399cdf0e10cSrcweir             while( pCop != aOldNew.end() )
1400cdf0e10cSrcweir             {
1401cdf0e10cSrcweir                 aCopy.push_back( *pCop );
1402cdf0e10cSrcweir                 ++pCop;
1403cdf0e10cSrcweir                 aRowSpanPos.push_back( nPos++ );
1404cdf0e10cSrcweir             }
1405cdf0e10cSrcweir             lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[nCurr],
1406cdf0e10cSrcweir                 rParm.nOldWish, nOldWidth, true );
1407cdf0e10cSrcweir             bool bGoOn = aRowSpanPos.size() > 0;
1408cdf0e10cSrcweir             sal_uInt16 j = nCurr;
1409cdf0e10cSrcweir             while( bGoOn )
1410cdf0e10cSrcweir             {
1411cdf0e10cSrcweir                 lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[--j],
1412cdf0e10cSrcweir                     rParm.nOldWish, nOldWidth, true );
1413cdf0e10cSrcweir                 lcl_AdjustWidthsInLine( rLines[j], aCopy, rParm, 0 );
1414cdf0e10cSrcweir                 bGoOn = aRowSpanPos.size() > 0 && j > 0;
1415cdf0e10cSrcweir             };
1416cdf0e10cSrcweir             aRowSpanPos.clear();
1417cdf0e10cSrcweir         }
1418cdf0e10cSrcweir         if( nCurr+1 < rLines.Count() )
1419cdf0e10cSrcweir         {
1420cdf0e10cSrcweir             ChangeList aCopy;
1421cdf0e10cSrcweir             ChangeList::iterator pCop = aOldNew.begin();
1422cdf0e10cSrcweir             sal_uInt16 nPos = 0;
1423cdf0e10cSrcweir             while( pCop != aOldNew.end() )
1424cdf0e10cSrcweir             {
1425cdf0e10cSrcweir                 aCopy.push_back( *pCop );
1426cdf0e10cSrcweir                 ++pCop;
1427cdf0e10cSrcweir                 aRowSpanPos.push_back( nPos++ );
1428cdf0e10cSrcweir             }
1429cdf0e10cSrcweir             lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[nCurr],
1430cdf0e10cSrcweir                 rParm.nOldWish, nOldWidth, false );
1431cdf0e10cSrcweir             bool bGoOn = aRowSpanPos.size() > 0;
1432cdf0e10cSrcweir             sal_uInt16 j = nCurr;
1433cdf0e10cSrcweir             while( bGoOn )
1434cdf0e10cSrcweir             {
1435cdf0e10cSrcweir                 lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[++j],
1436cdf0e10cSrcweir                     rParm.nOldWish, nOldWidth, false );
1437cdf0e10cSrcweir                 lcl_AdjustWidthsInLine( rLines[j], aCopy, rParm, 0 );
1438cdf0e10cSrcweir                 bGoOn = aRowSpanPos.size() > 0 && j+1 < rLines.Count();
1439cdf0e10cSrcweir             };
1440cdf0e10cSrcweir         }
1441cdf0e10cSrcweir         ::lcl_AdjustWidthsInLine( rLines[nCurr], aOldNew, rParm, 1 );
1442cdf0e10cSrcweir     }
1443cdf0e10cSrcweir     else for( sal_uInt16 i = 0; i < rLines.Count(); ++i )
1444cdf0e10cSrcweir         ::lcl_AdjustWidthsInLine( rLines[i], aOldNew, rParm, COLFUZZY );
1445cdf0e10cSrcweir     CHECK_TABLE( *this )
1446cdf0e10cSrcweir }
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir /*************************************************************************
1450cdf0e10cSrcweir |*
1451cdf0e10cSrcweir |*  const SwTableBox* SwTable::GetTblBox( const Strn?ng& rName ) const
1452cdf0e10cSrcweir |*      gebe den Pointer auf die benannte Box zurueck.
1453cdf0e10cSrcweir |*
1454cdf0e10cSrcweir |*************************************************************************/
1455cdf0e10cSrcweir 
IsValidRowName(const String & rStr)1456cdf0e10cSrcweir sal_Bool IsValidRowName( const String& rStr )
1457cdf0e10cSrcweir {
1458cdf0e10cSrcweir     sal_Bool bIsValid = sal_True;
1459cdf0e10cSrcweir     xub_StrLen nLen = rStr.Len();
1460cdf0e10cSrcweir     for (xub_StrLen i = 0;  i < nLen && bIsValid;  ++i)
1461cdf0e10cSrcweir     {
1462cdf0e10cSrcweir         const sal_Unicode cChar = rStr.GetChar(i);
1463cdf0e10cSrcweir         if (cChar < '0' || cChar > '9')
1464cdf0e10cSrcweir             bIsValid = sal_False;
1465cdf0e10cSrcweir     }
1466cdf0e10cSrcweir     return bIsValid;
1467cdf0e10cSrcweir }
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir // --> OD 2007-08-03 #i80314#
1470cdf0e10cSrcweir // add 3rd parameter and its handling
_GetBoxNum(String & rStr,sal_Bool bFirstPart,const bool bPerformValidCheck)1471cdf0e10cSrcweir sal_uInt16 SwTable::_GetBoxNum( String& rStr, sal_Bool bFirstPart,
1472cdf0e10cSrcweir                             const bool bPerformValidCheck )
1473cdf0e10cSrcweir {
1474cdf0e10cSrcweir     sal_uInt16 nRet = 0;
1475cdf0e10cSrcweir     xub_StrLen nPos = 0;
1476cdf0e10cSrcweir     if( bFirstPart )   // sal_True == column; sal_False == row
1477cdf0e10cSrcweir     {
1478cdf0e10cSrcweir         // die 1. ist mit Buchstaben addressiert!
1479cdf0e10cSrcweir         sal_Unicode cChar;
1480cdf0e10cSrcweir         sal_Bool bFirst = sal_True;
1481cdf0e10cSrcweir         while( 0 != ( cChar = rStr.GetChar( nPos )) &&
1482cdf0e10cSrcweir                ( (cChar >= 'A' && cChar <= 'Z') ||
1483cdf0e10cSrcweir                  (cChar >= 'a' && cChar <= 'z') ) )
1484cdf0e10cSrcweir         {
1485cdf0e10cSrcweir             if( (cChar -= 'A') >= 26 )
1486cdf0e10cSrcweir                 cChar -= 'a' - '[';
1487cdf0e10cSrcweir             if( bFirst )
1488cdf0e10cSrcweir                 bFirst = sal_False;
1489cdf0e10cSrcweir             else
1490cdf0e10cSrcweir                 ++nRet;
1491cdf0e10cSrcweir             nRet = nRet * 52 + cChar;
1492cdf0e10cSrcweir             ++nPos;
1493cdf0e10cSrcweir         }
1494cdf0e10cSrcweir         rStr.Erase( 0, nPos );      // Zeichen aus dem String loeschen
1495cdf0e10cSrcweir     }
1496cdf0e10cSrcweir     else if( STRING_NOTFOUND == ( nPos = rStr.Search( aDotStr ) ))
1497cdf0e10cSrcweir     {
1498cdf0e10cSrcweir         nRet = 0;
1499cdf0e10cSrcweir         if ( !bPerformValidCheck || IsValidRowName( rStr ) )
1500cdf0e10cSrcweir         {
1501cdf0e10cSrcweir             nRet = static_cast<sal_uInt16>(rStr.ToInt32());
1502cdf0e10cSrcweir         }
1503cdf0e10cSrcweir         rStr.Erase();
1504cdf0e10cSrcweir     }
1505cdf0e10cSrcweir     else
1506cdf0e10cSrcweir     {
1507cdf0e10cSrcweir         nRet = 0;
1508cdf0e10cSrcweir         String aTxt( rStr.Copy( 0, nPos ) );
1509cdf0e10cSrcweir         if ( !bPerformValidCheck || IsValidRowName( aTxt ) )
1510cdf0e10cSrcweir         {
1511cdf0e10cSrcweir             nRet = static_cast<sal_uInt16>(aTxt.ToInt32());
1512cdf0e10cSrcweir         }
1513cdf0e10cSrcweir         rStr.Erase( 0, nPos+1 );
1514cdf0e10cSrcweir     }
1515cdf0e10cSrcweir     return nRet;
1516cdf0e10cSrcweir }
1517cdf0e10cSrcweir // <--
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir // --> OD 2007-08-03 #i80314#
1520cdf0e10cSrcweir // add 2nd parameter and its handling
GetTblBox(const String & rName,const bool bPerformValidCheck) const1521cdf0e10cSrcweir const SwTableBox* SwTable::GetTblBox( const String& rName,
1522cdf0e10cSrcweir                                       const bool bPerformValidCheck ) const
1523cdf0e10cSrcweir {
1524cdf0e10cSrcweir     const SwTableBox* pBox = 0;
1525cdf0e10cSrcweir     const SwTableLine* pLine;
1526cdf0e10cSrcweir     const SwTableLines* pLines;
1527cdf0e10cSrcweir     const SwTableBoxes* pBoxes;
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir     sal_uInt16 nLine, nBox;
1530cdf0e10cSrcweir     String aNm( rName );
1531cdf0e10cSrcweir     while( aNm.Len() )
1532cdf0e10cSrcweir     {
1533cdf0e10cSrcweir         nBox = SwTable::_GetBoxNum( aNm, 0 == pBox, bPerformValidCheck );
1534cdf0e10cSrcweir         // erste Box ?
1535cdf0e10cSrcweir         if( !pBox )
1536cdf0e10cSrcweir             pLines = &GetTabLines();
1537cdf0e10cSrcweir         else
1538cdf0e10cSrcweir         {
1539cdf0e10cSrcweir             pLines = &pBox->GetTabLines();
1540cdf0e10cSrcweir             if( nBox )
1541cdf0e10cSrcweir                 --nBox;
1542cdf0e10cSrcweir         }
1543cdf0e10cSrcweir 
1544cdf0e10cSrcweir         nLine = SwTable::_GetBoxNum( aNm, sal_False, bPerformValidCheck );
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir         // bestimme die Line
1547cdf0e10cSrcweir         if( !nLine || nLine > pLines->Count() )
1548cdf0e10cSrcweir             return 0;
1549cdf0e10cSrcweir         pLine = (*pLines)[ nLine-1 ];
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir         // bestimme die Box
1552cdf0e10cSrcweir         pBoxes = &pLine->GetTabBoxes();
1553cdf0e10cSrcweir         if( nBox >= pBoxes->Count() )
1554cdf0e10cSrcweir             return 0;
1555cdf0e10cSrcweir         pBox = (*pBoxes)[ nBox ];
1556cdf0e10cSrcweir     }
1557cdf0e10cSrcweir 
1558cdf0e10cSrcweir     // abpruefen, ob die gefundene Box auch wirklich eine Inhaltstragende
1559cdf0e10cSrcweir     // Box ist ??
1560cdf0e10cSrcweir     if( pBox && !pBox->GetSttNd() )
1561cdf0e10cSrcweir     {
1562cdf0e10cSrcweir         ASSERT( sal_False, "Box ohne Inhalt, suche die naechste !!" );
1563cdf0e10cSrcweir         // "herunterfallen lassen" bis zur ersten Box
1564cdf0e10cSrcweir         while( pBox->GetTabLines().Count() )
1565cdf0e10cSrcweir             pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
1566cdf0e10cSrcweir     }
1567cdf0e10cSrcweir     return pBox;
1568cdf0e10cSrcweir }
1569cdf0e10cSrcweir 
GetTblBox(sal_uLong nSttIdx)1570cdf0e10cSrcweir SwTableBox* SwTable::GetTblBox( sal_uLong nSttIdx )
1571cdf0e10cSrcweir {
1572cdf0e10cSrcweir     //MA: Zur Optimierung nicht immer umstaendlich das ganze SortArray abhuenern.
1573cdf0e10cSrcweir     //OS: #102675# converting text to table tries und certain conditions
1574cdf0e10cSrcweir     // to ask for a table box of a table that is not yet having a format
1575cdf0e10cSrcweir     if(!GetFrmFmt())
1576cdf0e10cSrcweir         return 0;
1577cdf0e10cSrcweir     SwTableBox* pRet = 0;
1578cdf0e10cSrcweir     SwNodes& rNds = GetFrmFmt()->GetDoc()->GetNodes();
1579cdf0e10cSrcweir     sal_uLong nIndex = nSttIdx + 1;
1580cdf0e10cSrcweir     SwCntntNode* pCNd = 0;
1581cdf0e10cSrcweir     SwTableNode* pTblNd = 0;
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir     while ( nIndex < rNds.Count() )
1584cdf0e10cSrcweir     {
1585cdf0e10cSrcweir         pTblNd = rNds[ nIndex ]->GetTableNode();
1586cdf0e10cSrcweir         if ( pTblNd )
1587cdf0e10cSrcweir             break;
1588cdf0e10cSrcweir 
1589cdf0e10cSrcweir         pCNd = rNds[ nIndex ]->GetCntntNode();
1590cdf0e10cSrcweir         if ( pCNd )
1591cdf0e10cSrcweir             break;
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir         ++nIndex;
1594cdf0e10cSrcweir     }
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir     if ( pCNd || pTblNd )
1597cdf0e10cSrcweir     {
1598cdf0e10cSrcweir         SwModify* pModify = pCNd;
1599cdf0e10cSrcweir         // --> FME 2007-3-26 #144862# Better handling of table in table:
1600cdf0e10cSrcweir         if ( pTblNd && pTblNd->GetTable().GetFrmFmt() )
1601cdf0e10cSrcweir             pModify = pTblNd->GetTable().GetFrmFmt();
1602cdf0e10cSrcweir         // <--
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir         SwFrm* pFrm = SwIterator<SwFrm,SwModify>::FirstElement( *pModify );
1605cdf0e10cSrcweir         while ( pFrm && !pFrm->IsCellFrm() )
1606cdf0e10cSrcweir             pFrm = pFrm->GetUpper();
1607cdf0e10cSrcweir         if ( pFrm )
1608cdf0e10cSrcweir             pRet = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
1609cdf0e10cSrcweir     }
1610cdf0e10cSrcweir 
1611cdf0e10cSrcweir     //Falls es das Layout noch nicht gibt oder sonstwie etwas schieft geht.
1612cdf0e10cSrcweir     if ( !pRet )
1613cdf0e10cSrcweir     {
1614cdf0e10cSrcweir         for( sal_uInt16 n = aSortCntBoxes.Count(); n; )
1615cdf0e10cSrcweir             if( aSortCntBoxes[ --n ]->GetSttIdx() == nSttIdx )
1616cdf0e10cSrcweir                 return aSortCntBoxes[ n ];
1617cdf0e10cSrcweir     }
1618cdf0e10cSrcweir     return pRet;
1619cdf0e10cSrcweir }
1620cdf0e10cSrcweir 
IsTblComplex() const1621cdf0e10cSrcweir sal_Bool SwTable::IsTblComplex() const
1622cdf0e10cSrcweir {
1623cdf0e10cSrcweir     // returnt sal_True wenn sich in der Tabelle Verschachtelungen befinden
1624cdf0e10cSrcweir     // steht eine Box nicht in der obersten Line, da wurde gesplittet/
1625cdf0e10cSrcweir     // gemergt und die Struktur ist komplexer.
1626cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < aSortCntBoxes.Count(); ++n )
1627cdf0e10cSrcweir         if( aSortCntBoxes[ n ]->GetUpper()->GetUpper() )
1628cdf0e10cSrcweir             return sal_True;
1629cdf0e10cSrcweir     return sal_False;
1630cdf0e10cSrcweir }
1631cdf0e10cSrcweir 
1632cdf0e10cSrcweir 
1633cdf0e10cSrcweir 
1634cdf0e10cSrcweir /*************************************************************************
1635cdf0e10cSrcweir |*
1636cdf0e10cSrcweir |*  SwTableLine::SwTableLine()
1637cdf0e10cSrcweir |*
1638cdf0e10cSrcweir |*************************************************************************/
SwTableLine(SwTableLineFmt * pFmt,sal_uInt16 nBoxes,SwTableBox * pUp)1639cdf0e10cSrcweir SwTableLine::SwTableLine( SwTableLineFmt *pFmt, sal_uInt16 nBoxes,
1640cdf0e10cSrcweir                             SwTableBox *pUp )
1641cdf0e10cSrcweir     : SwClient( pFmt ),
1642cdf0e10cSrcweir     aBoxes( (sal_uInt8)nBoxes, 1 ),
1643cdf0e10cSrcweir     pUpper( pUp )
1644cdf0e10cSrcweir {
1645cdf0e10cSrcweir }
1646cdf0e10cSrcweir 
~SwTableLine()1647cdf0e10cSrcweir SwTableLine::~SwTableLine()
1648cdf0e10cSrcweir {
1649cdf0e10cSrcweir     // ist die TabelleLine der letzte Client im FrameFormat, kann dieses
1650cdf0e10cSrcweir     // geloescht werden
1651cdf0e10cSrcweir     SwModify* pMod = GetFrmFmt();
1652cdf0e10cSrcweir     pMod->Remove( this );               // austragen,
1653cdf0e10cSrcweir     if( !pMod->GetDepends() )
1654cdf0e10cSrcweir         delete pMod;    // und loeschen
1655cdf0e10cSrcweir }
1656cdf0e10cSrcweir 
1657cdf0e10cSrcweir /*************************************************************************
1658cdf0e10cSrcweir |*
1659cdf0e10cSrcweir |*  SwTableLine::ClaimFrmFmt(), ChgFrmFmt()
1660cdf0e10cSrcweir |*
1661cdf0e10cSrcweir |*************************************************************************/
ClaimFrmFmt()1662cdf0e10cSrcweir SwFrmFmt* SwTableLine::ClaimFrmFmt()
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir     // This method makes sure that this object is an exclusive SwTableLine client
1665cdf0e10cSrcweir     // of an SwTableLineFmt object
1666cdf0e10cSrcweir     // If other SwTableLine objects currently listen to the same SwTableLineFmt as
1667cdf0e10cSrcweir     // this one, something needs to be done
1668cdf0e10cSrcweir     SwTableLineFmt *pRet = (SwTableLineFmt*)GetFrmFmt();
1669cdf0e10cSrcweir     SwIterator<SwTableLine,SwFmt> aIter( *pRet );
1670cdf0e10cSrcweir     for( SwTableLine* pLast = aIter.First(); pLast; pLast = aIter.Next() )
1671cdf0e10cSrcweir     {
1672cdf0e10cSrcweir         if ( pLast != this )
1673cdf0e10cSrcweir         {
1674cdf0e10cSrcweir             // found another SwTableLine that is a client of the current Fmt
1675cdf0e10cSrcweir             // create a new Fmt as a copy and use it for this object
1676cdf0e10cSrcweir             SwTableLineFmt *pNewFmt = pRet->GetDoc()->MakeTableLineFmt();
1677cdf0e10cSrcweir             *pNewFmt = *pRet;
1678cdf0e10cSrcweir 
1679cdf0e10cSrcweir             // register SwRowFrms that know me as clients at the new Fmt
1680cdf0e10cSrcweir             SwIterator<SwRowFrm,SwFmt> aFrmIter( *pRet );
1681cdf0e10cSrcweir             for( SwRowFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
1682cdf0e10cSrcweir                 if( pFrm->GetTabLine() == this )
1683cdf0e10cSrcweir                     pFrm->RegisterToFormat( *pNewFmt );
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir             // register myself
1686cdf0e10cSrcweir             pNewFmt->Add( this );
1687cdf0e10cSrcweir             pRet = pNewFmt;
1688cdf0e10cSrcweir             break;
1689cdf0e10cSrcweir         }
1690cdf0e10cSrcweir     }
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir     return pRet;
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir 
ChgFrmFmt(SwTableLineFmt * pNewFmt)1695cdf0e10cSrcweir void SwTableLine::ChgFrmFmt( SwTableLineFmt *pNewFmt )
1696cdf0e10cSrcweir {
1697cdf0e10cSrcweir     SwFrmFmt *pOld = GetFrmFmt();
1698cdf0e10cSrcweir     SwIterator<SwRowFrm,SwFmt> aIter( *pOld );
1699cdf0e10cSrcweir 
1700cdf0e10cSrcweir     //Erstmal die Frms ummelden.
1701cdf0e10cSrcweir     for( SwRowFrm* pRow = aIter.First(); pRow; pRow = aIter.Next() )
1702cdf0e10cSrcweir     {
1703cdf0e10cSrcweir         if( pRow->GetTabLine() == this )
1704cdf0e10cSrcweir         {
1705cdf0e10cSrcweir             pRow->RegisterToFormat( *pNewFmt );
1706cdf0e10cSrcweir 
1707cdf0e10cSrcweir             pRow->InvalidateSize();
1708cdf0e10cSrcweir             pRow->_InvalidatePrt();
1709cdf0e10cSrcweir             pRow->SetCompletePaint();
1710cdf0e10cSrcweir             pRow->ReinitializeFrmSizeAttrFlags();
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir             // --> FME 2004-10-27 #i35063#
1713cdf0e10cSrcweir             // consider 'split row allowed' attribute
1714cdf0e10cSrcweir             SwTabFrm* pTab = pRow->FindTabFrm();
1715cdf0e10cSrcweir             bool bInFollowFlowRow = false;
1716cdf0e10cSrcweir             const bool bInFirstNonHeadlineRow = pTab->IsFollow() &&
1717cdf0e10cSrcweir                                                 pRow == pTab->GetFirstNonHeadlineRow();
1718cdf0e10cSrcweir             if ( bInFirstNonHeadlineRow ||
1719cdf0e10cSrcweir                  !pRow->GetNext() ||
1720cdf0e10cSrcweir                  0 != ( bInFollowFlowRow = pRow->IsInFollowFlowRow() ) ||
1721cdf0e10cSrcweir                  0 != pRow->IsInSplitTableRow() )
1722cdf0e10cSrcweir             {
1723cdf0e10cSrcweir                 if ( bInFirstNonHeadlineRow || bInFollowFlowRow )
1724cdf0e10cSrcweir                     pTab = pTab->FindMaster();
1725cdf0e10cSrcweir 
1726cdf0e10cSrcweir                 pTab->SetRemoveFollowFlowLinePending( sal_True );
1727cdf0e10cSrcweir                 pTab->InvalidatePos();
1728cdf0e10cSrcweir             }
1729cdf0e10cSrcweir             // <--
1730cdf0e10cSrcweir         }
1731cdf0e10cSrcweir     }
1732cdf0e10cSrcweir 
1733cdf0e10cSrcweir     //Jetzt noch mich selbst ummelden.
1734cdf0e10cSrcweir     pNewFmt->Add( this );
1735cdf0e10cSrcweir 
1736cdf0e10cSrcweir     if ( !pOld->GetDepends() )
1737cdf0e10cSrcweir         delete pOld;
1738cdf0e10cSrcweir }
1739cdf0e10cSrcweir 
GetTableLineHeight(bool & bLayoutAvailable) const1740cdf0e10cSrcweir SwTwips SwTableLine::GetTableLineHeight( bool& bLayoutAvailable ) const
1741cdf0e10cSrcweir {
1742cdf0e10cSrcweir     SwTwips nRet = 0;
1743cdf0e10cSrcweir     bLayoutAvailable = false;
1744cdf0e10cSrcweir     SwIterator<SwRowFrm,SwFmt> aIter( *GetFrmFmt() );
1745cdf0e10cSrcweir     // A row could appear several times in headers/footers so only one chain of master/follow tables
1746cdf0e10cSrcweir     // will be accepted...
1747cdf0e10cSrcweir     const SwTabFrm* pChain = NULL; // My chain
1748cdf0e10cSrcweir     for( SwRowFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
1749cdf0e10cSrcweir     {
1750cdf0e10cSrcweir         if( pLast->GetTabLine() == this )
1751cdf0e10cSrcweir         {
1752cdf0e10cSrcweir             const SwTabFrm* pTab = pLast->FindTabFrm();
1753cdf0e10cSrcweir             bLayoutAvailable = ( pTab && pTab->IsVertical() ) ?
1754cdf0e10cSrcweir                                ( 0 < pTab->Frm().Height() ) :
1755cdf0e10cSrcweir                                ( 0 < pTab->Frm().Width() );
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir             // The first one defines the chain, if a chain is defined, only members of the chain
1758cdf0e10cSrcweir             // will be added.
1759cdf0e10cSrcweir             if( !pChain || pChain->IsAnFollow( pTab ) || pTab->IsAnFollow( pChain ) )
1760cdf0e10cSrcweir             {
1761cdf0e10cSrcweir                 pChain = pTab; // defines my chain (even it is already)
1762cdf0e10cSrcweir                 if( pTab->IsVertical() )
1763cdf0e10cSrcweir                     nRet += pLast->Frm().Width();
1764cdf0e10cSrcweir                 else
1765cdf0e10cSrcweir                     nRet += pLast->Frm().Height();
1766cdf0e10cSrcweir                 // Optimization, if there are no master/follows in my chain, nothing more to add
1767cdf0e10cSrcweir                 if( !pTab->HasFollow() && !pTab->IsFollow() )
1768cdf0e10cSrcweir                     break;
1769cdf0e10cSrcweir                 // This is not an optimization, this is necessary to avoid double additions of
1770cdf0e10cSrcweir                 // repeating rows
1771cdf0e10cSrcweir                 if( pTab->IsInHeadline(*pLast) )
1772cdf0e10cSrcweir                     break;
1773cdf0e10cSrcweir             }
1774cdf0e10cSrcweir         }
1775cdf0e10cSrcweir     }
1776cdf0e10cSrcweir     return nRet;
1777cdf0e10cSrcweir }
1778cdf0e10cSrcweir 
1779cdf0e10cSrcweir /*************************************************************************
1780cdf0e10cSrcweir |*
1781cdf0e10cSrcweir |*  SwTableBox::SwTableBox()
1782cdf0e10cSrcweir |*
1783cdf0e10cSrcweir |*************************************************************************/
SwTableBox(SwTableBoxFmt * pFmt,sal_uInt16 nLines,SwTableLine * pUp)1784cdf0e10cSrcweir SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, sal_uInt16 nLines, SwTableLine *pUp )
1785cdf0e10cSrcweir     : SwClient( 0 ),
1786cdf0e10cSrcweir     aLines( (sal_uInt8)nLines, 1 ),
1787cdf0e10cSrcweir     pSttNd( 0 ),
1788cdf0e10cSrcweir     pUpper( pUp ),
1789cdf0e10cSrcweir     pImpl( 0 )
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir     CheckBoxFmt( pFmt )->Add( this );
1792cdf0e10cSrcweir }
1793cdf0e10cSrcweir 
SwTableBox(SwTableBoxFmt * pFmt,const SwNodeIndex & rIdx,SwTableLine * pUp)1794cdf0e10cSrcweir SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwNodeIndex &rIdx,
1795cdf0e10cSrcweir                         SwTableLine *pUp )
1796cdf0e10cSrcweir     : SwClient( 0 ),
1797cdf0e10cSrcweir     aLines( 0, 0 ),
1798cdf0e10cSrcweir     pUpper( pUp ),
1799cdf0e10cSrcweir     pImpl( 0 )
1800cdf0e10cSrcweir {
1801cdf0e10cSrcweir     CheckBoxFmt( pFmt )->Add( this );
1802cdf0e10cSrcweir 
1803cdf0e10cSrcweir     pSttNd = rIdx.GetNode().GetStartNode();
1804cdf0e10cSrcweir 
1805cdf0e10cSrcweir     // an der Table eintragen
1806cdf0e10cSrcweir     const SwTableNode* pTblNd = pSttNd->FindTableNode();
1807cdf0e10cSrcweir     ASSERT( pTblNd, "in welcher Tabelle steht denn die Box?" );
1808cdf0e10cSrcweir     SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
1809cdf0e10cSrcweir                                 GetTabSortBoxes();
1810cdf0e10cSrcweir     SwTableBox* p = this;   // error: &this
1811cdf0e10cSrcweir     rSrtArr.Insert( p );        // eintragen
1812cdf0e10cSrcweir }
1813cdf0e10cSrcweir 
SwTableBox(SwTableBoxFmt * pFmt,const SwStartNode & rSttNd,SwTableLine * pUp)1814cdf0e10cSrcweir SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwStartNode& rSttNd, SwTableLine *pUp ) :
1815cdf0e10cSrcweir     SwClient( 0 ),
1816cdf0e10cSrcweir     aLines( 0, 0 ),
1817cdf0e10cSrcweir     pSttNd( &rSttNd ),
1818cdf0e10cSrcweir     pUpper( pUp ),
1819cdf0e10cSrcweir     pImpl( 0 )
1820cdf0e10cSrcweir {
1821cdf0e10cSrcweir     CheckBoxFmt( pFmt )->Add( this );
1822cdf0e10cSrcweir 
1823cdf0e10cSrcweir     // an der Table eintragen
1824cdf0e10cSrcweir     const SwTableNode* pTblNd = pSttNd->FindTableNode();
1825cdf0e10cSrcweir     ASSERT( pTblNd, "in welcher Tabelle steht denn die Box?" );
1826cdf0e10cSrcweir     SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
1827cdf0e10cSrcweir                                 GetTabSortBoxes();
1828cdf0e10cSrcweir     SwTableBox* p = this;   // error: &this
1829cdf0e10cSrcweir     rSrtArr.Insert( p );        // eintragen
1830cdf0e10cSrcweir }
1831cdf0e10cSrcweir 
~SwTableBox()1832cdf0e10cSrcweir SwTableBox::~SwTableBox()
1833cdf0e10cSrcweir {
1834cdf0e10cSrcweir     // Inhaltstragende Box ?
1835cdf0e10cSrcweir     if( !GetFrmFmt()->GetDoc()->IsInDtor() && pSttNd )
1836cdf0e10cSrcweir     {
1837cdf0e10cSrcweir         // an der Table austragen
1838cdf0e10cSrcweir         const SwTableNode* pTblNd = pSttNd->FindTableNode();
1839cdf0e10cSrcweir         ASSERT( pTblNd, "in welcher Tabelle steht denn die Box?" );
1840cdf0e10cSrcweir         SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
1841cdf0e10cSrcweir                                     GetTabSortBoxes();
1842cdf0e10cSrcweir         SwTableBox *p = this;   // error: &this
1843cdf0e10cSrcweir         rSrtArr.Remove( p );        // austragen
1844cdf0e10cSrcweir     }
1845cdf0e10cSrcweir 
1846cdf0e10cSrcweir     // ist die TabelleBox der letzte Client im FrameFormat, kann dieses
1847cdf0e10cSrcweir     // geloescht werden
1848cdf0e10cSrcweir     SwModify* pMod = GetFrmFmt();
1849cdf0e10cSrcweir     pMod->Remove( this );               // austragen,
1850cdf0e10cSrcweir     if( !pMod->GetDepends() )
1851cdf0e10cSrcweir         delete pMod;    // und loeschen
1852cdf0e10cSrcweir 
1853cdf0e10cSrcweir     delete pImpl;
1854cdf0e10cSrcweir }
1855cdf0e10cSrcweir 
CheckBoxFmt(SwTableBoxFmt * pFmt)1856cdf0e10cSrcweir SwTableBoxFmt* SwTableBox::CheckBoxFmt( SwTableBoxFmt* pFmt )
1857cdf0e10cSrcweir {
1858cdf0e10cSrcweir     // sollte das Format eine Formel oder einen Value tragen, dann muss die
1859cdf0e10cSrcweir     // Box alleine am Format haengen. Ggfs. muss ein neues angelegt werden.
1860cdf0e10cSrcweir     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) ||
1861cdf0e10cSrcweir         SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA, sal_False ) )
1862cdf0e10cSrcweir     {
1863cdf0e10cSrcweir         SwTableBox* pOther = SwIterator<SwTableBox,SwFmt>::FirstElement( *pFmt );
1864cdf0e10cSrcweir         if( pOther )
1865cdf0e10cSrcweir         {
1866cdf0e10cSrcweir             SwTableBoxFmt* pNewFmt = pFmt->GetDoc()->MakeTableBoxFmt();
1867cdf0e10cSrcweir             pNewFmt->LockModify();
1868cdf0e10cSrcweir             *pNewFmt = *pFmt;
1869cdf0e10cSrcweir 
1870cdf0e10cSrcweir             // Values und Formeln entfernen
1871cdf0e10cSrcweir             pNewFmt->ResetFmtAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
1872cdf0e10cSrcweir             pNewFmt->UnlockModify();
1873cdf0e10cSrcweir 
1874cdf0e10cSrcweir             pFmt = pNewFmt;
1875cdf0e10cSrcweir         }
1876cdf0e10cSrcweir     }
1877cdf0e10cSrcweir     return pFmt;
1878cdf0e10cSrcweir }
1879cdf0e10cSrcweir 
1880cdf0e10cSrcweir /*************************************************************************
1881cdf0e10cSrcweir |*
1882cdf0e10cSrcweir |*  SwTableBox::ClaimFrmFmt(), ChgFrmFmt()
1883cdf0e10cSrcweir |*
1884cdf0e10cSrcweir |*************************************************************************/
ClaimFrmFmt()1885cdf0e10cSrcweir SwFrmFmt* SwTableBox::ClaimFrmFmt()
1886cdf0e10cSrcweir {
1887cdf0e10cSrcweir     // This method makes sure that this object is an exclusive SwTableBox client
1888cdf0e10cSrcweir     // of an SwTableBoxFmt object
1889cdf0e10cSrcweir     // If other SwTableBox objects currently listen to the same SwTableBoxFmt as
1890cdf0e10cSrcweir     // this one, something needs to be done
1891cdf0e10cSrcweir     SwTableBoxFmt *pRet = (SwTableBoxFmt*)GetFrmFmt();
1892cdf0e10cSrcweir     SwIterator<SwTableBox,SwFmt> aIter( *pRet );
1893cdf0e10cSrcweir     for( SwTableBox* pLast = aIter.First(); pLast; pLast = aIter.Next() )
1894cdf0e10cSrcweir     {
1895cdf0e10cSrcweir         if ( pLast != this )
1896cdf0e10cSrcweir         {
1897cdf0e10cSrcweir             // Found another SwTableBox object
1898cdf0e10cSrcweir             // create a new Fmt as a copy and assign me to it
1899cdf0e10cSrcweir             // don't copy values and formulas
1900cdf0e10cSrcweir             SwTableBoxFmt* pNewFmt = pRet->GetDoc()->MakeTableBoxFmt();
1901cdf0e10cSrcweir             pNewFmt->LockModify();
1902cdf0e10cSrcweir             *pNewFmt = *pRet;
1903cdf0e10cSrcweir             pNewFmt->ResetFmtAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
1904cdf0e10cSrcweir             pNewFmt->UnlockModify();
1905cdf0e10cSrcweir 
1906cdf0e10cSrcweir             // re-register SwCellFrm objects that know me
1907cdf0e10cSrcweir             SwIterator<SwCellFrm,SwFmt> aFrmIter( *pRet );
1908cdf0e10cSrcweir             for( SwCellFrm* pCell = aFrmIter.First(); pCell; pCell = aFrmIter.Next() )
1909cdf0e10cSrcweir                 if( pCell->GetTabBox() == this )
1910cdf0e10cSrcweir                     pCell->RegisterToFormat( *pNewFmt );
1911cdf0e10cSrcweir 
1912cdf0e10cSrcweir             // re-register myself
1913cdf0e10cSrcweir             pNewFmt->Add( this );
1914cdf0e10cSrcweir             pRet = pNewFmt;
1915cdf0e10cSrcweir             break;
1916cdf0e10cSrcweir         }
1917cdf0e10cSrcweir     }
1918cdf0e10cSrcweir     return pRet;
1919cdf0e10cSrcweir }
1920cdf0e10cSrcweir 
ChgFrmFmt(SwTableBoxFmt * pNewFmt)1921cdf0e10cSrcweir void SwTableBox::ChgFrmFmt( SwTableBoxFmt* pNewFmt )
1922cdf0e10cSrcweir {
1923cdf0e10cSrcweir     SwFrmFmt *pOld = GetFrmFmt();
1924cdf0e10cSrcweir     SwIterator<SwCellFrm,SwFmt> aIter( *pOld );
1925cdf0e10cSrcweir 
1926cdf0e10cSrcweir     //Erstmal die Frms ummelden.
1927cdf0e10cSrcweir     for( SwCellFrm* pCell = aIter.First(); pCell; pCell = aIter.Next() )
1928cdf0e10cSrcweir     {
1929cdf0e10cSrcweir         if( pCell->GetTabBox() == this )
1930cdf0e10cSrcweir         {
1931cdf0e10cSrcweir             pCell->RegisterToFormat( *pNewFmt );
1932cdf0e10cSrcweir             pCell->InvalidateSize();
1933cdf0e10cSrcweir             pCell->_InvalidatePrt();
1934cdf0e10cSrcweir             pCell->SetCompletePaint();
1935cdf0e10cSrcweir             pCell->SetDerivedVert( sal_False );
1936cdf0e10cSrcweir             pCell->CheckDirChange();
1937cdf0e10cSrcweir 
1938cdf0e10cSrcweir             // --> FME 2005-04-15 #i47489#
1939cdf0e10cSrcweir             // make sure that the row will be formatted, in order
1940cdf0e10cSrcweir             // to have the correct Get(Top|Bottom)MarginForLowers values
1941cdf0e10cSrcweir             // set at the row.
1942cdf0e10cSrcweir             const SwTabFrm* pTab = pCell->FindTabFrm();
1943cdf0e10cSrcweir             if ( pTab && pTab->IsCollapsingBorders() )
1944cdf0e10cSrcweir             {
1945cdf0e10cSrcweir                 SwFrm* pRow = pCell->GetUpper();
1946cdf0e10cSrcweir                 pRow->_InvalidateSize();
1947cdf0e10cSrcweir                 pRow->_InvalidatePrt();
1948cdf0e10cSrcweir             }
1949cdf0e10cSrcweir             // <--
1950cdf0e10cSrcweir         }
1951cdf0e10cSrcweir     }
1952cdf0e10cSrcweir 
1953cdf0e10cSrcweir     //Jetzt noch mich selbst ummelden.
1954cdf0e10cSrcweir     pNewFmt->Add( this );
1955cdf0e10cSrcweir 
1956cdf0e10cSrcweir     if( !pOld->GetDepends() )
1957cdf0e10cSrcweir         delete pOld;
1958cdf0e10cSrcweir }
1959cdf0e10cSrcweir 
1960cdf0e10cSrcweir /*************************************************************************
1961cdf0e10cSrcweir |*
1962cdf0e10cSrcweir |*  String SwTableBox::GetName() const
1963cdf0e10cSrcweir |*      gebe den Namen dieser Box zurueck. Dieser wird dynamisch bestimmt
1964cdf0e10cSrcweir |*      und ergibt sich aus der Position in den Lines/Boxen/Tabelle
1965cdf0e10cSrcweir |*
1966cdf0e10cSrcweir |*************************************************************************/
lcl_GetTblBoxColStr(sal_uInt16 nCol,String & rNm)1967cdf0e10cSrcweir void lcl_GetTblBoxColStr( sal_uInt16 nCol, String& rNm )
1968cdf0e10cSrcweir {
1969cdf0e10cSrcweir     const sal_uInt16 coDiff = 52;   // 'A'-'Z' 'a' - 'z'
1970cdf0e10cSrcweir     sal_uInt16 nCalc;
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir     do {
1973cdf0e10cSrcweir         nCalc = nCol % coDiff;
1974cdf0e10cSrcweir         if( nCalc >= 26 )
1975cdf0e10cSrcweir             rNm.Insert( sal_Unicode('a' - 26 + nCalc ), 0 );
1976cdf0e10cSrcweir         else
1977cdf0e10cSrcweir             rNm.Insert( sal_Unicode('A' + nCalc ), 0 );
1978cdf0e10cSrcweir 
1979cdf0e10cSrcweir         if( 0 == (nCol = nCol - nCalc) )
1980cdf0e10cSrcweir             break;
1981cdf0e10cSrcweir         nCol /= coDiff;
1982cdf0e10cSrcweir         --nCol;
1983cdf0e10cSrcweir     } while( 1 );
1984cdf0e10cSrcweir }
1985cdf0e10cSrcweir 
GetName() const1986cdf0e10cSrcweir String SwTableBox::GetName() const
1987cdf0e10cSrcweir {
1988cdf0e10cSrcweir     if( !pSttNd )       // keine Content Box ??
1989cdf0e10cSrcweir     {
1990cdf0e10cSrcweir         // die naechste erste Box suchen ??
1991cdf0e10cSrcweir         return aEmptyStr;
1992cdf0e10cSrcweir     }
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir     const SwTable& rTbl = pSttNd->FindTableNode()->GetTable();
1995cdf0e10cSrcweir     sal_uInt16 nPos;
1996cdf0e10cSrcweir     String sNm, sTmp;
1997cdf0e10cSrcweir     const SwTableBox* pBox = this;
1998cdf0e10cSrcweir     do {
1999cdf0e10cSrcweir         const SwTableBoxes* pBoxes = &pBox->GetUpper()->GetTabBoxes();
2000cdf0e10cSrcweir         const SwTableLine* pLine = pBox->GetUpper();
2001cdf0e10cSrcweir         // auf oberstere Ebene ?
2002cdf0e10cSrcweir         const SwTableLines* pLines = pLine->GetUpper()
2003cdf0e10cSrcweir                 ? &pLine->GetUpper()->GetTabLines() : &rTbl.GetTabLines();
2004cdf0e10cSrcweir 
2005cdf0e10cSrcweir         sTmp = String::CreateFromInt32( nPos = pLines->GetPos( pLine ) + 1 );
2006cdf0e10cSrcweir         if( sNm.Len() )
2007cdf0e10cSrcweir             sNm.Insert( aDotStr, 0 ).Insert( sTmp, 0 );
2008cdf0e10cSrcweir         else
2009cdf0e10cSrcweir             sNm = sTmp;
2010cdf0e10cSrcweir 
2011cdf0e10cSrcweir         sTmp = String::CreateFromInt32(( nPos = pBoxes->GetPos( pBox )) + 1 );
2012cdf0e10cSrcweir         if( 0 != ( pBox = pLine->GetUpper()) )
2013cdf0e10cSrcweir             sNm.Insert( aDotStr, 0 ).Insert( sTmp, 0 );
2014cdf0e10cSrcweir         else
2015cdf0e10cSrcweir             ::lcl_GetTblBoxColStr( nPos, sNm );
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir     } while( pBox );
2018cdf0e10cSrcweir     return sNm;
2019cdf0e10cSrcweir }
2020cdf0e10cSrcweir 
IsInHeadline(const SwTable * pTbl) const2021cdf0e10cSrcweir sal_Bool SwTableBox::IsInHeadline( const SwTable* pTbl ) const
2022cdf0e10cSrcweir {
2023cdf0e10cSrcweir     if( !GetUpper() )           // sollte nur beim Merge vorkommen.
2024cdf0e10cSrcweir         return sal_False;
2025cdf0e10cSrcweir 
2026cdf0e10cSrcweir     if( !pTbl )
2027cdf0e10cSrcweir         pTbl = &pSttNd->FindTableNode()->GetTable();
2028cdf0e10cSrcweir 
2029cdf0e10cSrcweir     const SwTableLine* pLine = GetUpper();
2030cdf0e10cSrcweir     while( pLine->GetUpper() )
2031cdf0e10cSrcweir         pLine = pLine->GetUpper()->GetUpper();
2032cdf0e10cSrcweir 
2033cdf0e10cSrcweir     // Headerline?
2034cdf0e10cSrcweir     return pTbl->GetTabLines()[ 0 ] == pLine;
2035cdf0e10cSrcweir }
2036cdf0e10cSrcweir 
2037cdf0e10cSrcweir #ifdef DBG_UTIL
2038cdf0e10cSrcweir 
GetSttIdx() const2039cdf0e10cSrcweir sal_uLong SwTableBox::GetSttIdx() const
2040cdf0e10cSrcweir {
2041cdf0e10cSrcweir     return pSttNd ? pSttNd->GetIndex() : 0;
2042cdf0e10cSrcweir }
2043cdf0e10cSrcweir #endif
2044cdf0e10cSrcweir 
2045cdf0e10cSrcweir     // erfrage vom Client Informationen
GetInfo(SfxPoolItem & rInfo) const2046cdf0e10cSrcweir sal_Bool SwTable::GetInfo( SfxPoolItem& rInfo ) const
2047cdf0e10cSrcweir {
2048cdf0e10cSrcweir     switch( rInfo.Which() )
2049cdf0e10cSrcweir     {
2050cdf0e10cSrcweir     case RES_AUTOFMT_DOCNODE:
2051cdf0e10cSrcweir     {
2052cdf0e10cSrcweir         const SwTableNode* pTblNode = GetTableNode();
2053cdf0e10cSrcweir         if( pTblNode && &pTblNode->GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
2054cdf0e10cSrcweir         {
2055cdf0e10cSrcweir             if ( aSortCntBoxes.Count() )
2056cdf0e10cSrcweir             {
2057cdf0e10cSrcweir                 SwNodeIndex aIdx( *aSortCntBoxes[ 0 ]->GetSttNd() );
2058cdf0e10cSrcweir                 ((SwAutoFmtGetDocNode&)rInfo).pCntntNode =
2059cdf0e10cSrcweir                                 GetFrmFmt()->GetDoc()->GetNodes().GoNext( &aIdx );
2060cdf0e10cSrcweir             }
2061cdf0e10cSrcweir             return sal_False;
2062cdf0e10cSrcweir         }
2063cdf0e10cSrcweir         break;
2064cdf0e10cSrcweir     }
2065cdf0e10cSrcweir     case RES_FINDNEARESTNODE:
2066cdf0e10cSrcweir         if( GetFrmFmt() && ((SwFmtPageDesc&)GetFrmFmt()->GetFmtAttr(
2067cdf0e10cSrcweir             RES_PAGEDESC )).GetPageDesc() &&
2068cdf0e10cSrcweir             aSortCntBoxes.Count() &&
2069cdf0e10cSrcweir             aSortCntBoxes[ 0 ]->GetSttNd()->GetNodes().IsDocNodes() )
2070cdf0e10cSrcweir             ((SwFindNearestNode&)rInfo).CheckNode( *
2071cdf0e10cSrcweir                 aSortCntBoxes[ 0 ]->GetSttNd()->FindTableNode() );
2072cdf0e10cSrcweir         break;
2073cdf0e10cSrcweir 
2074cdf0e10cSrcweir     case RES_CONTENT_VISIBLE:
2075cdf0e10cSrcweir         {
2076cdf0e10cSrcweir             ((SwPtrMsgPoolItem&)rInfo).pObject = SwIterator<SwFrm,SwFmt>::FirstElement( *GetFrmFmt() );
2077cdf0e10cSrcweir         }
2078cdf0e10cSrcweir         return sal_False;
2079cdf0e10cSrcweir     }
2080cdf0e10cSrcweir     return sal_True;
2081cdf0e10cSrcweir }
2082cdf0e10cSrcweir 
FindTable(SwFrmFmt const * const pFmt)2083cdf0e10cSrcweir SwTable * SwTable::FindTable( SwFrmFmt const*const pFmt )
2084cdf0e10cSrcweir {
2085cdf0e10cSrcweir     return (pFmt)
2086cdf0e10cSrcweir         ? SwIterator<SwTable,SwFmt>::FirstElement(*pFmt)
2087cdf0e10cSrcweir         : 0;
2088cdf0e10cSrcweir }
2089cdf0e10cSrcweir 
GetTableNode() const2090cdf0e10cSrcweir SwTableNode* SwTable::GetTableNode() const
2091cdf0e10cSrcweir {
2092cdf0e10cSrcweir     return GetTabSortBoxes().Count() ?
2093cdf0e10cSrcweir            (SwTableNode*)GetTabSortBoxes()[ 0 ]->GetSttNd()->FindTableNode() :
2094cdf0e10cSrcweir            pTableNode;
2095cdf0e10cSrcweir }
2096cdf0e10cSrcweir 
SetRefObject(SwServerObject * pObj)2097cdf0e10cSrcweir void SwTable::SetRefObject( SwServerObject* pObj )
2098cdf0e10cSrcweir {
2099cdf0e10cSrcweir     if( refObj.Is() )
2100cdf0e10cSrcweir         refObj->Closed();
2101cdf0e10cSrcweir 
2102cdf0e10cSrcweir     refObj = pObj;
2103cdf0e10cSrcweir }
2104cdf0e10cSrcweir 
2105cdf0e10cSrcweir 
SetHTMLTableLayout(SwHTMLTableLayout * p)2106cdf0e10cSrcweir void SwTable::SetHTMLTableLayout( SwHTMLTableLayout *p )
2107cdf0e10cSrcweir {
2108cdf0e10cSrcweir     delete pHTMLLayout;
2109cdf0e10cSrcweir     pHTMLLayout = p;
2110cdf0e10cSrcweir }
2111cdf0e10cSrcweir 
ChgTextToNum(SwTableBox & rBox,const String & rTxt,const Color * pCol,sal_Bool bChgAlign)2112cdf0e10cSrcweir void ChgTextToNum( SwTableBox& rBox, const String& rTxt, const Color* pCol,
2113cdf0e10cSrcweir                     sal_Bool bChgAlign )
2114cdf0e10cSrcweir {
2115cdf0e10cSrcweir     sal_uLong nNdPos = rBox.IsValidNumTxtNd( sal_True );
2116cdf0e10cSrcweir     ChgTextToNum( rBox,rTxt,pCol,bChgAlign,nNdPos);
2117cdf0e10cSrcweir }
ChgTextToNum(SwTableBox & rBox,const String & rTxt,const Color * pCol,sal_Bool bChgAlign,sal_uLong nNdPos)2118cdf0e10cSrcweir void ChgTextToNum( SwTableBox& rBox, const String& rTxt, const Color* pCol,
2119cdf0e10cSrcweir                     sal_Bool bChgAlign,sal_uLong nNdPos )
2120cdf0e10cSrcweir {
2121cdf0e10cSrcweir 
2122cdf0e10cSrcweir     if( ULONG_MAX != nNdPos )
2123cdf0e10cSrcweir     {
2124cdf0e10cSrcweir         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
2125cdf0e10cSrcweir         SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
2126cdf0e10cSrcweir         const SfxPoolItem* pItem;
2127cdf0e10cSrcweir 
2128cdf0e10cSrcweir         // Ausrichtung umsetzen
2129cdf0e10cSrcweir         if( bChgAlign )
2130cdf0e10cSrcweir         {
2131cdf0e10cSrcweir             pItem = &pTNd->SwCntntNode::GetAttr( RES_PARATR_ADJUST );
2132cdf0e10cSrcweir             SvxAdjust eAdjust = ((SvxAdjustItem*)pItem)->GetAdjust();
2133cdf0e10cSrcweir             if( SVX_ADJUST_LEFT == eAdjust || SVX_ADJUST_BLOCK == eAdjust )
2134cdf0e10cSrcweir             {
2135cdf0e10cSrcweir                 SvxAdjustItem aAdjust( *(SvxAdjustItem*)pItem );
2136cdf0e10cSrcweir                 aAdjust.SetAdjust( SVX_ADJUST_RIGHT );
2137cdf0e10cSrcweir                 pTNd->SetAttr( aAdjust );
2138cdf0e10cSrcweir             }
2139cdf0e10cSrcweir         }
2140cdf0e10cSrcweir 
2141cdf0e10cSrcweir         // Farbe umsetzen oder "Benutzer Farbe" sichern
2142cdf0e10cSrcweir         if( !pTNd->GetpSwAttrSet() || SFX_ITEM_SET != pTNd->GetpSwAttrSet()->
2143cdf0e10cSrcweir             GetItemState( RES_CHRATR_COLOR, sal_False, &pItem ))
2144cdf0e10cSrcweir             pItem = 0;
2145cdf0e10cSrcweir 
2146cdf0e10cSrcweir         const Color* pOldNumFmtColor = rBox.GetSaveNumFmtColor();
2147cdf0e10cSrcweir         const Color* pNewUserColor = pItem ? &((SvxColorItem*)pItem)->GetValue() : 0;
2148cdf0e10cSrcweir 
2149cdf0e10cSrcweir         if( ( pNewUserColor && pOldNumFmtColor &&
2150cdf0e10cSrcweir                 *pNewUserColor == *pOldNumFmtColor ) ||
2151cdf0e10cSrcweir             ( !pNewUserColor && !pOldNumFmtColor ))
2152cdf0e10cSrcweir         {
2153cdf0e10cSrcweir             // User Color nicht veraendern aktuellen Werte setzen
2154cdf0e10cSrcweir             // ggfs. die alte NumFmtColor loeschen
2155cdf0e10cSrcweir             if( pCol )
2156cdf0e10cSrcweir                 // ggfs. die Farbe setzen
2157cdf0e10cSrcweir                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
2158cdf0e10cSrcweir             else if( pItem )
2159cdf0e10cSrcweir             {
2160cdf0e10cSrcweir                 pNewUserColor = rBox.GetSaveUserColor();
2161cdf0e10cSrcweir                 if( pNewUserColor )
2162cdf0e10cSrcweir                     pTNd->SetAttr( SvxColorItem( *pNewUserColor, RES_CHRATR_COLOR ));
2163cdf0e10cSrcweir                 else
2164cdf0e10cSrcweir                     pTNd->ResetAttr( RES_CHRATR_COLOR );
2165cdf0e10cSrcweir             }
2166cdf0e10cSrcweir         }
2167cdf0e10cSrcweir         else
2168cdf0e10cSrcweir         {
2169cdf0e10cSrcweir             // User Color merken, ggfs. die NumFormat Color setzen, aber
2170cdf0e10cSrcweir             // nie die Farbe zurueck setzen
2171cdf0e10cSrcweir             rBox.SetSaveUserColor( pNewUserColor );
2172cdf0e10cSrcweir 
2173cdf0e10cSrcweir             if( pCol )
2174cdf0e10cSrcweir                 // ggfs. die Farbe setzen
2175cdf0e10cSrcweir                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
2176cdf0e10cSrcweir 
2177cdf0e10cSrcweir         }
2178cdf0e10cSrcweir         rBox.SetSaveNumFmtColor( pCol );
2179cdf0e10cSrcweir 
2180cdf0e10cSrcweir         if( pTNd->GetTxt() != rTxt )
2181cdf0e10cSrcweir         {
2182cdf0e10cSrcweir             // Text austauschen
2183cdf0e10cSrcweir             //JP 15.09.98: Bug 55741 - Tabs beibehalten (vorne und hinten!)
2184cdf0e10cSrcweir             const String& rOrig = pTNd->GetTxt();
2185cdf0e10cSrcweir             xub_StrLen n;
2186cdf0e10cSrcweir 
2187cdf0e10cSrcweir             for( n = 0; n < rOrig.Len() && '\x9' == rOrig.GetChar( n ); ++n )
2188cdf0e10cSrcweir                 ;
2189cdf0e10cSrcweir             for( ; n < rOrig.Len() && '\x01' == rOrig.GetChar( n ); ++n )
2190cdf0e10cSrcweir                 ;
2191cdf0e10cSrcweir             SwIndex aIdx( pTNd, n );
2192cdf0e10cSrcweir             for( n = rOrig.Len(); n && '\x9' == rOrig.GetChar( --n ); )
2193cdf0e10cSrcweir                 ;
2194cdf0e10cSrcweir             n -= aIdx.GetIndex() - 1;
2195cdf0e10cSrcweir 
2196cdf0e10cSrcweir             //JP 06.04.99: Bug 64321 - DontExpand-Flags vorm Austauschen
2197cdf0e10cSrcweir             //             zuruecksetzen, damit sie wieder aufgespannt werden
2198cdf0e10cSrcweir             {
2199cdf0e10cSrcweir                 SwIndex aResetIdx( aIdx, n );
2200cdf0e10cSrcweir                 pTNd->DontExpandFmt( aResetIdx, sal_False, sal_False );
2201cdf0e10cSrcweir             }
2202cdf0e10cSrcweir 
2203cdf0e10cSrcweir             if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
2204cdf0e10cSrcweir             {
2205cdf0e10cSrcweir                 SwPaM aTemp(*pTNd, 0, *pTNd, rOrig.Len());
2206cdf0e10cSrcweir                 pDoc->DeleteRedline(aTemp, true, USHRT_MAX);
2207cdf0e10cSrcweir             }
2208cdf0e10cSrcweir 
2209cdf0e10cSrcweir             pTNd->EraseText( aIdx, n,
2210cdf0e10cSrcweir                     IDocumentContentOperations::INS_EMPTYEXPAND );
2211cdf0e10cSrcweir             pTNd->InsertText( rTxt, aIdx,
2212cdf0e10cSrcweir                     IDocumentContentOperations::INS_EMPTYEXPAND );
2213cdf0e10cSrcweir 
2214cdf0e10cSrcweir             if( pDoc->IsRedlineOn() )
2215cdf0e10cSrcweir             {
2216cdf0e10cSrcweir                 SwPaM aTemp(*pTNd, 0, *pTNd, rTxt.Len());
2217cdf0e10cSrcweir                 pDoc->AppendRedline(new SwRedline(nsRedlineType_t::REDLINE_INSERT, aTemp), true);
2218cdf0e10cSrcweir             }
2219cdf0e10cSrcweir         }
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir         // vertikale Ausrichtung umsetzen
2222cdf0e10cSrcweir         if( bChgAlign &&
2223cdf0e10cSrcweir             ( SFX_ITEM_SET != rBox.GetFrmFmt()->GetItemState(
2224cdf0e10cSrcweir                 RES_VERT_ORIENT, sal_True, &pItem ) ||
2225cdf0e10cSrcweir                 text::VertOrientation::TOP == ((SwFmtVertOrient*)pItem)->GetVertOrient() ))
2226cdf0e10cSrcweir         {
2227cdf0e10cSrcweir             rBox.GetFrmFmt()->SetFmtAttr( SwFmtVertOrient( 0, text::VertOrientation::BOTTOM ));
2228cdf0e10cSrcweir         }
2229cdf0e10cSrcweir     }
2230cdf0e10cSrcweir }
2231cdf0e10cSrcweir 
ChgNumToText(SwTableBox & rBox,sal_uLong nFmt)2232cdf0e10cSrcweir void ChgNumToText( SwTableBox& rBox, sal_uLong nFmt )
2233cdf0e10cSrcweir {
2234cdf0e10cSrcweir     sal_uLong nNdPos = rBox.IsValidNumTxtNd( sal_False );
2235cdf0e10cSrcweir     if( ULONG_MAX != nNdPos )
2236cdf0e10cSrcweir     {
2237cdf0e10cSrcweir         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
2238cdf0e10cSrcweir         SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
2239cdf0e10cSrcweir         sal_Bool bChgAlign = pDoc->IsInsTblAlignNum();
2240cdf0e10cSrcweir         const SfxPoolItem* pItem;
2241cdf0e10cSrcweir 
2242cdf0e10cSrcweir         Color* pCol = 0;
2243cdf0e10cSrcweir         if( NUMBERFORMAT_TEXT != nFmt )
2244cdf0e10cSrcweir         {
2245cdf0e10cSrcweir             // speziellen Textformat:
2246cdf0e10cSrcweir             String sTmp, sTxt( pTNd->GetTxt() );
2247cdf0e10cSrcweir             pDoc->GetNumberFormatter()->GetOutputString( sTxt, nFmt, sTmp, &pCol );
2248cdf0e10cSrcweir             if( sTxt != sTmp )
2249cdf0e10cSrcweir             {
2250cdf0e10cSrcweir                 // Text austauschen
2251cdf0e10cSrcweir                 SwIndex aIdx( pTNd, sTxt.Len() );
2252cdf0e10cSrcweir                 //JP 06.04.99: Bug 64321 - DontExpand-Flags vorm Austauschen
2253cdf0e10cSrcweir                 //             zuruecksetzen, damit sie wieder aufgespannt werden
2254cdf0e10cSrcweir                 pTNd->DontExpandFmt( aIdx, sal_False, sal_False );
2255cdf0e10cSrcweir                 aIdx = 0;
2256cdf0e10cSrcweir                 pTNd->EraseText( aIdx, STRING_LEN,
2257cdf0e10cSrcweir                         IDocumentContentOperations::INS_EMPTYEXPAND );
2258cdf0e10cSrcweir                 pTNd->InsertText( sTmp, aIdx,
2259cdf0e10cSrcweir                         IDocumentContentOperations::INS_EMPTYEXPAND );
2260cdf0e10cSrcweir             }
2261cdf0e10cSrcweir         }
2262cdf0e10cSrcweir 
2263cdf0e10cSrcweir         const SfxItemSet* pAttrSet = pTNd->GetpSwAttrSet();
2264cdf0e10cSrcweir 
2265cdf0e10cSrcweir         // Ausrichtung umsetzen
2266cdf0e10cSrcweir         if( bChgAlign && pAttrSet && SFX_ITEM_SET == pAttrSet->GetItemState(
2267cdf0e10cSrcweir             RES_PARATR_ADJUST, sal_False, &pItem ) &&
2268cdf0e10cSrcweir                 SVX_ADJUST_RIGHT == ((SvxAdjustItem*)pItem)->GetAdjust() )
2269cdf0e10cSrcweir         {
2270cdf0e10cSrcweir             pTNd->SetAttr( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) );
2271cdf0e10cSrcweir         }
2272cdf0e10cSrcweir 
2273cdf0e10cSrcweir         // Farbe umsetzen oder "Benutzer Farbe" sichern
2274cdf0e10cSrcweir         if( !pAttrSet || SFX_ITEM_SET != pAttrSet->
2275cdf0e10cSrcweir             GetItemState( RES_CHRATR_COLOR, sal_False, &pItem ))
2276cdf0e10cSrcweir             pItem = 0;
2277cdf0e10cSrcweir 
2278cdf0e10cSrcweir         const Color* pOldNumFmtColor = rBox.GetSaveNumFmtColor();
2279cdf0e10cSrcweir         const Color* pNewUserColor = pItem ? &((SvxColorItem*)pItem)->GetValue() : 0;
2280cdf0e10cSrcweir 
2281cdf0e10cSrcweir         if( ( pNewUserColor && pOldNumFmtColor &&
2282cdf0e10cSrcweir                 *pNewUserColor == *pOldNumFmtColor ) ||
2283cdf0e10cSrcweir             ( !pNewUserColor && !pOldNumFmtColor ))
2284cdf0e10cSrcweir         {
2285cdf0e10cSrcweir             // User Color nicht veraendern aktuellen Werte setzen
2286cdf0e10cSrcweir             // ggfs. die alte NumFmtColor loeschen
2287cdf0e10cSrcweir             if( pCol )
2288cdf0e10cSrcweir                 // ggfs. die Farbe setzen
2289cdf0e10cSrcweir                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
2290cdf0e10cSrcweir             else if( pItem )
2291cdf0e10cSrcweir             {
2292cdf0e10cSrcweir                 pNewUserColor = rBox.GetSaveUserColor();
2293cdf0e10cSrcweir                 if( pNewUserColor )
2294cdf0e10cSrcweir                     pTNd->SetAttr( SvxColorItem( *pNewUserColor, RES_CHRATR_COLOR ));
2295cdf0e10cSrcweir                 else
2296cdf0e10cSrcweir                     pTNd->ResetAttr( RES_CHRATR_COLOR );
2297cdf0e10cSrcweir             }
2298cdf0e10cSrcweir         }
2299cdf0e10cSrcweir         else
2300cdf0e10cSrcweir         {
2301cdf0e10cSrcweir             // User Color merken, ggfs. die NumFormat Color setzen, aber
2302cdf0e10cSrcweir             // nie die Farbe zurueck setzen
2303cdf0e10cSrcweir             rBox.SetSaveUserColor( pNewUserColor );
2304cdf0e10cSrcweir 
2305cdf0e10cSrcweir             if( pCol )
2306cdf0e10cSrcweir                 // ggfs. die Farbe setzen
2307cdf0e10cSrcweir                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
2308cdf0e10cSrcweir 
2309cdf0e10cSrcweir         }
2310cdf0e10cSrcweir         rBox.SetSaveNumFmtColor( pCol );
2311cdf0e10cSrcweir 
2312cdf0e10cSrcweir 
2313cdf0e10cSrcweir         // vertikale Ausrichtung umsetzen
2314cdf0e10cSrcweir         if( bChgAlign &&
2315cdf0e10cSrcweir             SFX_ITEM_SET == rBox.GetFrmFmt()->GetItemState(
2316cdf0e10cSrcweir             RES_VERT_ORIENT, sal_False, &pItem ) &&
2317cdf0e10cSrcweir             text::VertOrientation::BOTTOM == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
2318cdf0e10cSrcweir         {
2319cdf0e10cSrcweir             rBox.GetFrmFmt()->SetFmtAttr( SwFmtVertOrient( 0, text::VertOrientation::TOP ));
2320cdf0e10cSrcweir         }
2321cdf0e10cSrcweir     }
2322cdf0e10cSrcweir }
2323cdf0e10cSrcweir 
2324cdf0e10cSrcweir // zum Erkennen von Veraenderungen (haupts. TableBoxAttribute)
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2325cdf0e10cSrcweir void SwTableBoxFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
2326cdf0e10cSrcweir {
2327cdf0e10cSrcweir     if( !IsModifyLocked() && !IsInDocDTOR() )
2328cdf0e10cSrcweir     {
2329cdf0e10cSrcweir         const SwTblBoxNumFormat *pNewFmt = 0;
2330cdf0e10cSrcweir         const SwTblBoxFormula *pNewFml = 0;
2331cdf0e10cSrcweir         const SwTblBoxValue *pNewVal = 0;
2332cdf0e10cSrcweir         double aOldValue = 0;
2333cdf0e10cSrcweir         sal_uLong nOldFmt = NUMBERFORMAT_TEXT;
2334cdf0e10cSrcweir 
2335cdf0e10cSrcweir         switch( pNew ? pNew->Which() : 0 )
2336cdf0e10cSrcweir         {
2337cdf0e10cSrcweir         case RES_ATTRSET_CHG:
2338cdf0e10cSrcweir             {
2339cdf0e10cSrcweir                 const SfxItemSet& rSet = *((SwAttrSetChg*)pNew)->GetChgSet();
2340cdf0e10cSrcweir                 if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT,
2341cdf0e10cSrcweir                                     sal_False, (const SfxPoolItem**)&pNewFmt ) )
2342cdf0e10cSrcweir                     nOldFmt = ((SwTblBoxNumFormat&)((SwAttrSetChg*)pOld)->
2343cdf0e10cSrcweir                             GetChgSet()->Get( RES_BOXATR_FORMAT )).GetValue();
2344cdf0e10cSrcweir                 rSet.GetItemState( RES_BOXATR_FORMULA, sal_False,
2345cdf0e10cSrcweir                                     (const SfxPoolItem**)&pNewFml );
2346cdf0e10cSrcweir                 if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE,
2347cdf0e10cSrcweir                                     sal_False, (const SfxPoolItem**)&pNewVal ) )
2348cdf0e10cSrcweir                     aOldValue = ((SwTblBoxValue&)((SwAttrSetChg*)pOld)->
2349cdf0e10cSrcweir                             GetChgSet()->Get( RES_BOXATR_VALUE )).GetValue();
2350cdf0e10cSrcweir             }
2351cdf0e10cSrcweir             break;
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir         case RES_BOXATR_FORMAT:
2354cdf0e10cSrcweir             pNewFmt = (SwTblBoxNumFormat*)pNew;
2355cdf0e10cSrcweir             nOldFmt = ((SwTblBoxNumFormat*)pOld)->GetValue();
2356cdf0e10cSrcweir             break;
2357cdf0e10cSrcweir         case RES_BOXATR_FORMULA:
2358cdf0e10cSrcweir             pNewFml = (SwTblBoxFormula*)pNew;
2359cdf0e10cSrcweir             break;
2360cdf0e10cSrcweir         case RES_BOXATR_VALUE:
2361cdf0e10cSrcweir             pNewVal = (SwTblBoxValue*)pNew;
2362cdf0e10cSrcweir             aOldValue = ((SwTblBoxValue*)pOld)->GetValue();
2363cdf0e10cSrcweir             break;
2364cdf0e10cSrcweir         }
2365cdf0e10cSrcweir 
2366cdf0e10cSrcweir         // es hat sich etwas getan und im Set ist noch irgendein BoxAttribut
2367cdf0e10cSrcweir         // vorhanden!
2368cdf0e10cSrcweir         if( pNewFmt || pNewFml || pNewVal )
2369cdf0e10cSrcweir         {
2370cdf0e10cSrcweir             GetDoc()->SetFieldsDirty(true, NULL, 0);
2371cdf0e10cSrcweir 
2372cdf0e10cSrcweir             if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMAT, sal_False ) ||
2373cdf0e10cSrcweir                 SFX_ITEM_SET == GetItemState( RES_BOXATR_VALUE, sal_False ) ||
2374cdf0e10cSrcweir                 SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, sal_False ) )
2375cdf0e10cSrcweir             {
2376cdf0e10cSrcweir                 // die Box holen
2377cdf0e10cSrcweir                 SwIterator<SwTableBox,SwFmt> aIter( *this );
2378cdf0e10cSrcweir                 SwTableBox* pBox = aIter.First();
2379cdf0e10cSrcweir                 if( pBox )
2380cdf0e10cSrcweir                 {
2381cdf0e10cSrcweir                     ASSERT( !aIter.Next(), "keine Box oder mehrere am Format" );
2382cdf0e10cSrcweir 
2383cdf0e10cSrcweir                     sal_uLong nNewFmt;
2384cdf0e10cSrcweir                     if( pNewFmt )
2385cdf0e10cSrcweir                     {
2386cdf0e10cSrcweir                         nNewFmt = pNewFmt->GetValue();
2387cdf0e10cSrcweir                         // neu Formatieren
2388cdf0e10cSrcweir                         // ist es neuer oder wurde der akt. entfernt?
2389cdf0e10cSrcweir                         if( SFX_ITEM_SET != GetItemState( RES_BOXATR_VALUE, sal_False ))
2390cdf0e10cSrcweir                             pNewFmt = 0;
2391cdf0e10cSrcweir                     }
2392cdf0e10cSrcweir                     else
2393cdf0e10cSrcweir                     {
2394cdf0e10cSrcweir                         // das akt. Item besorgen
2395cdf0e10cSrcweir                         GetItemState( RES_BOXATR_FORMAT, sal_False,
2396cdf0e10cSrcweir                                             (const SfxPoolItem**)&pNewFmt );
2397cdf0e10cSrcweir                         nOldFmt = GetTblBoxNumFmt().GetValue();
2398cdf0e10cSrcweir                         nNewFmt = pNewFmt ? pNewFmt->GetValue() : nOldFmt;
2399cdf0e10cSrcweir                     }
2400cdf0e10cSrcweir 
2401cdf0e10cSrcweir                     // ist es neuer oder wurde der akt. entfernt?
2402cdf0e10cSrcweir                     if( pNewVal )
2403cdf0e10cSrcweir                     {
2404cdf0e10cSrcweir                         if( NUMBERFORMAT_TEXT != nNewFmt )
2405cdf0e10cSrcweir                         {
2406cdf0e10cSrcweir                             if( SFX_ITEM_SET == GetItemState(
2407cdf0e10cSrcweir                                                 RES_BOXATR_VALUE, sal_False ))
2408cdf0e10cSrcweir                                 nOldFmt = NUMBERFORMAT_TEXT;
2409cdf0e10cSrcweir                             else
2410cdf0e10cSrcweir                                 nNewFmt = NUMBERFORMAT_TEXT;
2411cdf0e10cSrcweir                         }
2412cdf0e10cSrcweir                         else if( NUMBERFORMAT_TEXT == nNewFmt )
2413cdf0e10cSrcweir                             nOldFmt = 0;
2414cdf0e10cSrcweir                     }
2415cdf0e10cSrcweir 
2416cdf0e10cSrcweir                     // Logik:
2417cdf0e10cSrcweir                     // ValueAenderung:  -> "simuliere" eine FormatAenderung!
2418cdf0e10cSrcweir                     // FormatAenderung:
2419cdf0e10cSrcweir                     // Text -> !Text oder FormatAenderung:
2420cdf0e10cSrcweir                     //          - Ausrichtung auf RECHTS, wenn LINKS oder Blocksatz
2421cdf0e10cSrcweir                     //          - vertikale Ausrichtung auf UNTEN wenn OBEN oder nicht
2422cdf0e10cSrcweir                     //              gesetzt ist.
2423cdf0e10cSrcweir                     //          - Text ersetzen (Farbe?? neg. Zahlen ROT??)
2424cdf0e10cSrcweir                     // !Text -> Text:
2425cdf0e10cSrcweir                     //          - Ausrichtung auf LINKS, wenn RECHTS
2426cdf0e10cSrcweir                     //          - vertikale Ausrichtung auf OEBN, wenn UNTEN gesetzt ist
2427cdf0e10cSrcweir 
2428cdf0e10cSrcweir                     SvNumberFormatter* pNumFmtr = GetDoc()->GetNumberFormatter();
2429cdf0e10cSrcweir                     sal_Bool bNewIsTxtFmt = pNumFmtr->IsTextFormat( nNewFmt ) ||
2430cdf0e10cSrcweir                                         NUMBERFORMAT_TEXT == nNewFmt;
2431cdf0e10cSrcweir 
2432cdf0e10cSrcweir                     if( (!bNewIsTxtFmt && nOldFmt != nNewFmt) || pNewFml )
2433cdf0e10cSrcweir                     {
2434cdf0e10cSrcweir                         sal_Bool bChgTxt = sal_True;
2435cdf0e10cSrcweir                         double fVal = 0;
2436cdf0e10cSrcweir                         if( !pNewVal && SFX_ITEM_SET != GetItemState(
2437cdf0e10cSrcweir                             RES_BOXATR_VALUE, sal_False, (const SfxPoolItem**)&pNewVal ))
2438cdf0e10cSrcweir                         {
2439cdf0e10cSrcweir                             // es wurde noch nie ein Wert gesetzt, dann versuche
2440cdf0e10cSrcweir                             // doch mal den Inhalt auszuwerten
2441cdf0e10cSrcweir                             sal_uLong nNdPos = pBox->IsValidNumTxtNd( sal_True );
2442cdf0e10cSrcweir                             if( ULONG_MAX != nNdPos )
2443cdf0e10cSrcweir                             {
2444cdf0e10cSrcweir                                 sal_uInt32 nTmpFmtIdx = nNewFmt;
2445cdf0e10cSrcweir                                 String aTxt( GetDoc()->GetNodes()[ nNdPos ]
2446cdf0e10cSrcweir                                                 ->GetTxtNode()->GetRedlineTxt());
2447cdf0e10cSrcweir                                 if( !aTxt.Len() )
2448cdf0e10cSrcweir                                     bChgTxt = sal_False;
2449cdf0e10cSrcweir                                 else
2450cdf0e10cSrcweir                                 {
2451cdf0e10cSrcweir                                     //JP 15.09.98: Bug 55741 - Tabs beibehalten
2452cdf0e10cSrcweir                                     lcl_TabToBlankAtSttEnd( aTxt );
2453cdf0e10cSrcweir 
2454cdf0e10cSrcweir                                     // JP 22.04.98: Bug 49659 -
2455cdf0e10cSrcweir                                     //          Sonderbehandlung fuer Prozent
2456cdf0e10cSrcweir                                     sal_Bool bIsNumFmt = sal_False;
2457cdf0e10cSrcweir                                     if( NUMBERFORMAT_PERCENT ==
2458cdf0e10cSrcweir                                         pNumFmtr->GetType( nNewFmt ))
2459cdf0e10cSrcweir                                     {
2460cdf0e10cSrcweir                                         sal_uInt32 nTmpFmt = 0;
2461cdf0e10cSrcweir                                         if( pNumFmtr->IsNumberFormat(
2462cdf0e10cSrcweir                                                     aTxt, nTmpFmt, fVal ))
2463cdf0e10cSrcweir                                         {
2464cdf0e10cSrcweir                                             if( NUMBERFORMAT_NUMBER ==
2465cdf0e10cSrcweir                                                 pNumFmtr->GetType( nTmpFmt ))
2466cdf0e10cSrcweir                                                 aTxt += '%';
2467cdf0e10cSrcweir 
2468cdf0e10cSrcweir                                             bIsNumFmt = pNumFmtr->IsNumberFormat(
2469cdf0e10cSrcweir                                                         aTxt, nTmpFmtIdx, fVal );
2470cdf0e10cSrcweir                                         }
2471cdf0e10cSrcweir                                     }
2472cdf0e10cSrcweir                                     else
2473cdf0e10cSrcweir                                         bIsNumFmt = pNumFmtr->IsNumberFormat(
2474cdf0e10cSrcweir                                                         aTxt, nTmpFmtIdx, fVal );
2475cdf0e10cSrcweir 
2476cdf0e10cSrcweir                                     if( bIsNumFmt )
2477cdf0e10cSrcweir                                     {
2478cdf0e10cSrcweir                                         // dann setze den Value direkt in den Set -
2479cdf0e10cSrcweir                                         // ohne Modify
2480cdf0e10cSrcweir                                         int bIsLockMod = IsModifyLocked();
2481cdf0e10cSrcweir                                         LockModify();
2482cdf0e10cSrcweir                                         SetFmtAttr( SwTblBoxValue( fVal ));
2483cdf0e10cSrcweir                                         if( !bIsLockMod )
2484cdf0e10cSrcweir                                             UnlockModify();
2485cdf0e10cSrcweir                                     }
2486cdf0e10cSrcweir                                 }
2487cdf0e10cSrcweir                             }
2488cdf0e10cSrcweir                         }
2489cdf0e10cSrcweir                         else
2490cdf0e10cSrcweir                             fVal = pNewVal->GetValue();
2491cdf0e10cSrcweir 
2492cdf0e10cSrcweir                         // den Inhalt mit dem neuen Wert Formtieren und in den Absatz
2493cdf0e10cSrcweir                         // schbreiben
2494cdf0e10cSrcweir                         Color* pCol = 0;
2495cdf0e10cSrcweir                         String sNewTxt;
2496cdf0e10cSrcweir                         if( DBL_MAX == fVal )
2497cdf0e10cSrcweir                             sNewTxt = ViewShell::GetShellRes()->aCalc_Error;
2498cdf0e10cSrcweir                         else
2499cdf0e10cSrcweir                         {
2500cdf0e10cSrcweir                             pNumFmtr->GetOutputString( fVal, nNewFmt, sNewTxt, &pCol );
2501cdf0e10cSrcweir 
2502cdf0e10cSrcweir                             if( !bChgTxt )
2503cdf0e10cSrcweir                                 sNewTxt.Erase();
2504cdf0e10cSrcweir                         }
2505cdf0e10cSrcweir 
2506cdf0e10cSrcweir                         // ueber alle Boxen
2507cdf0e10cSrcweir                         ChgTextToNum( *pBox, sNewTxt, pCol,
2508cdf0e10cSrcweir                                         GetDoc()->IsInsTblAlignNum() );
2509cdf0e10cSrcweir 
2510cdf0e10cSrcweir                     }
2511cdf0e10cSrcweir                     else if( bNewIsTxtFmt && nOldFmt != nNewFmt )
2512cdf0e10cSrcweir                     {
2513cdf0e10cSrcweir                         // auf jedenfall muessen jetzt die Formeln/Values
2514cdf0e10cSrcweir                         // geloescht werden!
2515cdf0e10cSrcweir     //                  LockModify();
2516cdf0e10cSrcweir     //                  ResetAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
2517cdf0e10cSrcweir     //                  UnlockModify();
2518cdf0e10cSrcweir 
2519cdf0e10cSrcweir 
2520cdf0e10cSrcweir                         ChgNumToText( *pBox, nNewFmt );
2521cdf0e10cSrcweir                     }
2522cdf0e10cSrcweir                 }
2523cdf0e10cSrcweir             }
2524cdf0e10cSrcweir         }
2525cdf0e10cSrcweir     }
2526cdf0e10cSrcweir     // Und die Basis-Klasse rufen
2527cdf0e10cSrcweir     SwFrmFmt::Modify( pOld, pNew );
2528cdf0e10cSrcweir }
2529cdf0e10cSrcweir 
HasNumCntnt(double & rNum,sal_uInt32 & rFmtIndex,sal_Bool & rIsEmptyTxtNd) const2530cdf0e10cSrcweir sal_Bool SwTableBox::HasNumCntnt( double& rNum, sal_uInt32& rFmtIndex,
2531cdf0e10cSrcweir                             sal_Bool& rIsEmptyTxtNd ) const
2532cdf0e10cSrcweir {
2533cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2534cdf0e10cSrcweir     sal_uLong nNdPos = IsValidNumTxtNd( sal_True );
2535cdf0e10cSrcweir     if( ULONG_MAX != nNdPos )
2536cdf0e10cSrcweir     {
2537cdf0e10cSrcweir         String aTxt( pSttNd->GetNodes()[ nNdPos ]->GetTxtNode()->
2538cdf0e10cSrcweir                             GetRedlineTxt() );
2539cdf0e10cSrcweir         //JP 15.09.98: Bug 55741 - Tabs beibehalten
2540cdf0e10cSrcweir         lcl_TabToBlankAtSttEnd( aTxt );
2541cdf0e10cSrcweir         rIsEmptyTxtNd = 0 == aTxt.Len();
2542cdf0e10cSrcweir         SvNumberFormatter* pNumFmtr = GetFrmFmt()->GetDoc()->GetNumberFormatter();
2543cdf0e10cSrcweir 
2544cdf0e10cSrcweir         const SfxPoolItem* pItem;
2545cdf0e10cSrcweir         if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT,
2546cdf0e10cSrcweir                 sal_False, &pItem ))
2547cdf0e10cSrcweir         {
2548cdf0e10cSrcweir             rFmtIndex = ((SwTblBoxNumFormat*)pItem)->GetValue();
2549cdf0e10cSrcweir             // JP 22.04.98: Bug 49659 - Sonderbehandlung fuer Prozent
2550cdf0e10cSrcweir             if( !rIsEmptyTxtNd &&
2551cdf0e10cSrcweir                 NUMBERFORMAT_PERCENT == pNumFmtr->GetType( rFmtIndex ))
2552cdf0e10cSrcweir             {
2553cdf0e10cSrcweir                 sal_uInt32 nTmpFmt = 0;
2554cdf0e10cSrcweir                 if( pNumFmtr->IsNumberFormat( aTxt, nTmpFmt, rNum ) &&
2555cdf0e10cSrcweir                     NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt ))
2556cdf0e10cSrcweir                     aTxt += '%';
2557cdf0e10cSrcweir             }
2558cdf0e10cSrcweir         }
2559cdf0e10cSrcweir         else
2560cdf0e10cSrcweir             rFmtIndex = 0;
2561cdf0e10cSrcweir 
2562cdf0e10cSrcweir         bRet = pNumFmtr->IsNumberFormat( aTxt, rFmtIndex, rNum );
2563cdf0e10cSrcweir     }
2564cdf0e10cSrcweir     else
2565cdf0e10cSrcweir         rIsEmptyTxtNd = sal_False;
2566cdf0e10cSrcweir     return bRet;
2567cdf0e10cSrcweir }
2568cdf0e10cSrcweir 
IsNumberChanged() const2569cdf0e10cSrcweir sal_Bool SwTableBox::IsNumberChanged() const
2570cdf0e10cSrcweir {
2571cdf0e10cSrcweir     sal_Bool bRet = sal_True;
2572cdf0e10cSrcweir 
2573cdf0e10cSrcweir     if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA, sal_False ))
2574cdf0e10cSrcweir     {
2575cdf0e10cSrcweir         const SwTblBoxNumFormat *pNumFmt;
2576cdf0e10cSrcweir         const SwTblBoxValue *pValue;
2577cdf0e10cSrcweir 
2578cdf0e10cSrcweir         if( SFX_ITEM_SET != GetFrmFmt()->GetItemState( RES_BOXATR_VALUE, sal_False,
2579cdf0e10cSrcweir             (const SfxPoolItem**)&pValue ))
2580cdf0e10cSrcweir             pValue = 0;
2581cdf0e10cSrcweir         if( SFX_ITEM_SET != GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT, sal_False,
2582cdf0e10cSrcweir             (const SfxPoolItem**)&pNumFmt ))
2583cdf0e10cSrcweir             pNumFmt = 0;
2584cdf0e10cSrcweir 
2585cdf0e10cSrcweir         sal_uLong nNdPos;
2586cdf0e10cSrcweir         if( pNumFmt && pValue &&
2587cdf0e10cSrcweir             ULONG_MAX != ( nNdPos = IsValidNumTxtNd( sal_True ) ) )
2588cdf0e10cSrcweir         {
2589cdf0e10cSrcweir             String sNewTxt, sOldTxt( pSttNd->GetNodes()[ nNdPos ]->
2590cdf0e10cSrcweir                                     GetTxtNode()->GetRedlineTxt() );
2591cdf0e10cSrcweir             lcl_DelTabsAtSttEnd( sOldTxt );
2592cdf0e10cSrcweir 
2593cdf0e10cSrcweir             Color* pCol = 0;
2594cdf0e10cSrcweir             GetFrmFmt()->GetDoc()->GetNumberFormatter()->GetOutputString(
2595cdf0e10cSrcweir                 pValue->GetValue(), pNumFmt->GetValue(), sNewTxt, &pCol );
2596cdf0e10cSrcweir 
2597cdf0e10cSrcweir             bRet = sNewTxt != sOldTxt ||
2598cdf0e10cSrcweir                     !( ( !pCol && !GetSaveNumFmtColor() ) ||
2599cdf0e10cSrcweir                        ( pCol && GetSaveNumFmtColor() &&
2600cdf0e10cSrcweir                         *pCol == *GetSaveNumFmtColor() ));
2601cdf0e10cSrcweir         }
2602cdf0e10cSrcweir     }
2603cdf0e10cSrcweir     return bRet;
2604cdf0e10cSrcweir }
2605cdf0e10cSrcweir 
IsValidNumTxtNd(sal_Bool bCheckAttr) const2606cdf0e10cSrcweir sal_uLong SwTableBox::IsValidNumTxtNd( sal_Bool bCheckAttr ) const
2607cdf0e10cSrcweir {
2608cdf0e10cSrcweir     sal_uLong nPos = ULONG_MAX;
2609cdf0e10cSrcweir     if( pSttNd )
2610cdf0e10cSrcweir     {
2611cdf0e10cSrcweir         SwNodeIndex aIdx( *pSttNd );
2612cdf0e10cSrcweir         sal_uLong nIndex = aIdx.GetIndex();
2613cdf0e10cSrcweir         const sal_uLong nIndexEnd = pSttNd->GetNodes()[ nIndex ]->EndOfSectionIndex();
2614cdf0e10cSrcweir         const SwTxtNode *pTextNode = 0;
2615cdf0e10cSrcweir         while( ++nIndex < nIndexEnd )
2616cdf0e10cSrcweir         {
2617cdf0e10cSrcweir             const SwNode* pNode = pSttNd->GetNodes()[nIndex];
2618cdf0e10cSrcweir             if( pNode->IsTableNode() )
2619cdf0e10cSrcweir             {    /*return ULONG_MAX if the cell contains a table(in table)*/
2620cdf0e10cSrcweir                 pTextNode = 0;
2621cdf0e10cSrcweir                 break;
2622cdf0e10cSrcweir             }
2623cdf0e10cSrcweir             if( pNode->IsTxtNode() )
2624cdf0e10cSrcweir             {
2625cdf0e10cSrcweir                 if( pTextNode )
2626cdf0e10cSrcweir                 {    /*return ULONG_MAX if the cell contains complex paragraphs*/
2627cdf0e10cSrcweir                     pTextNode = 0;
2628cdf0e10cSrcweir                     break;
2629cdf0e10cSrcweir                 }
2630cdf0e10cSrcweir                 else
2631cdf0e10cSrcweir                 {
2632cdf0e10cSrcweir                     pTextNode = pNode->GetTxtNode();
2633cdf0e10cSrcweir                     nPos = nIndex;
2634cdf0e10cSrcweir                 }
2635cdf0e10cSrcweir             }
2636cdf0e10cSrcweir         }
2637cdf0e10cSrcweir         if( pTextNode )
2638cdf0e10cSrcweir         {
2639cdf0e10cSrcweir             if( bCheckAttr )
2640cdf0e10cSrcweir             {
2641cdf0e10cSrcweir                 const SwpHints* pHts = pTextNode->GetpSwpHints();
2642cdf0e10cSrcweir                 const String& rTxt = pTextNode->GetTxt();
2643cdf0e10cSrcweir                 // dann teste doch mal, ob das wirklich nur Text im Node steht!
2644cdf0e10cSrcweir                 // Flys/Felder/..
2645cdf0e10cSrcweir                 if( pHts )
2646cdf0e10cSrcweir                 {
2647b1f53925SMichael Stahl                     xub_StrLen nNextSetField = 0;
2648cdf0e10cSrcweir                     for( sal_uInt16 n = 0; n < pHts->Count(); ++n )
2649cdf0e10cSrcweir                     {
2650cdf0e10cSrcweir                         const SwTxtAttr* pAttr = (*pHts)[ n ];
2651cdf0e10cSrcweir                         if( RES_TXTATR_NOEND_BEGIN <= pAttr->Which() ||
2652cdf0e10cSrcweir                             *pAttr->GetStart() ||
2653cdf0e10cSrcweir                             *pAttr->GetAnyEnd() < rTxt.Len() )
2654cdf0e10cSrcweir                         {
2655dec99bbdSOliver-Rainer Wittmann                             if ( (*pAttr->GetStart() == nNextSetField)
2656dec99bbdSOliver-Rainer Wittmann                                  && (pAttr->Which() == RES_TXTATR_FIELD))
2657cdf0e10cSrcweir                             {
2658b1f53925SMichael Stahl                                 // #i104949# hideous hack for report builder:
2659b1f53925SMichael Stahl                                 // it inserts hidden variable-set fields at
2660b1f53925SMichael Stahl                                 // the beginning of para in cell, but they
2661b1f53925SMichael Stahl                                 // should not turn cell into text cell
2662c0286415SOliver-Rainer Wittmann                                 const SwField* pField = pAttr->GetFmtFld().GetField();
2663b1f53925SMichael Stahl                                 if (pField &&
2664b1f53925SMichael Stahl                                     (pField->GetTypeId() == TYP_SETFLD) &&
2665b1f53925SMichael Stahl                                     (0 != (static_cast<SwSetExpField const*>
2666b1f53925SMichael Stahl                                            (pField)->GetSubType() &
2667b1f53925SMichael Stahl                                         nsSwExtendedSubType::SUB_INVISIBLE)))
2668cdf0e10cSrcweir                                 {
2669b1f53925SMichael Stahl                                     nNextSetField = *pAttr->GetStart() + 1;
2670cdf0e10cSrcweir                                     continue;
2671cdf0e10cSrcweir                                 }
2672cdf0e10cSrcweir                             }
2673cdf0e10cSrcweir                             nPos = ULONG_MAX;
2674cdf0e10cSrcweir                             break;
2675cdf0e10cSrcweir                         }
2676cdf0e10cSrcweir                     }
2677cdf0e10cSrcweir                 }
2678cdf0e10cSrcweir             }
2679cdf0e10cSrcweir         }
2680cdf0e10cSrcweir         else
2681cdf0e10cSrcweir             nPos = ULONG_MAX;
2682cdf0e10cSrcweir     }
2683cdf0e10cSrcweir     return nPos;
2684cdf0e10cSrcweir }
2685cdf0e10cSrcweir 
2686cdf0e10cSrcweir // ist das eine FormelBox oder eine Box mit numerischen Inhalt (AutoSum)
IsFormulaOrValueBox() const2687cdf0e10cSrcweir sal_uInt16 SwTableBox::IsFormulaOrValueBox() const
2688cdf0e10cSrcweir {
2689cdf0e10cSrcweir     sal_uInt16 nWhich = 0;
2690cdf0e10cSrcweir     const SwTxtNode* pTNd;
2691cdf0e10cSrcweir     SwFrmFmt* pFmt = GetFrmFmt();
2692cdf0e10cSrcweir     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA, sal_False ))
2693cdf0e10cSrcweir         nWhich = RES_BOXATR_FORMULA;
2694cdf0e10cSrcweir     else if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) &&
2695cdf0e10cSrcweir             !pFmt->GetDoc()->GetNumberFormatter()->IsTextFormat(
2696cdf0e10cSrcweir                 pFmt->GetTblBoxNumFmt().GetValue() ))
2697cdf0e10cSrcweir         nWhich = RES_BOXATR_VALUE;
2698cdf0e10cSrcweir     else if( pSttNd && pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex()
2699cdf0e10cSrcweir             && 0 != ( pTNd = pSttNd->GetNodes()[ pSttNd->GetIndex() + 1 ]
2700cdf0e10cSrcweir             ->GetTxtNode() ) && !pTNd->GetTxt().Len() )
2701cdf0e10cSrcweir         nWhich = USHRT_MAX;
2702cdf0e10cSrcweir 
2703cdf0e10cSrcweir     return nWhich;
2704cdf0e10cSrcweir }
2705cdf0e10cSrcweir 
ActualiseValueBox()2706cdf0e10cSrcweir void SwTableBox::ActualiseValueBox()
2707cdf0e10cSrcweir {
2708cdf0e10cSrcweir     const SfxPoolItem *pFmtItem, *pValItem;
2709cdf0e10cSrcweir     SwFrmFmt* pFmt = GetFrmFmt();
2710cdf0e10cSrcweir     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMAT, sal_True, &pFmtItem )
2711cdf0e10cSrcweir         && SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_True, &pValItem ))
2712cdf0e10cSrcweir     {
2713cdf0e10cSrcweir         const sal_uLong nFmtId = ((SwTblBoxNumFormat*)pFmtItem)->GetValue();
2714cdf0e10cSrcweir         sal_uLong nNdPos = ULONG_MAX;
2715cdf0e10cSrcweir         SvNumberFormatter* pNumFmtr = pFmt->GetDoc()->GetNumberFormatter();
2716cdf0e10cSrcweir 
2717cdf0e10cSrcweir         if( !pNumFmtr->IsTextFormat( nFmtId ) &&
2718cdf0e10cSrcweir             ULONG_MAX != (nNdPos = IsValidNumTxtNd( sal_True )) )
2719cdf0e10cSrcweir         {
2720cdf0e10cSrcweir             double fVal = ((SwTblBoxValue*)pValItem)->GetValue();
2721cdf0e10cSrcweir             Color* pCol = 0;
2722cdf0e10cSrcweir             String sNewTxt;
2723cdf0e10cSrcweir             pNumFmtr->GetOutputString( fVal, nFmtId, sNewTxt, &pCol );
2724cdf0e10cSrcweir 
2725cdf0e10cSrcweir             const String& rTxt = pSttNd->GetNodes()[ nNdPos ]->GetTxtNode()->GetTxt();
2726cdf0e10cSrcweir             if( rTxt != sNewTxt )
2727cdf0e10cSrcweir                 ChgTextToNum( *this, sNewTxt, pCol, sal_False ,nNdPos);
2728cdf0e10cSrcweir         }
2729cdf0e10cSrcweir     }
2730cdf0e10cSrcweir }
2731cdf0e10cSrcweir 
SetNewCol(Color ** ppCol,const Color * pNewCol)2732cdf0e10cSrcweir void SwTableBox_Impl::SetNewCol( Color** ppCol, const Color* pNewCol )
2733cdf0e10cSrcweir {
2734cdf0e10cSrcweir     if( *ppCol != pNewCol )
2735cdf0e10cSrcweir     {
2736cdf0e10cSrcweir         delete *ppCol;
2737cdf0e10cSrcweir         if( pNewCol )
2738cdf0e10cSrcweir             *ppCol = new Color( *pNewCol );
2739cdf0e10cSrcweir         else
2740cdf0e10cSrcweir             *ppCol = 0;
2741cdf0e10cSrcweir     }
2742cdf0e10cSrcweir }
2743cdf0e10cSrcweir 
2744cdf0e10cSrcweir struct SwTableCellInfo::Impl
2745cdf0e10cSrcweir {
2746cdf0e10cSrcweir     const SwTable * m_pTable;
2747cdf0e10cSrcweir     const SwCellFrm * m_pCellFrm;
2748cdf0e10cSrcweir     const SwTabFrm * m_pTabFrm;
2749cdf0e10cSrcweir     typedef ::std::set<const SwTableBox *> TableBoxes_t;
2750cdf0e10cSrcweir     TableBoxes_t m_HandledTableBoxes;
2751cdf0e10cSrcweir 
2752cdf0e10cSrcweir public:
ImplSwTableCellInfo::Impl2753cdf0e10cSrcweir     Impl()
2754cdf0e10cSrcweir         : m_pTable(NULL), m_pCellFrm(NULL), m_pTabFrm(NULL)
2755cdf0e10cSrcweir     {
2756cdf0e10cSrcweir     }
2757cdf0e10cSrcweir 
~ImplSwTableCellInfo::Impl2758cdf0e10cSrcweir     ~Impl() {}
2759cdf0e10cSrcweir 
setTableSwTableCellInfo::Impl2760cdf0e10cSrcweir     void setTable(const SwTable * pTable) {
2761cdf0e10cSrcweir         m_pTable = pTable;
2762cdf0e10cSrcweir         SwFrmFmt * pFrmFmt = m_pTable->GetFrmFmt();
2763cdf0e10cSrcweir         m_pTabFrm = SwIterator<SwTabFrm,SwFmt>::FirstElement(*pFrmFmt);
2764cdf0e10cSrcweir         if (m_pTabFrm->IsFollow())
2765cdf0e10cSrcweir             m_pTabFrm = m_pTabFrm->FindMaster(true);
2766cdf0e10cSrcweir     }
getTableSwTableCellInfo::Impl2767cdf0e10cSrcweir     const SwTable * getTable() const { return m_pTable; }
2768cdf0e10cSrcweir 
getCellFrmSwTableCellInfo::Impl2769cdf0e10cSrcweir     const SwCellFrm * getCellFrm() const { return m_pCellFrm; }
2770cdf0e10cSrcweir 
2771cdf0e10cSrcweir     const SwFrm * getNextFrmInTable(const SwFrm * pFrm);
2772cdf0e10cSrcweir     const SwCellFrm * getNextCellFrm(const SwFrm * pFrm);
2773cdf0e10cSrcweir     const SwCellFrm * getNextTableBoxsCellFrm(const SwFrm * pFrm);
2774cdf0e10cSrcweir     bool getNext();
2775cdf0e10cSrcweir };
2776cdf0e10cSrcweir 
getNextFrmInTable(const SwFrm * pFrm)2777cdf0e10cSrcweir const SwFrm * SwTableCellInfo::Impl::getNextFrmInTable(const SwFrm * pFrm)
2778cdf0e10cSrcweir {
2779cdf0e10cSrcweir     const SwFrm * pResult = NULL;
2780cdf0e10cSrcweir 
2781cdf0e10cSrcweir     if (((! pFrm->IsTabFrm()) || pFrm == m_pTabFrm) && pFrm->GetLower())
2782cdf0e10cSrcweir         pResult = pFrm->GetLower();
2783cdf0e10cSrcweir     else if (pFrm->GetNext())
2784cdf0e10cSrcweir         pResult = pFrm->GetNext();
2785cdf0e10cSrcweir     else
2786cdf0e10cSrcweir     {
2787cdf0e10cSrcweir         while (pFrm->GetUpper() != NULL)
2788cdf0e10cSrcweir         {
2789cdf0e10cSrcweir             pFrm = pFrm->GetUpper();
2790cdf0e10cSrcweir 
2791cdf0e10cSrcweir             if (pFrm->IsTabFrm())
2792cdf0e10cSrcweir             {
2793cdf0e10cSrcweir                 m_pTabFrm = static_cast<const SwTabFrm *>(pFrm)->GetFollow();
2794cdf0e10cSrcweir                 pResult = m_pTabFrm;
2795cdf0e10cSrcweir                 break;
2796cdf0e10cSrcweir             }
2797cdf0e10cSrcweir             else if (pFrm->GetNext())
2798cdf0e10cSrcweir             {
2799cdf0e10cSrcweir                 pResult = pFrm->GetNext();
2800cdf0e10cSrcweir                 break;
2801cdf0e10cSrcweir             }
2802cdf0e10cSrcweir         }
2803cdf0e10cSrcweir     }
2804cdf0e10cSrcweir 
2805cdf0e10cSrcweir     return pResult;
2806cdf0e10cSrcweir }
2807cdf0e10cSrcweir 
getNextCellFrm(const SwFrm * pFrm)2808cdf0e10cSrcweir const SwCellFrm * SwTableCellInfo::Impl::getNextCellFrm(const SwFrm * pFrm)
2809cdf0e10cSrcweir {
2810cdf0e10cSrcweir     const SwCellFrm * pResult = NULL;
2811cdf0e10cSrcweir 
2812cdf0e10cSrcweir     while ((pFrm = getNextFrmInTable(pFrm)) != NULL)
2813cdf0e10cSrcweir     {
2814cdf0e10cSrcweir         if (pFrm->IsCellFrm())
2815cdf0e10cSrcweir         {
2816cdf0e10cSrcweir             pResult = static_cast<const SwCellFrm *>(pFrm);
2817cdf0e10cSrcweir             break;
2818cdf0e10cSrcweir         }
2819cdf0e10cSrcweir     }
2820cdf0e10cSrcweir 
2821cdf0e10cSrcweir     return pResult;
2822cdf0e10cSrcweir }
2823cdf0e10cSrcweir 
getNextTableBoxsCellFrm(const SwFrm * pFrm)2824cdf0e10cSrcweir const SwCellFrm * SwTableCellInfo::Impl::getNextTableBoxsCellFrm(const SwFrm * pFrm)
2825cdf0e10cSrcweir {
2826cdf0e10cSrcweir     const SwCellFrm * pResult = NULL;
2827cdf0e10cSrcweir 
2828cdf0e10cSrcweir     while ((pFrm = getNextCellFrm(pFrm)) != NULL)
2829cdf0e10cSrcweir     {
2830cdf0e10cSrcweir         const SwCellFrm * pCellFrm = static_cast<const SwCellFrm *>(pFrm);
2831cdf0e10cSrcweir         const SwTableBox * pTabBox = pCellFrm->GetTabBox();
2832cdf0e10cSrcweir         TableBoxes_t::const_iterator aIt = m_HandledTableBoxes.find(pTabBox);
2833cdf0e10cSrcweir 
2834cdf0e10cSrcweir         if (aIt == m_HandledTableBoxes.end())
2835cdf0e10cSrcweir         {
2836cdf0e10cSrcweir             pResult = pCellFrm;
2837cdf0e10cSrcweir             m_HandledTableBoxes.insert(pTabBox);
2838cdf0e10cSrcweir             break;
2839cdf0e10cSrcweir         }
2840cdf0e10cSrcweir     }
2841cdf0e10cSrcweir 
2842cdf0e10cSrcweir     return pResult;
2843cdf0e10cSrcweir }
2844cdf0e10cSrcweir 
getCellFrm() const2845cdf0e10cSrcweir const SwCellFrm * SwTableCellInfo::getCellFrm() const
2846cdf0e10cSrcweir {
2847cdf0e10cSrcweir     return m_pImpl->getCellFrm();
2848cdf0e10cSrcweir }
2849cdf0e10cSrcweir 
getNext()2850cdf0e10cSrcweir bool SwTableCellInfo::Impl::getNext()
2851cdf0e10cSrcweir {
2852cdf0e10cSrcweir     if (m_pCellFrm == NULL)
2853cdf0e10cSrcweir     {
2854cdf0e10cSrcweir         if (m_pTabFrm != NULL)
2855cdf0e10cSrcweir             m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pTabFrm);
2856cdf0e10cSrcweir     }
2857cdf0e10cSrcweir     else
2858cdf0e10cSrcweir         m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pCellFrm);
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir     return m_pCellFrm != NULL;
2861cdf0e10cSrcweir }
2862cdf0e10cSrcweir 
SwTableCellInfo(const SwTable * pTable)2863cdf0e10cSrcweir SwTableCellInfo::SwTableCellInfo(const SwTable * pTable)
2864cdf0e10cSrcweir {
2865cdf0e10cSrcweir     m_pImpl.reset(new Impl());
2866cdf0e10cSrcweir     m_pImpl->setTable(pTable);
2867cdf0e10cSrcweir }
2868cdf0e10cSrcweir 
~SwTableCellInfo()2869cdf0e10cSrcweir SwTableCellInfo::~SwTableCellInfo()
2870cdf0e10cSrcweir {
2871cdf0e10cSrcweir }
2872cdf0e10cSrcweir 
getNext()2873cdf0e10cSrcweir bool SwTableCellInfo::getNext()
2874cdf0e10cSrcweir {
2875cdf0e10cSrcweir     return m_pImpl->getNext();
2876cdf0e10cSrcweir }
2877cdf0e10cSrcweir 
getRect() const2878cdf0e10cSrcweir SwRect SwTableCellInfo::getRect() const
2879cdf0e10cSrcweir {
2880cdf0e10cSrcweir     SwRect aRet;
2881cdf0e10cSrcweir 
2882cdf0e10cSrcweir     if (getCellFrm() != NULL)
2883cdf0e10cSrcweir         aRet = getCellFrm()->Frm();
2884cdf0e10cSrcweir 
2885cdf0e10cSrcweir     return aRet;
2886cdf0e10cSrcweir }
2887cdf0e10cSrcweir 
getTableBox() const2888cdf0e10cSrcweir const SwTableBox * SwTableCellInfo::getTableBox() const
2889cdf0e10cSrcweir {
2890cdf0e10cSrcweir     const SwTableBox * pRet = NULL;
2891cdf0e10cSrcweir 
2892cdf0e10cSrcweir     if (getCellFrm() != NULL)
2893cdf0e10cSrcweir         pRet = getCellFrm()->GetTabBox();
2894cdf0e10cSrcweir 
2895cdf0e10cSrcweir     return pRet;
2896cdf0e10cSrcweir }
2897cdf0e10cSrcweir 
RegisterToFormat(SwFmt & rFmt)2898cdf0e10cSrcweir void SwTable::RegisterToFormat( SwFmt& rFmt )
2899cdf0e10cSrcweir {
2900cdf0e10cSrcweir     rFmt.Add( this );
2901cdf0e10cSrcweir }
2902cdf0e10cSrcweir 
RegisterToFormat(SwFmt & rFmt)2903cdf0e10cSrcweir void SwTableLine::RegisterToFormat( SwFmt& rFmt )
2904cdf0e10cSrcweir {
2905cdf0e10cSrcweir     rFmt.Add( this );
2906cdf0e10cSrcweir }
2907cdf0e10cSrcweir 
RegisterToFormat(SwFmt & rFmt)2908cdf0e10cSrcweir void SwTableBox::RegisterToFormat( SwFmt& rFmt )
2909cdf0e10cSrcweir {
2910cdf0e10cSrcweir     rFmt.Add( this );
2911cdf0e10cSrcweir }
2912cdf0e10cSrcweir 
ForgetFrmFmt()2913cdf0e10cSrcweir void SwTableBox::ForgetFrmFmt()
2914cdf0e10cSrcweir {
2915cdf0e10cSrcweir     if ( GetRegisteredIn() )
2916cdf0e10cSrcweir         GetRegisteredInNonConst()->Remove(this);
2917cdf0e10cSrcweir }
2918