1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tblrwcl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <com/sun/star/text/HoriOrientation.hpp>
35 #include <com/sun/star/chart2/XChartDocument.hpp>
36 #include <hintids.hxx>
38 #define _ZFORLIST_DECLARE_TABLE
39 #include <svx/brshitem.hxx>
40 #include <svx/lrspitem.hxx>
41 #include <svx/protitem.hxx>
42 #include <svx/boxitem.hxx>
43 #include <tools/fract.hxx>
44 #include <fmtfsize.hxx>
45 #include <fmtornt.hxx>
49 #include <frmtool.hxx>
51 #include <swtable.hxx>
59 #include <cellatr.hxx>
61 #include <swtblfmt.hxx>
62 #include <swddetbl.hxx>
63 #include <poolfmt.hxx>
64 #include <tblrwcl.hxx>
65 #include <unochart.hxx>
66 #include <boost/shared_ptr.hpp>
68 using namespace com::sun::star
;
69 using namespace com::sun::star::uno
;
75 using namespace ::com::sun::star
;
78 #define CHECK_TABLE(t)
81 #define CHECK_TABLE(t) (t).CheckConsistency();
83 #define CHECK_TABLE(t)
87 typedef SwTableLine
* SwTableLinePtr
;
88 SV_DECL_PTRARR_SORT( SwSortTableLines
, SwTableLinePtr
, 16, 16 )
89 SV_IMPL_PTRARR_SORT( SwSortTableLines
, SwTableLinePtr
);
91 SV_IMPL_PTRARR( _SwShareBoxFmts
, SwShareBoxFmt
* )
93 // fuers setzen der Frame-Formate an den Boxen reicht es, das aktuelle
94 // im Array zu suchen. Ist es vorhanden, so gebe das neue zurueck
98 SwTableBoxFmt
*pFrmFmt
; // fuer CopyCol
99 SwTwips nSize
; // fuer DelCol
101 SwTableBoxFmt
*pNewFrmFmt
;
103 _CpyTabFrm( SwTableBoxFmt
* pAktFrmFmt
) : pNewFrmFmt( 0 )
104 { Value
.pFrmFmt
= pAktFrmFmt
; }
106 _CpyTabFrm
& operator=( const _CpyTabFrm
& );
108 BOOL
operator==( const _CpyTabFrm
& rCpyTabFrm
)
109 { return (ULONG
)Value
.nSize
== (ULONG
)rCpyTabFrm
.Value
.nSize
; }
110 BOOL
operator<( const _CpyTabFrm
& rCpyTabFrm
)
111 { return (ULONG
)Value
.nSize
< (ULONG
)rCpyTabFrm
.Value
.nSize
; }
114 struct CR_SetBoxWidth
117 SwSortTableLines aLines
;
118 SvUShorts aLinesWidth
;
119 SwShareBoxFmts aShareFmts
;
121 SwUndoTblNdsChg
* pUndo
;
122 SwTwips nDiff
, nSide
, nMaxSize
, nLowerDiff
;
124 USHORT nTblWidth
, nRemainWidth
, nBoxWidth
;
125 BOOL bBigger
, bLeft
, bSplittBox
, bAnyBoxFnd
;
127 CR_SetBoxWidth( USHORT eType
, SwTwips nDif
, SwTwips nSid
, SwTwips nTblW
,
128 SwTwips nMax
, SwTableNode
* pTNd
)
130 nDiff( nDif
), nSide( nSid
), nMaxSize( nMax
), nLowerDiff( 0 ),
131 nTblWidth( (USHORT
)nTblW
), nRemainWidth( 0 ), nBoxWidth( 0 ),
132 bSplittBox( FALSE
), bAnyBoxFnd( FALSE
)
134 bLeft
= nsTblChgWidthHeightType::WH_COL_LEFT
== ( eType
& 0xff ) ||
135 nsTblChgWidthHeightType::WH_CELL_LEFT
== ( eType
& 0xff );
136 bBigger
= 0 != (eType
& nsTblChgWidthHeightType::WH_FLAG_BIGGER
);
137 nMode
= pTblNd
->GetTable().GetTblChgMode();
139 CR_SetBoxWidth( const CR_SetBoxWidth
& rCpy
)
140 : pTblNd( rCpy
.pTblNd
),
142 nDiff( rCpy
.nDiff
), nSide( rCpy
.nSide
),
143 nMaxSize( rCpy
.nMaxSize
), nLowerDiff( 0 ),
144 nMode( rCpy
.nMode
), nTblWidth( rCpy
.nTblWidth
),
145 nRemainWidth( rCpy
.nRemainWidth
), nBoxWidth( nBoxWidth
),
146 bBigger( rCpy
.bBigger
), bLeft( rCpy
.bLeft
),
147 bSplittBox( rCpy
.bSplittBox
), bAnyBoxFnd( rCpy
.bAnyBoxFnd
)
149 aLines
.Insert( &rCpy
.aLines
);
150 aLinesWidth
.Insert( &rCpy
.aLinesWidth
, 0 );
153 SwUndoTblNdsChg
* CreateUndo( SwUndoId eUndoType
)
155 return pUndo
= new SwUndoTblNdsChg( eUndoType
, aBoxes
, *pTblNd
);
160 nLowerDiff
= 0; nRemainWidth
= 0;
163 void AddBoxWidth( const SwTableBox
& rBox
, USHORT nWidth
)
165 SwTableLinePtr p
= (SwTableLine
*)rBox
.GetUpper();
167 if( aLines
.Insert( p
, nFndPos
))
168 aLinesWidth
.Insert( nWidth
, nFndPos
);
170 aLinesWidth
[ nFndPos
] = aLinesWidth
[ nFndPos
] + nWidth
;
173 USHORT
GetBoxWidth( const SwTableLine
& rLn
) const
175 SwTableLinePtr p
= (SwTableLine
*)&rLn
;
177 if( aLines
.Seek_Entry( p
, &nFndPos
) )
178 nFndPos
= aLinesWidth
[ nFndPos
];
185 BOOL
lcl_SetSelBoxWidth( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
186 SwTwips nDist
, BOOL bCheck
);
187 BOOL
lcl_SetOtherBoxWidth( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
188 SwTwips nDist
, BOOL bCheck
);
189 BOOL
lcl_InsSelBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
190 SwTwips nDist
, BOOL bCheck
);
191 BOOL
lcl_InsOtherBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
192 SwTwips nDist
, BOOL bCheck
);
193 BOOL
lcl_DelSelBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
194 SwTwips nDist
, BOOL bCheck
);
195 BOOL
lcl_DelOtherBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
196 SwTwips nDist
, BOOL bCheck
);
198 typedef BOOL (*FN_lcl_SetBoxWidth
)(SwTableLine
*, CR_SetBoxWidth
&, SwTwips
, BOOL
);
200 #if !defined( PRODUCT ) || defined( JP_DEBUG )
202 void _CheckBoxWidth( const SwTableLine
& rLine
, SwTwips nSize
);
204 #define CHECKBOXWIDTH \
206 SwTwips nSize = GetFrmFmt()->GetFrmSize().GetWidth(); \
207 for( USHORT nTmp = 0; nTmp < aLines.Count(); ++nTmp ) \
208 ::_CheckBoxWidth( *aLines[ nTmp ], nSize ); \
211 #define CHECKTABLELAYOUT \
213 for ( USHORT i = 0; i < GetTabLines().Count(); ++i ) \
215 SwFrmFmt* pFmt = GetTabLines()[i]->GetFrmFmt(); \
216 SwClientIter aIter( *pFmt ); \
217 SwClient* pLast = aIter.GoStart(); \
222 SwFrm *pFrm = PTR_CAST( SwFrm, pLast ); \
224 ((SwRowFrm*)pFrm)->GetTabLine() == GetTabLines()[i] ) \
226 ASSERT( pFrm->GetUpper()->IsTabFrm(), \
227 "Table layout does not match table structure" ) \
229 } while ( 0 != ( pLast = aIter++ ) ); \
236 #define CHECKBOXWIDTH
237 #define CHECKTABLELAYOUT
242 struct CR_SetLineHeight
245 SwShareBoxFmts aShareFmts
;
247 SwUndoTblNdsChg
* pUndo
;
248 SwTwips nMaxSpace
, nMaxHeight
;
251 BOOL bBigger
, bTop
, bSplittBox
, bAnyBoxFnd
;
253 CR_SetLineHeight( USHORT eType
, SwTableNode
* pTNd
)
254 : pTblNd( pTNd
), pUndo( 0 ),
255 nMaxSpace( 0 ), nMaxHeight( 0 ), nLines( 0 ),
256 bSplittBox( FALSE
), bAnyBoxFnd( FALSE
)
258 bTop
= nsTblChgWidthHeightType::WH_ROW_TOP
== ( eType
& 0xff ) || nsTblChgWidthHeightType::WH_CELL_TOP
== ( eType
& 0xff );
259 bBigger
= 0 != (eType
& nsTblChgWidthHeightType::WH_FLAG_BIGGER
);
260 if( eType
& nsTblChgWidthHeightType::WH_FLAG_INSDEL
)
262 nMode
= pTblNd
->GetTable().GetTblChgMode();
264 CR_SetLineHeight( const CR_SetLineHeight
& rCpy
)
265 : pTblNd( rCpy
.pTblNd
), pUndo( rCpy
.pUndo
),
266 nMaxSpace( rCpy
.nMaxSpace
), nMaxHeight( rCpy
.nMaxHeight
),
267 nMode( rCpy
.nMode
), nLines( rCpy
.nLines
),
268 bBigger( rCpy
.bBigger
), bTop( rCpy
.bTop
),
269 bSplittBox( rCpy
.bSplittBox
), bAnyBoxFnd( rCpy
.bAnyBoxFnd
)
272 SwUndoTblNdsChg
* CreateUndo( SwUndoId nUndoType
)
274 return pUndo
= new SwUndoTblNdsChg( nUndoType
, aBoxes
, *pTblNd
);
278 BOOL
lcl_SetSelLineHeight( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
279 SwTwips nDist
, BOOL bCheck
);
280 BOOL
lcl_SetOtherLineHeight( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
281 SwTwips nDist
, BOOL bCheck
);
282 BOOL
lcl_InsDelSelLine( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
283 SwTwips nDist
, BOOL bCheck
);
285 typedef BOOL (*FN_lcl_SetLineHeight
)(SwTableLine
*, CR_SetLineHeight
&, SwTwips
, BOOL
);
287 _CpyTabFrm
& _CpyTabFrm::operator=( const _CpyTabFrm
& rCpyTabFrm
)
289 pNewFrmFmt
= rCpyTabFrm
.pNewFrmFmt
;
290 Value
= rCpyTabFrm
.Value
;
294 SV_DECL_VARARR_SORT( _CpyTabFrms
, _CpyTabFrm
, 0, 50 )
295 SV_IMPL_VARARR_SORT( _CpyTabFrms
, _CpyTabFrm
)
297 void lcl_DelCpyTabFrmFmts( _CpyTabFrm
& rArr
);
299 // ---------------------------------------------------------------
303 boost::shared_ptr
< std::vector
< std::vector
< ULONG
> > > pWidths
;
306 _CpyTabFrms
& rTabFrmArr
;
307 SwTableLine
* pInsLine
;
309 ULONG nOldSize
, nNewSize
; // zum Korrigieren der Size-Attribute
310 ULONG nMinLeft
, nMaxRight
;
311 USHORT nCpyCnt
, nInsPos
;
312 USHORT nLnIdx
, nBoxIdx
;
316 _CpyPara( SwTableNode
* pNd
, USHORT nCopies
, _CpyTabFrms
& rFrmArr
,
317 BOOL bCopyContent
= TRUE
)
318 : pDoc( pNd
->GetDoc() ), pTblNd( pNd
), rTabFrmArr(rFrmArr
),
319 pInsLine(0), pInsBox(0), nOldSize(0), nNewSize(0),
320 nMinLeft(ULONG_MAX
), nMaxRight(0),
321 nCpyCnt(nCopies
), nInsPos(0),
322 nLnIdx(0), nBoxIdx(0),
323 nDelBorderFlag(0), bCpyCntnt( bCopyContent
)
325 _CpyPara( const _CpyPara
& rPara
, SwTableLine
* pLine
)
326 : pWidths( rPara
.pWidths
), pDoc(rPara
.pDoc
), pTblNd(rPara
.pTblNd
),
327 rTabFrmArr(rPara
.rTabFrmArr
), pInsLine(pLine
), pInsBox(rPara
.pInsBox
),
328 nOldSize(0), nNewSize(rPara
.nNewSize
), nMinLeft( rPara
.nMinLeft
),
329 nMaxRight( rPara
.nMaxRight
), nCpyCnt(rPara
.nCpyCnt
), nInsPos(0),
330 nLnIdx( rPara
.nLnIdx
), nBoxIdx( rPara
.nBoxIdx
),
331 nDelBorderFlag( rPara
.nDelBorderFlag
), bCpyCntnt( rPara
.bCpyCntnt
)
333 _CpyPara( const _CpyPara
& rPara
, SwTableBox
* pBox
)
334 : pWidths( rPara
.pWidths
), pDoc(rPara
.pDoc
), pTblNd(rPara
.pTblNd
),
335 rTabFrmArr(rPara
.rTabFrmArr
), pInsLine(rPara
.pInsLine
), pInsBox(pBox
),
336 nOldSize(rPara
.nOldSize
), nNewSize(rPara
.nNewSize
),
337 nMinLeft( rPara
.nMinLeft
), nMaxRight( rPara
.nMaxRight
),
338 nCpyCnt(rPara
.nCpyCnt
), nInsPos(0), nLnIdx(rPara
.nLnIdx
), nBoxIdx(rPara
.nBoxIdx
),
339 nDelBorderFlag( rPara
.nDelBorderFlag
), bCpyCntnt( rPara
.bCpyCntnt
)
341 void SetBoxWidth( SwTableBox
* pBox
);
345 BOOL
lcl_CopyCol( const _FndBox
*& rpFndBox
, void* pPara
)
347 _CpyPara
* pCpyPara
= (_CpyPara
*)pPara
;
349 // suche das FrmFmt im Array aller Frame-Formate
350 SwTableBox
* pBox
= (SwTableBox
*)rpFndBox
->GetBox();
351 _CpyTabFrm
aFindFrm( (SwTableBoxFmt
*)pBox
->GetFrmFmt() );
354 if( pCpyPara
->nCpyCnt
)
356 if( !pCpyPara
->rTabFrmArr
.Seek_Entry( aFindFrm
, &nFndPos
))
358 // fuer das verschachtelte Kopieren sicher auch das neue Format
360 SwTableBoxFmt
* pNewFmt
= (SwTableBoxFmt
*)pBox
->ClaimFrmFmt();
362 // suche die selektierten Boxen in der Line:
363 _FndLine
* pCmpLine
= NULL
;
364 SwFmtFrmSize
aFrmSz( pNewFmt
->GetFrmSize() );
366 bool bDiffCount
= false;
367 if( pBox
->GetTabLines().Count() )
369 pCmpLine
= rpFndBox
->GetLines()[ 0 ];
370 if ( pCmpLine
->GetBoxes().Count() != pCmpLine
->GetLine()->GetTabBoxes().Count() )
376 // die erste Line sollte reichen
377 _FndBoxes
& rFndBoxes
= pCmpLine
->GetBoxes();
379 for( USHORT n
= rFndBoxes
.Count(); n
; )
380 nSz
+= rFndBoxes
[ --n
]->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
381 aFrmSz
.SetWidth( aFrmSz
.GetWidth() -
382 nSz
/ ( pCpyPara
->nCpyCnt
+ 1 ) );
383 pNewFmt
->SetFmtAttr( aFrmSz
);
384 aFrmSz
.SetWidth( nSz
/ ( pCpyPara
->nCpyCnt
+ 1 ) );
386 // fuer die neue Box ein neues Format mit der Groesse anlegen!
387 aFindFrm
.pNewFrmFmt
= (SwTableBoxFmt
*)pNewFmt
->GetDoc()->
389 *aFindFrm
.pNewFrmFmt
= *pNewFmt
;
390 aFindFrm
.pNewFrmFmt
->SetFmtAttr( aFrmSz
);
394 aFrmSz
.SetWidth( aFrmSz
.GetWidth() / ( pCpyPara
->nCpyCnt
+ 1 ) );
395 pNewFmt
->SetFmtAttr( aFrmSz
);
397 aFindFrm
.pNewFrmFmt
= pNewFmt
;
398 pCpyPara
->rTabFrmArr
.Insert( aFindFrm
);
399 aFindFrm
.Value
.pFrmFmt
= pNewFmt
;
400 pCpyPara
->rTabFrmArr
.Insert( aFindFrm
);
405 aFindFrm
= pCpyPara
->rTabFrmArr
[ nFndPos
];
406 // aFindFrm.pNewFrmFmt->Add( pBox );
407 pBox
->ChgFrmFmt( (SwTableBoxFmt
*)aFindFrm
.pNewFrmFmt
);
412 if( pCpyPara
->nDelBorderFlag
&&
413 pCpyPara
->rTabFrmArr
.Seek_Entry( aFindFrm
, &nFndPos
))
414 aFindFrm
= pCpyPara
->rTabFrmArr
[ nFndPos
];
416 aFindFrm
.pNewFrmFmt
= (SwTableBoxFmt
*)pBox
->GetFrmFmt();
419 if( rpFndBox
->GetLines().Count() )
421 pBox
= new SwTableBox( aFindFrm
.pNewFrmFmt
,
422 rpFndBox
->GetLines().Count(), pCpyPara
->pInsLine
);
423 pCpyPara
->pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pBox
, pCpyPara
->nInsPos
++);
424 _CpyPara
aPara( *pCpyPara
, pBox
);
425 aPara
.nDelBorderFlag
&= 7;
427 ((_FndBox
*)rpFndBox
)->GetLines().ForEach( &lcl_CopyRow
, &aPara
);
431 ::_InsTblBox( pCpyPara
->pDoc
, pCpyPara
->pTblNd
, pCpyPara
->pInsLine
,
432 aFindFrm
.pNewFrmFmt
, pBox
, pCpyPara
->nInsPos
++ );
434 const _FndBoxes
& rFndBxs
= rpFndBox
->GetUpper()->GetBoxes();
435 if( 8 > pCpyPara
->nDelBorderFlag
436 ? pCpyPara
->nDelBorderFlag
437 : rpFndBox
== rFndBxs
[ rFndBxs
.Count() - 1 ] )
439 const SvxBoxItem
& rBoxItem
= pBox
->GetFrmFmt()->GetBox();
440 if( 8 > pCpyPara
->nDelBorderFlag
442 : rBoxItem
.GetRight() )
444 aFindFrm
.Value
.pFrmFmt
= (SwTableBoxFmt
*)pBox
->GetFrmFmt();
446 SvxBoxItem
aNew( rBoxItem
);
447 if( 8 > pCpyPara
->nDelBorderFlag
)
448 aNew
.SetLine( 0, BOX_LINE_TOP
);
450 aNew
.SetLine( 0, BOX_LINE_RIGHT
);
452 if( 1 == pCpyPara
->nDelBorderFlag
||
453 8 == pCpyPara
->nDelBorderFlag
)
455 // es wird dahinter kopiert, bei allen Boxen die
456 // TopBorderLine loeschen
457 pBox
= pCpyPara
->pInsLine
->GetTabBoxes()[
458 pCpyPara
->nInsPos
- 1 ];
461 aFindFrm
.pNewFrmFmt
= (SwTableBoxFmt
*)pBox
->GetFrmFmt();
463 // ansonsten wird davor kopiert und die erste Line behaelt
464 // die TopLine und an der originalen wird sie entfernt
465 pBox
->ClaimFrmFmt()->SetFmtAttr( aNew
);
467 if( !pCpyPara
->nCpyCnt
)
468 pCpyPara
->rTabFrmArr
.Insert( aFindFrm
);
475 BOOL
lcl_CopyRow( const _FndLine
*& rpFndLine
, void* pPara
)
477 _CpyPara
* pCpyPara
= (_CpyPara
*)pPara
;
478 SwTableLine
* pNewLine
= new SwTableLine(
479 (SwTableLineFmt
*)rpFndLine
->GetLine()->GetFrmFmt(),
480 rpFndLine
->GetBoxes().Count(), pCpyPara
->pInsBox
);
481 if( pCpyPara
->pInsBox
)
483 pCpyPara
->pInsBox
->GetTabLines().C40_INSERT( SwTableLine
, pNewLine
, pCpyPara
->nInsPos
++ );
487 pCpyPara
->pTblNd
->GetTable().GetTabLines().C40_INSERT( SwTableLine
, pNewLine
,
488 pCpyPara
->nInsPos
++ );
491 _CpyPara
aPara( *pCpyPara
, pNewLine
);
492 ((_FndLine
*)rpFndLine
)->GetBoxes().ForEach( &lcl_CopyCol
, &aPara
);
494 pCpyPara
->nDelBorderFlag
&= 0xf8;
498 //-----------------------------------------------------------
500 void lcl_InsCol( _FndLine
* pFndLn
, _CpyPara
& rCpyPara
, USHORT nCpyCnt
,
503 // Bug 29124: nicht nur in den Grundlines kopieren. Wenns geht, so weit
504 // runter wie moeglich.
506 if( 1 == pFndLn
->GetBoxes().Count() &&
507 !( pFBox
= pFndLn
->GetBoxes()[ 0 ] )->GetBox()->GetSttNd() )
509 // eine Box mit mehreren Lines, also in diese Lines einfuegen
510 for( USHORT n
= 0; n
< pFBox
->GetLines().Count(); ++n
)
511 lcl_InsCol( pFBox
->GetLines()[ n
], rCpyPara
, nCpyCnt
, bBehind
);
515 rCpyPara
.pInsLine
= pFndLn
->GetLine();
516 SwTableBox
* pBox
= pFndLn
->GetBoxes()[ bBehind
?
517 pFndLn
->GetBoxes().Count()-1 : 0 ]->GetBox();
518 rCpyPara
.nInsPos
= pFndLn
->GetLine()->GetTabBoxes().C40_GETPOS( SwTableBox
, pBox
);
522 for( USHORT n
= 0; n
< nCpyCnt
; ++n
)
524 if( n
+ 1 == nCpyCnt
&& bBehind
)
525 rCpyPara
.nDelBorderFlag
= 9;
527 rCpyPara
.nDelBorderFlag
= 8;
528 pFndLn
->GetBoxes().ForEach( &lcl_CopyCol
, &rCpyPara
);
533 SwRowFrm
* GetRowFrm( SwTableLine
& rLine
)
535 SwClientIter
aIter( *rLine
.GetFrmFmt() );
536 for( SwClient
* pFrm
= aIter
.First( TYPE( SwRowFrm
)); pFrm
;
537 pFrm
= aIter
.Next() )
538 if( ((SwRowFrm
*)pFrm
)->GetTabLine() == &rLine
)
539 return (SwRowFrm
*)pFrm
;
544 BOOL
SwTable::InsertCol( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
, BOOL bBehind
)
546 ASSERT( rBoxes
.Count() && nCnt
, "keine gueltige Box-Liste" );
547 SwTableNode
* pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
553 bRes
= NewInsertCol( pDoc
, rBoxes
, nCnt
, bBehind
);
556 // suche alle Boxen / Lines
557 _FndBox
aFndBox( 0, 0 );
559 _FndPara
aPara( rBoxes
, &aFndBox
);
560 GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
562 if( !aFndBox
.GetLines().Count() )
565 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
567 //Lines fuer das Layout-Update herausuchen.
568 aFndBox
.SetTableLines( *this );
569 aFndBox
.DelFrms( *this );
571 // TL_CHART2: nothing to be done since chart2 currently does not want to
572 // get notified about new rows/cols.
574 _CpyTabFrms aTabFrmArr
;
575 _CpyPara
aCpyPara( pTblNd
, nCnt
, aTabFrmArr
);
577 for( USHORT n
= 0; n
< aFndBox
.GetLines().Count(); ++n
)
578 lcl_InsCol( aFndBox
.GetLines()[ n
], aCpyPara
, nCnt
, bBehind
);
580 // dann raeume die Struktur dieser Line noch mal auf, generell alle
584 aFndBox
.MakeFrms( *this );
591 SwChartDataProvider
*pPCD
= pDoc
->GetChartDataProvider();
593 pPCD
->AddRowCols( *this, rBoxes
, nCnt
, bBehind
);
594 pDoc
->UpdateCharts( GetFrmFmt()->GetName() );
599 BOOL
SwTable::_InsertRow( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
,
600 USHORT nCnt
, BOOL bBehind
)
602 ASSERT( pDoc
&& rBoxes
.Count() && nCnt
, "keine gueltige Box-Liste" );
603 SwTableNode
* pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
607 // suche alle Boxen / Lines
608 _FndBox
aFndBox( 0, 0 );
610 _FndPara
aPara( rBoxes
, &aFndBox
);
611 GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
613 if( !aFndBox
.GetLines().Count() )
616 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
618 _FndBox
* pFndBox
= &aFndBox
;
621 while( 1 == pFndBox
->GetLines().Count() &&
622 1 == ( pFndLine
= pFndBox
->GetLines()[ 0 ])->GetBoxes().Count() )
624 // nicht zu weit runter, eine Line mit Boxen muss nachbleiben!!
625 _FndBox
* pTmpBox
= pFndLine
->GetBoxes()[ 0 ];
626 if( pTmpBox
->GetLines().Count() )
633 //Lines fuer das Layout-Update herausuchen.
634 const BOOL bLayout
= !IsNewModel() &&
635 0 != SwClientIter( *GetFrmFmt() ).First( TYPE(SwTabFrm
) );
639 aFndBox
.SetTableLines( *this );
640 if( pFndBox
!= &aFndBox
)
641 aFndBox
.DelFrms( *this );
642 // TL_CHART2: nothing to be done since chart2 currently does not want to
643 // get notified about new rows/cols.
646 _CpyTabFrms aTabFrmArr
;
647 _CpyPara
aCpyPara( pTblNd
, 0, aTabFrmArr
);
649 SwTableLine
* pLine
= pFndBox
->GetLines()[ bBehind
?
650 pFndBox
->GetLines().Count()-1 : 0 ]->GetLine();
651 if( &aFndBox
== pFndBox
)
652 aCpyPara
.nInsPos
= GetTabLines().C40_GETPOS( SwTableLine
, pLine
);
655 aCpyPara
.pInsBox
= pFndBox
->GetBox();
656 aCpyPara
.nInsPos
= pFndBox
->GetBox()->GetTabLines().C40_GETPOS( SwTableLine
, pLine
);
662 aCpyPara
.nDelBorderFlag
= 1;
665 aCpyPara
.nDelBorderFlag
= 2;
667 for( USHORT nCpyCnt
= 0; nCpyCnt
< nCnt
; ++nCpyCnt
)
670 aCpyPara
.nDelBorderFlag
= 1;
671 pFndBox
->GetLines().ForEach( &lcl_CopyRow
, &aCpyPara
);
674 // dann raeume die Struktur dieser Line noch mal auf, generell alle
675 if( !pDoc
->IsInReading() )
681 if( pFndBox
!= &aFndBox
)
682 aFndBox
.MakeFrms( *this );
684 aFndBox
.MakeNewFrms( *this, nCnt
, bBehind
);
690 SwChartDataProvider
*pPCD
= pDoc
->GetChartDataProvider();
692 pPCD
->AddRowCols( *this, rBoxes
, nCnt
, bBehind
);
693 pDoc
->UpdateCharts( GetFrmFmt()->GetName() );
698 BOOL
_FndBoxAppendRowLine( const SwTableLine
*& rpLine
, void* pPara
);
700 BOOL
_FndBoxAppendRowBox( const SwTableBox
*& rpBox
, void* pPara
)
702 _FndPara
* pFndPara
= (_FndPara
*)pPara
;
703 _FndBox
* pFndBox
= new _FndBox( (SwTableBox
*)rpBox
, pFndPara
->pFndLine
);
704 if( rpBox
->GetTabLines().Count() )
706 _FndPara
aPara( *pFndPara
, pFndBox
);
707 pFndBox
->GetBox()->GetTabLines().ForEach( &_FndBoxAppendRowLine
, &aPara
);
708 if( !pFndBox
->GetLines().Count() )
712 pFndPara
->pFndLine
->GetBoxes().C40_INSERT( _FndBox
, pFndBox
,
713 pFndPara
->pFndLine
->GetBoxes().Count() );
717 BOOL
_FndBoxAppendRowLine( const SwTableLine
*& rpLine
, void* pPara
)
719 _FndPara
* pFndPara
= (_FndPara
*)pPara
;
720 _FndLine
* pFndLine
= new _FndLine( (SwTableLine
*)rpLine
, pFndPara
->pFndBox
);
721 _FndPara
aPara( *pFndPara
, pFndLine
);
722 pFndLine
->GetLine()->GetTabBoxes().ForEach( &_FndBoxAppendRowBox
, &aPara
);
723 if( pFndLine
->GetBoxes().Count() )
725 pFndPara
->pFndBox
->GetLines().C40_INSERT( _FndLine
, pFndLine
,
726 pFndPara
->pFndBox
->GetLines().Count() );
734 BOOL
SwTable::AppendRow( SwDoc
* pDoc
, USHORT nCnt
)
736 SwTableNode
* pTblNd
= (SwTableNode
*)aSortCntBoxes
[0]->GetSttNd()->FindTableNode();
740 // suche alle Boxen / Lines
741 _FndBox
aFndBox( 0, 0 );
743 const SwTableLine
* pLLine
= GetTabLines()[ GetTabLines().Count()-1 ];
745 const SwSelBoxes
* pBxs
= 0; // Dummy !!!
746 _FndPara
aPara( *pBxs
, &aFndBox
);
748 _FndBoxAppendRowLine( pLLine
, &aPara
);
750 if( !aFndBox
.GetLines().Count() )
753 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
755 //Lines fuer das Layout-Update herausuchen.
756 const BOOL bLayout
= 0 != SwClientIter( *GetFrmFmt() ).First( TYPE(SwTabFrm
) );
759 aFndBox
.SetTableLines( *this );
760 // TL_CHART2: nothing to be done since chart2 currently does not want to
761 // get notified about new rows/cols.
764 _CpyTabFrms aTabFrmArr
;
765 _CpyPara
aCpyPara( pTblNd
, 0, aTabFrmArr
);
766 aCpyPara
.nInsPos
= GetTabLines().Count();
767 aCpyPara
.nDelBorderFlag
= 1;
769 for( USHORT nCpyCnt
= 0; nCpyCnt
< nCnt
; ++nCpyCnt
)
771 aCpyPara
.nDelBorderFlag
= 1;
772 aFndBox
.GetLines().ForEach( &lcl_CopyRow
, &aCpyPara
);
775 // dann raeume die Struktur dieser Line noch mal auf, generell alle
776 if( !pDoc
->IsInReading() )
782 aFndBox
.MakeNewFrms( *this, nCnt
, TRUE
);
784 // TL_CHART2: need to inform chart of probably changed cell names
785 pDoc
->UpdateCharts( GetFrmFmt()->GetName() );
794 void lcl_LastBoxSetWidth( SwTableBoxes
&rBoxes
, const long nOffset
,
795 BOOL bFirst
, SwShareBoxFmts
& rShareFmts
);
797 void lcl_LastBoxSetWidthLine( SwTableLines
&rLines
, const long nOffset
,
798 BOOL bFirst
, SwShareBoxFmts
& rShareFmts
)
800 for ( USHORT i
= 0; i
< rLines
.Count(); ++i
)
801 ::lcl_LastBoxSetWidth( rLines
[i
]->GetTabBoxes(), nOffset
, bFirst
,
805 void lcl_LastBoxSetWidth( SwTableBoxes
&rBoxes
, const long nOffset
,
806 BOOL bFirst
, SwShareBoxFmts
& rShareFmts
)
808 SwTableBox
& rBox
= *rBoxes
[ bFirst
? 0 : rBoxes
.Count() - 1 ];
809 if( !rBox
.GetSttNd() )
810 ::lcl_LastBoxSetWidthLine( rBox
.GetTabLines(), nOffset
,
811 bFirst
, rShareFmts
);
814 SwFrmFmt
*pBoxFmt
= rBox
.GetFrmFmt();
815 SwFmtFrmSize
aNew( pBoxFmt
->GetFrmSize() );
816 aNew
.SetWidth( aNew
.GetWidth() + nOffset
);
817 SwFrmFmt
*pFmt
= rShareFmts
.GetFormat( *pBoxFmt
, aNew
);
819 rBox
.ChgFrmFmt( (SwTableBoxFmt
*)pFmt
);
822 pFmt
= rBox
.ClaimFrmFmt();
825 pFmt
->SetFmtAttr( aNew
);
826 pFmt
->UnlockModify();
828 rShareFmts
.AddFormat( *pBoxFmt
, *pFmt
);
832 void _DeleteBox( SwTable
& rTbl
, SwTableBox
* pBox
, SwUndo
* pUndo
,
833 BOOL bCalcNewSize
, const BOOL bCorrBorder
,
834 SwShareBoxFmts
* pShareFmts
)
837 SwTwips nBoxSz
= bCalcNewSize
?
838 pBox
->GetFrmFmt()->GetFrmSize().GetWidth() : 0;
839 SwTableLine
* pLine
= pBox
->GetUpper();
840 SwTableBoxes
& rTblBoxes
= pLine
->GetTabBoxes();
841 USHORT nDelPos
= rTblBoxes
.C40_GETPOS( SwTableBox
, pBox
);
842 SwTableBox
* pUpperBox
= pBox
->GetUpper()->GetUpper();
844 // Sonderbehandlung fuer Umrandung:
845 if( bCorrBorder
&& 1 < rTblBoxes
.Count() )
848 const SvxBoxItem
& rBoxItem
= pBox
->GetFrmFmt()->GetBox();
850 if( rBoxItem
.GetLeft() || rBoxItem
.GetRight() )
852 //JP 02.04.97: 1.Teil fuer Bug 36271
853 // zuerst die linken/rechten Kanten
854 if( nDelPos
+ 1 < rTblBoxes
.Count() )
856 SwTableBox
* pNxtBox
= rTblBoxes
[ nDelPos
+ 1 ];
857 const SvxBoxItem
& rNxtBoxItem
= pNxtBox
->GetFrmFmt()->GetBox();
859 SwTableBox
* pPrvBox
= nDelPos
? rTblBoxes
[ nDelPos
- 1 ] : 0;
861 if( pNxtBox
->GetSttNd() && !rNxtBoxItem
.GetLeft() &&
862 ( !pPrvBox
|| !pPrvBox
->GetFrmFmt()->GetBox().GetRight()) )
864 SvxBoxItem
aTmp( rNxtBoxItem
);
865 aTmp
.SetLine( rBoxItem
.GetLeft() ? rBoxItem
.GetLeft()
866 : rBoxItem
.GetRight(),
869 pShareFmts
->SetAttr( *pNxtBox
, aTmp
);
871 pNxtBox
->ClaimFrmFmt()->SetFmtAttr( aTmp
);
875 if( !bChgd
&& nDelPos
)
877 SwTableBox
* pPrvBox
= rTblBoxes
[ nDelPos
- 1 ];
878 const SvxBoxItem
& rPrvBoxItem
= pPrvBox
->GetFrmFmt()->GetBox();
880 SwTableBox
* pNxtBox
= nDelPos
+ 1 < rTblBoxes
.Count()
881 ? rTblBoxes
[ nDelPos
+ 1 ] : 0;
883 if( pPrvBox
->GetSttNd() && !rPrvBoxItem
.GetRight() &&
884 ( !pNxtBox
|| !pNxtBox
->GetFrmFmt()->GetBox().GetLeft()) )
886 SvxBoxItem
aTmp( rPrvBoxItem
);
887 aTmp
.SetLine( rBoxItem
.GetLeft() ? rBoxItem
.GetLeft()
888 : rBoxItem
.GetRight(),
891 pShareFmts
->SetAttr( *pPrvBox
, aTmp
);
893 pPrvBox
->ClaimFrmFmt()->SetFmtAttr( aTmp
);
900 // erst die Box, dann die Nodes loeschen!!
901 SwStartNode
* pSttNd
= (SwStartNode
*)pBox
->GetSttNd();
903 pShareFmts
->RemoveFormat( *rTblBoxes
[ nDelPos
]->GetFrmFmt() );
904 rTblBoxes
.DeleteAndDestroy( nDelPos
);
908 // ist das UndoObject zum speichern der Section vorbereitet?
909 if( pUndo
&& pUndo
->IsDelBox() )
910 ((SwUndoTblNdsChg
*)pUndo
)->SaveSection( pSttNd
);
912 pSttNd
->GetDoc()->DeleteSection( pSttNd
);
915 // auch die Zeile noch loeschen ??
916 if( rTblBoxes
.Count() )
918 // dann passe noch die Frame-SSize an
919 BOOL bLastBox
= nDelPos
== rTblBoxes
.Count();
922 pBox
= rTblBoxes
[nDelPos
];
925 SwFmtFrmSize
aNew( pBox
->GetFrmFmt()->GetFrmSize() );
926 aNew
.SetWidth( aNew
.GetWidth() + nBoxSz
);
928 pShareFmts
->SetSize( *pBox
, aNew
);
930 pBox
->ClaimFrmFmt()->SetFmtAttr( aNew
);
932 if( !pBox
->GetSttNd() )
934 // dann muss es auch rekursiv in allen Zeilen, in allen
936 SwShareBoxFmts aShareFmts
;
937 ::lcl_LastBoxSetWidthLine( pBox
->GetTabLines(), nBoxSz
,
939 pShareFmts
? *pShareFmts
943 break; // nichts mehr loeschen
945 // loesche die Line aus Tabelle/Box
948 // dann loesche auch noch die Line aus der Tabelle
949 nDelPos
= rTbl
.GetTabLines().C40_GETPOS( SwTableLine
, pLine
);
951 pShareFmts
->RemoveFormat( *rTbl
.GetTabLines()[ nDelPos
]->GetFrmFmt() );
952 rTbl
.GetTabLines().DeleteAndDestroy( nDelPos
);
953 break; // mehr kann nicht geloescht werden
956 // dann loesche auch noch die Line
958 nDelPos
= pBox
->GetTabLines().C40_GETPOS( SwTableLine
, pLine
);
960 pShareFmts
->RemoveFormat( *pBox
->GetTabLines()[ nDelPos
]->GetFrmFmt() );
961 pBox
->GetTabLines().DeleteAndDestroy( nDelPos
);
962 } while( !pBox
->GetTabLines().Count() );
965 SwTableBox
* lcl_FndNxtPrvDelBox( const SwTableLines
& rTblLns
,
966 SwTwips nBoxStt
, SwTwips nBoxWidth
,
967 USHORT nLinePos
, BOOL bNxt
,
968 SwSelBoxes
* pAllDelBoxes
, USHORT
* pCurPos
)
970 SwTableBox
* pFndBox
= 0;
976 SwTableLine
* pLine
= rTblLns
[ nLinePos
];
977 SwTwips nFndBoxWidth
= 0;
978 SwTwips nFndWidth
= nBoxStt
+ nBoxWidth
;
979 USHORT nBoxCnt
= pLine
->GetTabBoxes().Count();
981 pFndBox
= pLine
->GetTabBoxes()[ 0 ];
982 for( USHORT n
= 0; 0 < nFndWidth
&& n
< nBoxCnt
; ++n
)
984 pFndBox
= pLine
->GetTabBoxes()[ n
];
985 nFndWidth
-= (nFndBoxWidth
= pFndBox
->GetFrmFmt()->
986 GetFrmSize().GetWidth());
989 // suche die erste ContentBox
990 while( !pFndBox
->GetSttNd() )
992 const SwTableLines
& rLowLns
= pFndBox
->GetTabLines();
994 pFndBox
= rLowLns
[ 0 ]->GetTabBoxes()[ 0 ];
996 pFndBox
= rLowLns
[ rLowLns
.Count() - 1 ]->GetTabBoxes()[ 0 ];
999 if( Abs( nFndWidth
) > COLFUZZY
||
1000 Abs( nBoxWidth
- nFndBoxWidth
) > COLFUZZY
)
1002 else if( pAllDelBoxes
)
1004 // falls der Vorganger auch geloscht wird, ist nicht zu tun
1006 if( !pAllDelBoxes
->Seek_Entry( pFndBox
, &nFndPos
) )
1009 // sonst noch mal weitersuchen
1010 // Die Box muessen wir aber nicht nochmal abpruefen
1012 if( nFndPos
<= *pCurPos
)
1014 pAllDelBoxes
->Remove( nFndPos
);
1016 } while( bNxt
? ( nLinePos
+ 1 < rTblLns
.Count() ) : nLinePos
);
1020 void lcl_SaveUpperLowerBorder( SwTable
& rTbl
, const SwTableBox
& rBox
,
1021 SwShareBoxFmts
& rShareFmts
,
1022 SwSelBoxes
* pAllDelBoxes
= 0,
1023 USHORT
* pCurPos
= 0 )
1025 //JP 16.04.97: 2.Teil fuer Bug 36271
1027 const SwTableLine
* pLine
= rBox
.GetUpper();
1028 const SwTableBoxes
& rTblBoxes
= pLine
->GetTabBoxes();
1029 const SwTableBox
* pUpperBox
= &rBox
;
1030 USHORT nDelPos
= rTblBoxes
.C40_GETPOS( SwTableBox
, pUpperBox
);
1031 pUpperBox
= rBox
.GetUpper()->GetUpper();
1032 const SvxBoxItem
& rBoxItem
= rBox
.GetFrmFmt()->GetBox();
1034 // dann die unteren/oberen Kanten
1035 if( rBoxItem
.GetTop() || rBoxItem
.GetBottom() )
1038 const SwTableLines
* pTblLns
;
1040 pTblLns
= &pUpperBox
->GetTabLines();
1042 pTblLns
= &rTbl
.GetTabLines();
1044 USHORT nLnPos
= pTblLns
->GetPos( pLine
);
1046 // bestimme die Attr.Position der akt. zu loeschenden Box
1047 // und suche dann in der unteren / oberen Line die entspr.
1049 SwTwips nBoxStt
= 0;
1050 for( USHORT n
= 0; n
< nDelPos
; ++n
)
1051 nBoxStt
+= rTblBoxes
[ n
]->GetFrmFmt()->GetFrmSize().GetWidth();
1052 SwTwips nBoxWidth
= rBox
.GetFrmFmt()->GetFrmSize().GetWidth();
1054 SwTableBox
*pPrvBox
= 0, *pNxtBox
= 0;
1055 if( nLnPos
) // Vorgaenger?
1056 pPrvBox
= ::lcl_FndNxtPrvDelBox( *pTblLns
, nBoxStt
, nBoxWidth
,
1057 nLnPos
, FALSE
, pAllDelBoxes
, pCurPos
);
1059 if( nLnPos
+ 1 < pTblLns
->Count() ) // Nachfolger?
1060 pNxtBox
= ::lcl_FndNxtPrvDelBox( *pTblLns
, nBoxStt
, nBoxWidth
,
1061 nLnPos
, TRUE
, pAllDelBoxes
, pCurPos
);
1063 if( pNxtBox
&& pNxtBox
->GetSttNd() )
1065 const SvxBoxItem
& rNxtBoxItem
= pNxtBox
->GetFrmFmt()->GetBox();
1066 if( !rNxtBoxItem
.GetTop() && ( !pPrvBox
||
1067 !pPrvBox
->GetFrmFmt()->GetBox().GetBottom()) )
1069 SvxBoxItem
aTmp( rNxtBoxItem
);
1070 aTmp
.SetLine( rBoxItem
.GetTop() ? rBoxItem
.GetTop()
1071 : rBoxItem
.GetBottom(),
1073 rShareFmts
.SetAttr( *pNxtBox
, aTmp
);
1077 if( !bChgd
&& pPrvBox
&& pPrvBox
->GetSttNd() )
1079 const SvxBoxItem
& rPrvBoxItem
= pPrvBox
->GetFrmFmt()->GetBox();
1080 if( !rPrvBoxItem
.GetTop() && ( !pNxtBox
||
1081 !pNxtBox
->GetFrmFmt()->GetBox().GetTop()) )
1083 SvxBoxItem
aTmp( rPrvBoxItem
);
1084 aTmp
.SetLine( rBoxItem
.GetTop() ? rBoxItem
.GetTop()
1085 : rBoxItem
.GetBottom(),
1087 rShareFmts
.SetAttr( *pPrvBox
, aTmp
);
1095 BOOL
SwTable::DeleteSel(
1098 const SwSelBoxes
& rBoxes
,
1099 const SwSelBoxes
* pMerged
, SwUndo
* pUndo
,
1100 const BOOL bDelMakeFrms
, const BOOL bCorrBorder
)
1102 ASSERT( pDoc
, "No doc?" );
1103 SwTableNode
* pTblNd
= 0;
1104 if( rBoxes
.Count() )
1106 pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
1111 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
1113 //Lines fuer das Layout-Update herausuchen.
1114 _FndBox
aFndBox( 0, 0 );
1117 if( pMerged
&& pMerged
->Count() )
1118 aFndBox
.SetTableLines( *pMerged
, *this );
1119 else if( rBoxes
.Count() )
1120 aFndBox
.SetTableLines( rBoxes
, *this );
1121 aFndBox
.DelFrms( *this );
1124 SwShareBoxFmts aShareFmts
;
1126 // erst die Umrandung umsetzen, dann loeschen
1130 aBoxes
.Insert( &rBoxes
);
1131 for( USHORT n
= 0; n
< aBoxes
.Count(); ++n
)
1132 ::lcl_SaveUpperLowerBorder( *this, *rBoxes
[ n
], aShareFmts
,
1136 PrepareDelBoxes( rBoxes
);
1138 SwChartDataProvider
*pPCD
= pDoc
->GetChartDataProvider();
1140 // delete boxes from last to first
1141 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1143 USHORT nIdx
= rBoxes
.Count() - 1 - n
;
1145 // first adapt the data-sequence for chart if necessary
1146 // (needed to move the implementation cursor properly to it's new
1147 // position which can't be done properly if the cell is already gone)
1149 pPCD
->DeleteBox( &pTblNd
->GetTable(), *rBoxes
[nIdx
] );
1151 // ... then delete the boxes
1152 _DeleteBox( *this, rBoxes
[nIdx
], pUndo
, TRUE
, bCorrBorder
, &aShareFmts
);
1155 // dann raeume die Struktur aller Lines auf
1158 if( bDelMakeFrms
&& aFndBox
.AreLinesToRestore( *this ) )
1159 aFndBox
.MakeFrms( *this );
1161 // TL_CHART2: now inform chart that sth has changed
1162 pDoc
->UpdateCharts( GetFrmFmt()->GetName() );
1165 CHECK_TABLE( *this )
1171 // ---------------------------------------------------------------
1173 BOOL
SwTable::OldSplitRow( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
,
1176 ASSERT( pDoc
&& rBoxes
.Count() && nCnt
, "keine gueltigen Werte" );
1177 SwTableNode
* pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
1181 // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1182 // the table to complex to be handled with chart.
1183 // Thus we tell the charts to use their own data provider and forget about this table
1184 pDoc
->CreateChartInternalDataProviders( this );
1186 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
1188 // If the rows should get the same (min) height, we first have
1189 // to store the old row heights before deleting the frames
1190 long* pRowHeights
= 0;
1193 pRowHeights
= new long[ rBoxes
.Count() ];
1194 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1196 SwTableBox
* pSelBox
= *( rBoxes
.GetData() + n
);
1197 const SwRowFrm
* pRow
= GetRowFrm( *pSelBox
->GetUpper() );
1198 ASSERT( pRow
, "wo ist der Frm von der SwTableLine?" )
1200 pRowHeights
[ n
] = (pRow
->Frm().*fnRect
->fnGetHeight
)();
1204 //Lines fuer das Layout-Update herausuchen.
1205 _FndBox
aFndBox( 0, 0 );
1206 aFndBox
.SetTableLines( rBoxes
, *this );
1207 aFndBox
.DelFrms( *this );
1209 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
1211 SwTableBox
* pSelBox
= *( rBoxes
.GetData() + n
);
1212 ASSERT( pSelBox
, "Box steht nicht in der Tabelle" );
1214 // dann fuege in die Box nCnt neue Zeilen ein
1215 SwTableLine
* pInsLine
= pSelBox
->GetUpper();
1216 SwTableBoxFmt
* pFrmFmt
= (SwTableBoxFmt
*)pSelBox
->GetFrmFmt();
1218 // Hoehe der Line beachten, gegebenenfalls neu setzen
1219 SwFmtFrmSize
aFSz( pInsLine
->GetFrmFmt()->GetFrmSize() );
1220 if ( bSameHeight
&& ATT_VAR_SIZE
== aFSz
.GetHeightSizeType() )
1221 aFSz
.SetHeightSizeType( ATT_MIN_SIZE
);
1223 BOOL bChgLineSz
= 0 != aFSz
.GetHeight() || bSameHeight
;
1225 aFSz
.SetHeight( ( bSameHeight
? pRowHeights
[ n
] : aFSz
.GetHeight() ) /
1228 SwTableBox
* pNewBox
= new SwTableBox( pFrmFmt
, nCnt
, pInsLine
);
1229 USHORT nBoxPos
= pInsLine
->GetTabBoxes().C40_GETPOS( SwTableBox
, pSelBox
);
1230 pInsLine
->GetTabBoxes().Remove( nBoxPos
); // alte loeschen
1231 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pNewBox
, nBoxPos
);
1233 // Hintergrund- / Rand Attribut loeschen
1234 SwTableBox
* pLastBox
= pSelBox
; // zum verteilen der TextNodes !!
1235 // sollte Bereiche in der Box stehen, dann bleibt sie so bestehen
1236 // !! FALLS DAS GEAENDERT WIRD MUSS DAS UNDO ANGEPASST WERDEN !!!
1237 BOOL bMoveNodes
= TRUE
;
1239 ULONG nSttNd
= pLastBox
->GetSttIdx() + 1,
1240 nEndNd
= pLastBox
->GetSttNd()->EndOfSectionIndex();
1241 while( nSttNd
< nEndNd
)
1242 if( !pDoc
->GetNodes()[ nSttNd
++ ]->IsTxtNode() )
1249 SwTableBoxFmt
* pCpyBoxFrmFmt
= (SwTableBoxFmt
*)pSelBox
->GetFrmFmt();
1250 BOOL bChkBorder
= 0 != pCpyBoxFrmFmt
->GetBox().GetTop();
1252 pCpyBoxFrmFmt
= (SwTableBoxFmt
*)pSelBox
->ClaimFrmFmt();
1254 for( USHORT i
= 0; i
<= nCnt
; ++i
)
1256 // also erstmal eine neue Linie in der neuen Box
1257 SwTableLine
* pNewLine
= new SwTableLine(
1258 (SwTableLineFmt
*)pInsLine
->GetFrmFmt(), 1, pNewBox
);
1261 pNewLine
->ClaimFrmFmt()->SetFmtAttr( aFSz
);
1264 pNewBox
->GetTabLines().C40_INSERT( SwTableLine
, pNewLine
, i
);
1265 // dann eine neue Box in der Line
1266 if( !i
) // haenge die originale Box ein
1268 pSelBox
->SetUpper( pNewLine
);
1269 pNewLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pSelBox
, 0 );
1273 ::_InsTblBox( pDoc
, pTblNd
, pNewLine
, pCpyBoxFrmFmt
,
1278 pCpyBoxFrmFmt
= (SwTableBoxFmt
*)pNewLine
->GetTabBoxes()[ 0 ]->ClaimFrmFmt();
1279 SvxBoxItem
aTmp( pCpyBoxFrmFmt
->GetBox() );
1280 aTmp
.SetLine( 0, BOX_LINE_TOP
);
1281 pCpyBoxFrmFmt
->SetFmtAttr( aTmp
);
1287 const SwNode
* pEndNd
= pLastBox
->GetSttNd()->EndOfSectionNode();
1288 if( pLastBox
->GetSttIdx()+2 != pEndNd
->GetIndex() )
1290 // TextNodes verschieben
1291 SwNodeRange
aRg( *pLastBox
->GetSttNd(), +2, *pEndNd
);
1292 pLastBox
= pNewLine
->GetTabBoxes()[0]; // neu setzen
1293 SwNodeIndex
aInsPos( *pLastBox
->GetSttNd(), 1 );
1294 pDoc
->GetNodes()._MoveNodes(aRg
, pDoc
->GetNodes(), aInsPos
, FALSE
);
1295 pDoc
->GetNodes().Delete( aInsPos
, 1 ); // den leeren noch loeschen
1300 // in Boxen mit Lines darf es nur noch Size/Fillorder geben
1301 pFrmFmt
= (SwTableBoxFmt
*)pNewBox
->ClaimFrmFmt();
1302 pFrmFmt
->ResetFmtAttr( RES_LR_SPACE
, RES_FRMATR_END
- 1 );
1303 pFrmFmt
->ResetFmtAttr( RES_BOXATR_BEGIN
, RES_BOXATR_END
- 1 );
1306 delete[] pRowHeights
;
1310 aFndBox
.MakeFrms( *this );
1317 BOOL
SwTable::SplitCol( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
, USHORT nCnt
)
1319 ASSERT( pDoc
&& rBoxes
.Count() && nCnt
, "keine gueltigen Werte" );
1320 SwTableNode
* pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
1324 // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1325 // the table to complex to be handled with chart.
1326 // Thus we tell the charts to use their own data provider and forget about this table
1327 pDoc
->CreateChartInternalDataProviders( this );
1329 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
1330 SwSelBoxes aSelBoxes
;
1331 aSelBoxes
.Insert(rBoxes
.GetData(), rBoxes
.Count());
1332 ExpandSelection( aSelBoxes
);
1334 //Lines fuer das Layout-Update herausuchen.
1335 _FndBox
aFndBox( 0, 0 );
1336 aFndBox
.SetTableLines( aSelBoxes
, *this );
1337 aFndBox
.DelFrms( *this );
1339 _CpyTabFrms aFrmArr
;
1340 SvPtrarr aLastBoxArr
;
1342 for( USHORT n
= 0; n
< aSelBoxes
.Count(); ++n
)
1344 SwTableBox
* pSelBox
= *( aSelBoxes
.GetData() + n
);
1345 ASSERT( pSelBox
, "Box steht nicht in der Tabelle" );
1347 // We don't want to split small table cells into very very small cells
1348 if( pSelBox
->GetFrmFmt()->GetFrmSize().GetWidth()/( nCnt
+ 1 ) < 10 )
1351 // dann teile die Box nCnt in nCnt Boxen
1352 SwTableLine
* pInsLine
= pSelBox
->GetUpper();
1353 USHORT nBoxPos
= pInsLine
->GetTabBoxes().C40_GETPOS( SwTableBox
, pSelBox
);
1355 // suche das FrmFmt im Array aller Frame-Formate
1356 SwTableBoxFmt
* pLastBoxFmt
;
1357 _CpyTabFrm
aFindFrm( (SwTableBoxFmt
*)pSelBox
->GetFrmFmt() );
1358 if( !aFrmArr
.Seek_Entry( aFindFrm
, &nFndPos
))
1360 // aender das FrmFmt
1361 aFindFrm
.pNewFrmFmt
= (SwTableBoxFmt
*)pSelBox
->ClaimFrmFmt();
1362 SwTwips nBoxSz
= aFindFrm
.pNewFrmFmt
->GetFrmSize().GetWidth();
1363 SwTwips nNewBoxSz
= nBoxSz
/ ( nCnt
+ 1 );
1364 aFindFrm
.pNewFrmFmt
->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE
,
1366 aFrmArr
.Insert( aFindFrm
);
1368 pLastBoxFmt
= aFindFrm
.pNewFrmFmt
;
1369 if( nBoxSz
!= ( nNewBoxSz
* (nCnt
+ 1)))
1371 // es bleibt ein Rest, also muss fuer die letzte Box ein
1372 // eigenes Format definiert werden
1373 pLastBoxFmt
= new SwTableBoxFmt( *aFindFrm
.pNewFrmFmt
);
1374 pLastBoxFmt
->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE
,
1375 nBoxSz
- ( nNewBoxSz
* nCnt
), 0 ) );
1377 void* p
= pLastBoxFmt
;
1378 aLastBoxArr
.Insert( p
, nFndPos
);
1382 aFindFrm
= aFrmArr
[ nFndPos
];
1383 pSelBox
->ChgFrmFmt( (SwTableBoxFmt
*)aFindFrm
.pNewFrmFmt
);
1384 pLastBoxFmt
= (SwTableBoxFmt
*)aLastBoxArr
[ nFndPos
];
1387 // dann fuege mal an der Position die neuen Boxen ein
1388 for( USHORT i
= 1; i
< nCnt
; ++i
)
1389 ::_InsTblBox( pDoc
, pTblNd
, pInsLine
, aFindFrm
.pNewFrmFmt
,
1390 pSelBox
, nBoxPos
+ i
); // dahinter einfuegen
1392 ::_InsTblBox( pDoc
, pTblNd
, pInsLine
, pLastBoxFmt
,
1393 pSelBox
, nBoxPos
+ nCnt
); // dahinter einfuegen
1395 // Sonderbehandlung fuer die Umrandung:
1396 const SvxBoxItem
& aSelBoxItem
= aFindFrm
.pNewFrmFmt
->GetBox();
1397 if( aSelBoxItem
.GetRight() )
1399 pInsLine
->GetTabBoxes()[ nBoxPos
+ nCnt
]->ClaimFrmFmt();
1401 SvxBoxItem
aTmp( aSelBoxItem
);
1402 aTmp
.SetLine( 0, BOX_LINE_RIGHT
);
1403 aFindFrm
.pNewFrmFmt
->SetFmtAttr( aTmp
);
1405 // und dann das Format aus dem "cache" entfernen
1406 for( USHORT i
= aFrmArr
.Count(); i
; )
1408 const _CpyTabFrm
& rCTF
= aFrmArr
[ --i
];
1409 if( rCTF
.pNewFrmFmt
== aFindFrm
.pNewFrmFmt
||
1410 rCTF
.Value
.pFrmFmt
== aFindFrm
.pNewFrmFmt
)
1412 aFrmArr
.Remove( i
);
1413 aLastBoxArr
.Remove( i
);
1420 aFndBox
.MakeFrms( *this );
1427 // ---------------------------------------------------------------
1430 ----------------------- >> MERGE << ------------------------
1432 ist in der _FndBox nur eine Line angegeben, nehme die Line
1433 und teste die Anzahl der Boxen
1434 - ist mehr als 1 Box angegeben, so wird auf Boxenebene zusammen-
1435 gefasst, d.H. die neue Box wird so Breit wie die alten.
1436 - Alle Lines die ueber/unter dem Bereich liegen werden in die
1437 Box als Line + Box mit Lines eingefuegt
1438 - Alle Lines die vor/hinter dem Bereich liegen werden in
1439 die Boxen Left/Right eingetragen
1441 ----------------------- >> MERGE << ------------------------
1444 void lcl_CpyLines( USHORT nStt
, USHORT nEnd
,
1445 SwTableLines
& rLines
,
1446 SwTableBox
* pInsBox
,
1447 USHORT nPos
= USHRT_MAX
)
1449 for( USHORT n
= nStt
; n
< nEnd
; ++n
)
1450 rLines
[n
]->SetUpper( pInsBox
);
1451 if( USHRT_MAX
== nPos
)
1452 nPos
= pInsBox
->GetTabLines().Count();
1453 pInsBox
->GetTabLines().Insert( &rLines
, nPos
, nStt
, nEnd
);
1454 rLines
.Remove( nStt
, nEnd
- nStt
);
1457 void lcl_CpyBoxes( USHORT nStt
, USHORT nEnd
,
1458 SwTableBoxes
& rBoxes
,
1459 SwTableLine
* pInsLine
,
1460 USHORT nPos
= USHRT_MAX
)
1462 for( USHORT n
= nStt
; n
< nEnd
; ++n
)
1463 rBoxes
[n
]->SetUpper( pInsLine
);
1464 if( USHRT_MAX
== nPos
)
1465 nPos
= pInsLine
->GetTabBoxes().Count();
1466 pInsLine
->GetTabBoxes().Insert( &rBoxes
, nPos
, nStt
, nEnd
);
1467 rBoxes
.Remove( nStt
, nEnd
- nStt
);
1470 void lcl_CalcWidth( SwTableBox
* pBox
)
1472 // Annahme: jede Line in der Box ist gleich gross
1473 SwFrmFmt
* pFmt
= pBox
->ClaimFrmFmt();
1474 ASSERT( pBox
->GetTabLines().Count(), "Box hat keine Lines" );
1476 SwTableLine
* pLine
= pBox
->GetTabLines()[0];
1477 ASSERT( pLine
, "Box steht in keiner Line" );
1480 for( USHORT n
= 0; n
< pLine
->GetTabBoxes().Count(); ++n
)
1481 nWidth
+= pLine
->GetTabBoxes()[n
]->GetFrmFmt()->GetFrmSize().GetWidth();
1483 pFmt
->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE
, nWidth
, 0 ));
1485 // in Boxen mit Lines darf es nur noch Size/Fillorder geben
1486 pFmt
->ResetFmtAttr( RES_LR_SPACE
, RES_FRMATR_END
- 1 );
1487 pFmt
->ResetFmtAttr( RES_BOXATR_BEGIN
, RES_BOXATR_END
- 1 );
1494 SwTableNode
* pTblNd
;
1495 SwTableLine
* pInsLine
;
1496 SwTableBox
* pInsBox
;
1497 BOOL bUL_LR
: 1; // Upper-Lower(TRUE) oder Left-Right(FALSE) ?
1498 BOOL bUL
: 1; // Upper-Left(TRUE) oder Lower-Right(FALSE) ?
1500 SwTableBox
* pLeftBox
;
1501 SwTableBox
* pRightBox
;
1502 SwTableBox
* pMergeBox
;
1504 _InsULPara( SwTableNode
* pTNd
, BOOL bUpperLower
, BOOL bUpper
,
1505 SwTableBox
* pLeft
, SwTableBox
* pMerge
, SwTableBox
* pRight
,
1506 SwTableLine
* pLine
=0, SwTableBox
* pBox
=0 )
1507 : pTblNd( pTNd
), pInsLine( pLine
), pInsBox( pBox
),
1508 pLeftBox( pLeft
), pRightBox( pRight
), pMergeBox( pMerge
)
1509 { bUL_LR
= bUpperLower
; bUL
= bUpper
; }
1511 void SetLeft( SwTableBox
* pBox
=0 )
1512 { bUL_LR
= FALSE
; bUL
= TRUE
; if( pBox
) pInsBox
= pBox
; }
1513 void SetRight( SwTableBox
* pBox
=0 )
1514 { bUL_LR
= FALSE
; bUL
= FALSE
; if( pBox
) pInsBox
= pBox
; }
1515 void SetUpper( SwTableLine
* pLine
=0 )
1516 { bUL_LR
= TRUE
; bUL
= TRUE
; if( pLine
) pInsLine
= pLine
; }
1517 void SetLower( SwTableLine
* pLine
=0 )
1518 { bUL_LR
= TRUE
; bUL
= FALSE
; if( pLine
) pInsLine
= pLine
; }
1522 BOOL
lcl_Merge_MoveBox( const _FndBox
*& rpFndBox
, void* pPara
)
1524 _InsULPara
* pULPara
= (_InsULPara
*)pPara
;
1525 SwTableBoxes
* pBoxes
;
1527 USHORT nStt
= 0, nEnd
= rpFndBox
->GetLines().Count();
1528 USHORT nInsPos
= USHRT_MAX
;
1529 if( !pULPara
->bUL_LR
) // Left/Right
1532 SwTableBox
* pFndBox
= (SwTableBox
*)rpFndBox
->GetBox();
1533 pBoxes
= &pFndBox
->GetUpper()->GetTabBoxes();
1534 if( pULPara
->bUL
) // Left ?
1536 // gibt es noch davor Boxen, dann move sie
1537 if( 0 != ( nPos
= pBoxes
->C40_GETPOS( SwTableBox
, pFndBox
)) )
1538 lcl_CpyBoxes( 0, nPos
, *pBoxes
, pULPara
->pInsLine
);
1541 // gibt es noch dahinter Boxen, dann move sie
1542 if( (nPos
= pBoxes
->C40_GETPOS( SwTableBox
, pFndBox
)) +1 < pBoxes
->Count() )
1544 nInsPos
= pULPara
->pInsLine
->GetTabBoxes().Count();
1545 lcl_CpyBoxes( nPos
+1, pBoxes
->Count(),
1546 *pBoxes
, pULPara
->pInsLine
);
1549 // Upper/Lower und gehts noch tiefer ??
1550 else if( rpFndBox
->GetLines().Count() )
1552 // suche nur die Line, ab der Verschoben werden muss
1553 nStt
= pULPara
->bUL
? 0 : rpFndBox
->GetLines().Count()-1;
1557 pBoxes
= &pULPara
->pInsLine
->GetTabBoxes();
1559 // geht es noch eine weitere Stufe runter?
1560 if( rpFndBox
->GetBox()->GetTabLines().Count() )
1562 SwTableBox
* pBox
= new SwTableBox(
1563 (SwTableBoxFmt
*)rpFndBox
->GetBox()->GetFrmFmt(), 0, pULPara
->pInsLine
);
1564 _InsULPara
aPara( *pULPara
);
1565 aPara
.pInsBox
= pBox
;
1566 ((_FndBox
*)rpFndBox
)->GetLines().ForEach( nStt
, nEnd
,
1567 &lcl_Merge_MoveLine
, &aPara
);
1568 if( pBox
->GetTabLines().Count() )
1570 if( USHRT_MAX
== nInsPos
)
1571 nInsPos
= pBoxes
->Count();
1572 pBoxes
->C40_INSERT( SwTableBox
, pBox
, nInsPos
);
1573 lcl_CalcWidth( pBox
); // bereche die Breite der Box
1581 BOOL
lcl_Merge_MoveLine( const _FndLine
*& rpFndLine
, void* pPara
)
1583 _InsULPara
* pULPara
= (_InsULPara
*)pPara
;
1584 SwTableLines
* pLines
;
1586 USHORT nStt
= 0, nEnd
= rpFndLine
->GetBoxes().Count();
1587 USHORT nInsPos
= USHRT_MAX
;
1588 if( pULPara
->bUL_LR
) // UpperLower ?
1591 SwTableLine
* pFndLn
= (SwTableLine
*)rpFndLine
->GetLine();
1592 pLines
= pFndLn
->GetUpper() ?
1593 &pFndLn
->GetUpper()->GetTabLines() :
1594 &pULPara
->pTblNd
->GetTable().GetTabLines();
1596 SwTableBox
* pLBx
= rpFndLine
->GetBoxes()[0]->GetBox();
1597 SwTableBox
* pRBx
= rpFndLine
->GetBoxes()[
1598 rpFndLine
->GetBoxes().Count()-1]->GetBox();
1599 USHORT nLeft
= pFndLn
->GetTabBoxes().C40_GETPOS( SwTableBox
, pLBx
);
1600 USHORT nRight
= pFndLn
->GetTabBoxes().C40_GETPOS( SwTableBox
, pRBx
);
1602 // if( ( nLeft && nRight+1 < pFndLn->GetTabBoxes().Count() ) ||
1603 // ( !nLeft && nRight+1 >= pFndLn->GetTabBoxes().Count() ) )
1604 if( !nLeft
|| nRight
== pFndLn
->GetTabBoxes().Count() )
1606 if( pULPara
->bUL
) // Upper ?
1608 // gibt es noch davor Zeilen, dann move sie
1609 if( 0 != ( nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) )
1610 lcl_CpyLines( 0, nPos
, *pLines
, pULPara
->pInsBox
);
1613 // gibt es noch dahinter Zeilen, dann move sie
1614 if( (nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) +1 < pLines
->Count() )
1616 nInsPos
= pULPara
->pInsBox
->GetTabLines().Count();
1617 lcl_CpyLines( nPos
+1, pLines
->Count(), *pLines
,
1623 // es gibt links noch weitere Boxen, also setze Left-
1624 // und Merge-Box in eine Box und Line, fuege davor/dahinter
1625 // eine Line mit Box ein, in die die oberen/unteren Lines
1626 // eingefuegt werden
1627 SwTableLine
* pInsLine
= pULPara
->pLeftBox
->GetUpper();
1628 SwTableBox
* pLMBox
= new SwTableBox(
1629 (SwTableBoxFmt
*)pULPara
->pLeftBox
->GetFrmFmt(), 0, pInsLine
);
1630 SwTableLine
* pLMLn
= new SwTableLine(
1631 (SwTableLineFmt
*)pInsLine
->GetFrmFmt(), 2, pLMBox
);
1632 pLMLn
->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE
);
1634 pLMBox
->GetTabLines().C40_INSERT( SwTableLine
, pLMLn
, 0 );
1636 lcl_CpyBoxes( 0, 2, pInsLine
->GetTabBoxes(), pLMLn
);
1638 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pLMBox
, 0 );
1640 if( pULPara
->bUL
) // Upper ?
1642 // gibt es noch davor Zeilen, dann move sie
1643 if( 0 != ( nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) )
1644 lcl_CpyLines( 0, nPos
, *pLines
, pLMBox
, 0 );
1647 // gibt es noch dahinter Zeilen, dann move sie
1648 if( (nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) +1 < pLines
->Count() )
1649 lcl_CpyLines( nPos
+1, pLines
->Count(), *pLines
,
1651 lcl_CalcWidth( pLMBox
); // bereche die Breite der Box
1653 else if( nRight
+1 < pFndLn
->GetTabBoxes().Count() )
1655 // es gibt rechts noch weitere Boxen, also setze Right-
1656 // und Merge-Box in eine Box und Line, fuege davor/dahinter
1657 // eine Line mit Box ein, in die die oberen/unteren Lines
1658 // eingefuegt werden
1659 SwTableLine
* pInsLine
= pULPara
->pRightBox
->GetUpper();
1661 if( pULPara
->pLeftBox
->GetUpper() == pInsLine
)
1663 pRMBox
= new SwTableBox(
1664 (SwTableBoxFmt
*)pULPara
->pRightBox
->GetFrmFmt(), 0, pInsLine
);
1665 SwTableLine
* pRMLn
= new SwTableLine(
1666 (SwTableLineFmt
*)pInsLine
->GetFrmFmt(), 2, pRMBox
);
1667 pRMLn
->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE
);
1668 pRMBox
->GetTabLines().C40_INSERT( SwTableLine
, pRMLn
, 0 );
1670 lcl_CpyBoxes( 1, 3, pInsLine
->GetTabBoxes(), pRMLn
);
1672 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pRMBox
, 0 );
1676 // Left und Merge wurden schon zusammengefuegt, also move
1677 // Right auch mit in die Line
1679 pInsLine
= pULPara
->pLeftBox
->GetUpper();
1680 USHORT nMvPos
= pULPara
->pRightBox
->GetUpper()->GetTabBoxes().
1681 C40_GETPOS( SwTableBox
, pULPara
->pRightBox
);
1682 lcl_CpyBoxes( nMvPos
, nMvPos
+1,
1683 pULPara
->pRightBox
->GetUpper()->GetTabBoxes(),
1685 pRMBox
= pInsLine
->GetUpper();
1687 // sind schon Lines vorhanden, dann muessen diese in eine
1688 // neue Line und Box
1689 nMvPos
= pRMBox
->GetTabLines().C40_GETPOS( SwTableLine
, pInsLine
);
1690 if( pULPara
->bUL
? nMvPos
1691 : nMvPos
+1 < pRMBox
->GetTabLines().Count() )
1693 // alle Lines zu einer neuen Line und Box zusammenfassen
1694 SwTableLine
* pNewLn
= new SwTableLine(
1695 (SwTableLineFmt
*)pInsLine
->GetFrmFmt(), 1, pRMBox
);
1696 pNewLn
->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE
);
1697 pRMBox
->GetTabLines().C40_INSERT( SwTableLine
, pNewLn
,
1698 pULPara
->bUL
? nMvPos
: nMvPos
+1 );
1699 pRMBox
= new SwTableBox( (SwTableBoxFmt
*)pRMBox
->GetFrmFmt(), 0, pNewLn
);
1700 pNewLn
->GetTabBoxes().C40_INSERT( SwTableBox
, pRMBox
, 0 );
1702 USHORT nPos1
, nPos2
;
1708 nPos2
= pNewLn
->GetUpper()->GetTabLines().Count();
1710 lcl_CpyLines( nPos1
, nPos2
,
1711 pNewLn
->GetUpper()->GetTabLines(), pRMBox
);
1712 lcl_CalcWidth( pRMBox
); // bereche die Breite der Box
1714 pRMBox
= new SwTableBox( (SwTableBoxFmt
*)pRMBox
->GetFrmFmt(), 0, pNewLn
);
1715 pNewLn
->GetTabBoxes().C40_INSERT( SwTableBox
, pRMBox
,
1716 pNewLn
->GetTabBoxes().Count() );
1719 if( pULPara
->bUL
) // Upper ?
1721 // gibt es noch davor Zeilen, dann move sie
1722 if( 0 != ( nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) )
1723 lcl_CpyLines( 0, nPos
, *pLines
, pRMBox
, 0 );
1726 // gibt es noch dahinter Zeilen, dann move sie
1727 if( (nPos
= pLines
->C40_GETPOS( SwTableLine
, pFndLn
)) +1 < pLines
->Count() )
1728 lcl_CpyLines( nPos
+1, pLines
->Count(), *pLines
,
1730 lcl_CalcWidth( pRMBox
); // bereche die Breite der Box
1733 ASSERT( FALSE
, "Was denn nun" );
1739 // suche nur die Line, ab der Verschoben werden muss
1740 nStt
= pULPara
->bUL
? 0 : rpFndLine
->GetBoxes().Count()-1;
1743 pLines
= &pULPara
->pInsBox
->GetTabLines();
1745 SwTableLine
* pNewLine
= new SwTableLine(
1746 (SwTableLineFmt
*)rpFndLine
->GetLine()->GetFrmFmt(), 0, pULPara
->pInsBox
);
1747 _InsULPara
aPara( *pULPara
); // kopieren
1748 aPara
.pInsLine
= pNewLine
;
1749 ((_FndLine
*)rpFndLine
)->GetBoxes().ForEach( nStt
, nEnd
,
1750 &lcl_Merge_MoveBox
, &aPara
);
1751 if( pNewLine
->GetTabBoxes().Count() )
1753 if( USHRT_MAX
== nInsPos
)
1754 nInsPos
= pLines
->Count();
1755 pLines
->C40_INSERT( SwTableLine
, pNewLine
, nInsPos
);
1764 BOOL
SwTable::OldMerge( SwDoc
* pDoc
, const SwSelBoxes
& rBoxes
,
1765 SwTableBox
* pMergeBox
, SwUndoTblMerge
* pUndo
)
1767 ASSERT( rBoxes
.Count() && pMergeBox
, "keine gueltigen Werte" );
1768 SwTableNode
* pTblNd
= (SwTableNode
*)rBoxes
[0]->GetSttNd()->FindTableNode();
1772 // suche alle Boxen / Lines
1773 _FndBox
aFndBox( 0, 0 );
1775 _FndPara
aPara( rBoxes
, &aFndBox
);
1776 GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
1778 if( !aFndBox
.GetLines().Count() )
1781 // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1782 // the table to complex to be handled with chart.
1783 // Thus we tell the charts to use their own data provider and forget about this table
1784 pDoc
->CreateChartInternalDataProviders( this );
1786 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
1789 pUndo
->SetSelBoxes( rBoxes
);
1791 //Lines fuer das Layout-Update herausuchen.
1792 aFndBox
.SetTableLines( *this );
1793 aFndBox
.DelFrms( *this );
1795 _FndBox
* pFndBox
= &aFndBox
;
1796 while( 1 == pFndBox
->GetLines().Count() &&
1797 1 == pFndBox
->GetLines()[0]->GetBoxes().Count() )
1798 pFndBox
= pFndBox
->GetLines()[0]->GetBoxes()[0];
1800 SwTableLine
* pInsLine
= new SwTableLine(
1801 (SwTableLineFmt
*)pFndBox
->GetLines()[0]->GetLine()->GetFrmFmt(), 0,
1802 !pFndBox
->GetUpper() ? 0 : pFndBox
->GetBox() );
1803 pInsLine
->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE
);
1805 // trage die neue Line ein
1806 SwTableLines
* pLines
= pFndBox
->GetUpper() ?
1807 &pFndBox
->GetBox()->GetTabLines() : &GetTabLines();
1809 SwTableLine
* pNewLine
= pFndBox
->GetLines()[0]->GetLine();
1810 USHORT nInsPos
= pLines
->C40_GETPOS( SwTableLine
, pNewLine
);
1811 pLines
->C40_INSERT( SwTableLine
, pInsLine
, nInsPos
);
1813 SwTableBox
* pLeftBox
= new SwTableBox( (SwTableBoxFmt
*)pMergeBox
->GetFrmFmt(), 0, pInsLine
);
1814 SwTableBox
* pRightBox
= new SwTableBox( (SwTableBoxFmt
*)pMergeBox
->GetFrmFmt(), 0, pInsLine
);
1815 pMergeBox
->SetUpper( pInsLine
);
1816 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pLeftBox
, 0 );
1817 pLeftBox
->ClaimFrmFmt();
1818 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pMergeBox
, 1 );
1819 pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pRightBox
, 2 );
1820 pRightBox
->ClaimFrmFmt();
1822 // in diese kommen alle Lines, die ueber dem selektierten Bereich stehen
1823 // Sie bilden also eine Upper/Lower Line
1824 _InsULPara
aPara( pTblNd
, TRUE
, TRUE
, pLeftBox
, pMergeBox
, pRightBox
, pInsLine
);
1826 // move die oben/unten ueberhaengenden Lines vom selektierten Bereich
1827 pFndBox
->GetLines()[0]->GetBoxes().ForEach( &lcl_Merge_MoveBox
,
1829 aPara
.SetLower( pInsLine
);
1830 USHORT nEnd
= pFndBox
->GetLines().Count()-1;
1831 pFndBox
->GetLines()[nEnd
]->GetBoxes().ForEach( &lcl_Merge_MoveBox
,
1834 // move die links/rechts hereinreichenden Boxen vom selektierten Bereich
1835 aPara
.SetLeft( pLeftBox
);
1836 pFndBox
->GetLines().ForEach( &lcl_Merge_MoveLine
, &aPara
);
1838 aPara
.SetRight( pRightBox
);
1839 pFndBox
->GetLines().ForEach( &lcl_Merge_MoveLine
, &aPara
);
1841 if( !pLeftBox
->GetTabLines().Count() )
1842 _DeleteBox( *this, pLeftBox
, 0, FALSE
, FALSE
);
1845 lcl_CalcWidth( pLeftBox
); // bereche die Breite der Box
1846 if( pUndo
&& pLeftBox
->GetSttNd() )
1847 pUndo
->AddNewBox( pLeftBox
->GetSttIdx() );
1849 if( !pRightBox
->GetTabLines().Count() )
1850 _DeleteBox( *this, pRightBox
, 0, FALSE
, FALSE
);
1853 lcl_CalcWidth( pRightBox
); // bereche die Breite der Box
1854 if( pUndo
&& pRightBox
->GetSttNd() )
1855 pUndo
->AddNewBox( pRightBox
->GetSttIdx() );
1858 DeleteSel( pDoc
, rBoxes
, 0, 0, FALSE
, FALSE
);
1860 // dann raeume die Struktur dieser Line noch mal auf:
1861 // generell alle Aufraeumen
1864 GetTabLines()[0]->GetTabBoxes().ForEach( &lcl_BoxSetHeadCondColl
, 0 );
1866 aFndBox
.MakeFrms( *this );
1874 // ---------------------------------------------------------------
1876 void lcl_CheckRowSpan( SwTable
&rTbl
)
1878 USHORT nLineCount
= rTbl
.GetTabLines().Count();
1879 USHORT nMaxSpan
= nLineCount
;
1883 SwTableLine
* pLine
= rTbl
.GetTabLines()[ nLineCount
- nMaxSpan
];
1884 for( USHORT nBox
= 0; nBox
< pLine
->GetTabBoxes().Count(); ++nBox
)
1886 SwTableBox
* pBox
= pLine
->GetTabBoxes()[nBox
];
1887 long nRowSpan
= pBox
->getRowSpan();
1888 if( nRowSpan
> nMaxSpan
)
1889 pBox
->setRowSpan( nMaxSpan
);
1890 else if( nRowSpan
< nMinSpan
)
1891 pBox
->setRowSpan( nMinSpan
> 0 ? nMaxSpan
: nMinSpan
);
1894 nMinSpan
= -nMaxSpan
;
1898 USHORT
lcl_GetBoxOffset( const _FndBox
& rBox
)
1900 // suche die erste Box
1901 const _FndBox
* pFirstBox
= &rBox
;
1902 while( pFirstBox
->GetLines().Count() )
1903 pFirstBox
= pFirstBox
->GetLines()[ 0 ]->GetBoxes()[ 0 ];
1906 // dann ueber die Lines nach oben die Position bestimmen
1907 const SwTableBox
* pBox
= pFirstBox
->GetBox();
1909 const SwTableBoxes
& rBoxes
= pBox
->GetUpper()->GetTabBoxes();
1910 const SwTableBox
* pCmp
;
1911 for( USHORT n
= 0; pBox
!= ( pCmp
= rBoxes
[ n
] ); ++n
)
1912 nRet
= nRet
+ (USHORT
) pCmp
->GetFrmFmt()->GetFrmSize().GetWidth();
1913 pBox
= pBox
->GetUpper()->GetUpper();
1918 USHORT
lcl_GetLineWidth( const _FndLine
& rLine
)
1921 for( USHORT n
= rLine
.GetBoxes().Count(); n
; )
1922 nRet
= nRet
+ (USHORT
)rLine
.GetBoxes()[ --n
]->GetBox()->GetFrmFmt()
1923 ->GetFrmSize().GetWidth();
1927 void lcl_CalcNewWidths( const _FndLines
& rFndLines
, _CpyPara
& rPara
)
1929 rPara
.pWidths
.reset();
1930 USHORT nLineCount
= rFndLines
.Count();
1933 rPara
.pWidths
= boost::shared_ptr
< std::vector
< std::vector
< ULONG
> > >
1934 ( new std::vector
< std::vector
< ULONG
> >( nLineCount
));
1935 // First we collect information about the left/right borders of all
1937 for( USHORT nLine
= 0; nLine
< nLineCount
; ++nLine
)
1939 std::vector
< ULONG
> &rWidth
= (*rPara
.pWidths
.get())[ nLine
];
1940 const _FndLine
*pFndLine
= rFndLines
[ nLine
];
1941 if( pFndLine
&& pFndLine
->GetBoxes().Count() )
1943 const SwTableLine
*pLine
= pFndLine
->GetLine();
1944 if( pLine
&& pLine
->GetTabBoxes().Count() )
1946 USHORT nBoxCount
= pLine
->GetTabBoxes().Count();
1948 // The first selected box...
1949 const SwTableBox
*pSel
= pFndLine
->GetBoxes()[0]->GetBox();
1951 // Sum up the width of all boxes before the first selected box
1952 while( nBox
< nBoxCount
)
1954 SwTableBox
* pBox
= pLine
->GetTabBoxes()[nBox
++];
1956 nPos
+= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
1960 // nPos is now the left border of the first selceted box
1961 if( rPara
.nMinLeft
> nPos
)
1962 rPara
.nMinLeft
= nPos
;
1963 nBoxCount
= pFndLine
->GetBoxes().Count();
1964 rWidth
= std::vector
< ULONG
>( nBoxCount
+2 );
1966 // Add now the widths of all selected boxes and store
1967 // the positions in the vector
1968 for( nBox
= 0; nBox
< nBoxCount
; )
1970 nPos
+= pFndLine
->GetBoxes()[nBox
]
1971 ->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
1972 rWidth
[ ++nBox
] = nPos
;
1974 // nPos: The right border of the last selected box
1975 if( rPara
.nMaxRight
< nPos
)
1976 rPara
.nMaxRight
= nPos
;
1977 if( nPos
<= rWidth
[ 0 ] )
1983 // Second step: calculate the new widths for the copied cells
1984 ULONG nSelSize
= rPara
.nMaxRight
- rPara
.nMinLeft
;
1987 for( USHORT nLine
= 0; nLine
< nLineCount
; ++nLine
)
1989 std::vector
< ULONG
> &rWidth
= (*rPara
.pWidths
.get())[ nLine
];
1990 USHORT nCount
= (USHORT
)rWidth
.size();
1993 rWidth
[ nCount
- 1 ] = rPara
.nMaxRight
;
1995 for( USHORT nBox
= 0; nBox
< nCount
; ++nBox
)
1997 sal_uInt64 nNextPos
= rWidth
[ nBox
];
1998 nNextPos
-= rPara
.nMinLeft
;
1999 nNextPos
*= rPara
.nNewSize
;
2000 nNextPos
/= nSelSize
;
2001 rWidth
[ nBox
] = (ULONG
)(nNextPos
- nLastPos
);
2002 nLastPos
= (ULONG
)nNextPos
;
2009 BOOL
lcl_CopyBoxToDoc( const _FndBox
*& rpFndBox
, void* pPara
)
2011 _CpyPara
* pCpyPara
= (_CpyPara
*)pPara
;
2013 // Calculation of new size
2017 if( pCpyPara
->pTblNd
->GetTable().IsNewModel() )
2019 if( pCpyPara
->nBoxIdx
== 1 )
2020 nDummy1
= (*pCpyPara
->pWidths
.get())[pCpyPara
->nLnIdx
][0];
2021 nRealSize
= (*pCpyPara
->pWidths
.get())[pCpyPara
->nLnIdx
][pCpyPara
->nBoxIdx
++];
2022 if( pCpyPara
->nBoxIdx
== (*pCpyPara
->pWidths
.get())[pCpyPara
->nLnIdx
].size()-1 )
2023 nDummy2
= (*pCpyPara
->pWidths
.get())[pCpyPara
->nLnIdx
][pCpyPara
->nBoxIdx
];
2027 nRealSize
= pCpyPara
->nNewSize
;
2028 nRealSize
*= rpFndBox
->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
2029 nRealSize
/= pCpyPara
->nOldSize
;
2033 bool bDummy
= nDummy1
> 0;
2043 // suche das Frame-Format in der Liste aller Frame-Formate
2044 _CpyTabFrm
aFindFrm( (SwTableBoxFmt
*)rpFndBox
->GetBox()->GetFrmFmt() );
2046 SwFmtFrmSize aFrmSz
;
2048 if( !pCpyPara
->rTabFrmArr
.Seek_Entry( aFindFrm
, &nFndPos
) ||
2049 ( aFrmSz
= ( aFindFrm
= pCpyPara
->rTabFrmArr
[ nFndPos
]).pNewFrmFmt
->
2050 GetFrmSize()).GetWidth() != (SwTwips
)nSize
)
2052 // es ist noch nicht vorhanden, also kopiere es
2053 aFindFrm
.pNewFrmFmt
= pCpyPara
->pDoc
->MakeTableBoxFmt();
2054 aFindFrm
.pNewFrmFmt
->CopyAttrs( *rpFndBox
->GetBox()->GetFrmFmt() );
2055 if( !pCpyPara
->bCpyCntnt
)
2056 aFindFrm
.pNewFrmFmt
->ResetFmtAttr( RES_BOXATR_FORMULA
, RES_BOXATR_VALUE
);
2057 aFrmSz
.SetWidth( nSize
);
2058 aFindFrm
.pNewFrmFmt
->SetFmtAttr( aFrmSz
);
2059 pCpyPara
->rTabFrmArr
.Insert( aFindFrm
);
2063 if( rpFndBox
->GetLines().Count() )
2065 pBox
= new SwTableBox( aFindFrm
.pNewFrmFmt
,
2066 rpFndBox
->GetLines().Count(), pCpyPara
->pInsLine
);
2067 pCpyPara
->pInsLine
->GetTabBoxes().C40_INSERT( SwTableBox
, pBox
, pCpyPara
->nInsPos
++ );
2068 _CpyPara
aPara( *pCpyPara
, pBox
);
2069 aPara
.nNewSize
= nSize
; // hole die Groesse
2070 ((_FndBox
*)rpFndBox
)->GetLines().ForEach( &lcl_CopyLineToDoc
, &aPara
);
2074 // erzeuge eine leere Box
2075 pCpyPara
->pDoc
->GetNodes().InsBoxen( pCpyPara
->pTblNd
, pCpyPara
->pInsLine
,
2076 aFindFrm
.pNewFrmFmt
,
2077 (SwTxtFmtColl
*)pCpyPara
->pDoc
->GetDfltTxtFmtColl(),
2078 0, pCpyPara
->nInsPos
);
2079 pBox
= pCpyPara
->pInsLine
->GetTabBoxes()[ pCpyPara
->nInsPos
];
2081 pBox
->setDummyFlag( true );
2082 else if( pCpyPara
->bCpyCntnt
)
2084 // dann kopiere mal den Inhalt in diese leere Box
2085 pBox
->setRowSpan( rpFndBox
->GetBox()->getRowSpan() );
2087 // der Inhalt kopiert wird, dann koennen auch Formeln&Values
2090 SfxItemSet
aBoxAttrSet( pCpyPara
->pDoc
->GetAttrPool(),
2091 RES_BOXATR_FORMAT
, RES_BOXATR_VALUE
);
2092 aBoxAttrSet
.Put( rpFndBox
->GetBox()->GetFrmFmt()->GetAttrSet() );
2093 if( aBoxAttrSet
.Count() )
2095 const SfxPoolItem
* pItem
;
2096 SvNumberFormatter
* pN
= pCpyPara
->pDoc
->GetNumberFormatter( FALSE
);
2097 if( pN
&& pN
->HasMergeFmtTbl() && SFX_ITEM_SET
== aBoxAttrSet
.
2098 GetItemState( RES_BOXATR_FORMAT
, FALSE
, &pItem
) )
2100 ULONG nOldIdx
= ((SwTblBoxNumFormat
*)pItem
)->GetValue();
2101 ULONG nNewIdx
= pN
->GetMergeFmtIndex( nOldIdx
);
2102 if( nNewIdx
!= nOldIdx
)
2103 aBoxAttrSet
.Put( SwTblBoxNumFormat( nNewIdx
));
2105 pBox
->ClaimFrmFmt()->SetFmtAttr( aBoxAttrSet
);
2108 SwDoc
* pFromDoc
= rpFndBox
->GetBox()->GetFrmFmt()->GetDoc();
2109 SwNodeRange
aCpyRg( *rpFndBox
->GetBox()->GetSttNd(), 1,
2110 *rpFndBox
->GetBox()->GetSttNd()->EndOfSectionNode() );
2111 SwNodeIndex
aInsIdx( *pBox
->GetSttNd(), 1 );
2113 pFromDoc
->CopyWithFlyInFly( aCpyRg
, 0, aInsIdx
, FALSE
);
2114 // den initialen TextNode loeschen
2115 pCpyPara
->pDoc
->GetNodes().Delete( aInsIdx
, 1 );
2117 ++pCpyPara
->nInsPos
;
2136 BOOL
lcl_CopyLineToDoc( const _FndLine
*& rpFndLine
, void* pPara
)
2138 _CpyPara
* pCpyPara
= (_CpyPara
*)pPara
;
2140 // suche das Format in der Liste aller Formate
2141 _CpyTabFrm
aFindFrm( (SwTableBoxFmt
*)rpFndLine
->GetLine()->GetFrmFmt() );
2143 if( !pCpyPara
->rTabFrmArr
.Seek_Entry( aFindFrm
, &nFndPos
))
2145 // es ist noch nicht vorhanden, also kopiere es
2146 aFindFrm
.pNewFrmFmt
= (SwTableBoxFmt
*)pCpyPara
->pDoc
->MakeTableLineFmt();
2147 aFindFrm
.pNewFrmFmt
->CopyAttrs( *rpFndLine
->GetLine()->GetFrmFmt() );
2148 pCpyPara
->rTabFrmArr
.Insert( aFindFrm
);
2151 aFindFrm
= pCpyPara
->rTabFrmArr
[ nFndPos
];
2153 SwTableLine
* pNewLine
= new SwTableLine( (SwTableLineFmt
*)aFindFrm
.pNewFrmFmt
,
2154 rpFndLine
->GetBoxes().Count(), pCpyPara
->pInsBox
);
2155 if( pCpyPara
->pInsBox
)
2157 pCpyPara
->pInsBox
->GetTabLines().C40_INSERT( SwTableLine
, pNewLine
, pCpyPara
->nInsPos
++ );
2161 pCpyPara
->pTblNd
->GetTable().GetTabLines().C40_INSERT( SwTableLine
, pNewLine
,
2162 pCpyPara
->nInsPos
++ );
2165 _CpyPara
aPara( *pCpyPara
, pNewLine
);
2167 if( pCpyPara
->pTblNd
->GetTable().IsNewModel() )
2169 aPara
.nOldSize
= 0; // will not be used
2172 else if( rpFndLine
->GetBoxes().Count() ==
2173 rpFndLine
->GetLine()->GetTabBoxes().Count() )
2175 // hole die Size vom Parent
2176 const SwFrmFmt
* pFmt
;
2178 if( rpFndLine
->GetLine()->GetUpper() )
2179 pFmt
= rpFndLine
->GetLine()->GetUpper()->GetFrmFmt();
2181 pFmt
= pCpyPara
->pTblNd
->GetTable().GetFrmFmt();
2182 aPara
.nOldSize
= pFmt
->GetFrmSize().GetWidth();
2186 for( USHORT n
= 0; n
< rpFndLine
->GetBoxes().Count(); ++n
)
2187 aPara
.nOldSize
+= rpFndLine
->GetBoxes()[n
]
2188 ->GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
2190 ((_FndLine
*)rpFndLine
)->GetBoxes().ForEach( &lcl_CopyBoxToDoc
, &aPara
);
2191 if( pCpyPara
->pTblNd
->GetTable().IsNewModel() )
2196 BOOL
SwTable::CopyHeadlineIntoTable( SwTableNode
& rTblNd
)
2198 // suche alle Boxen / Lines
2199 SwSelBoxes aSelBoxes
;
2200 SwTableBox
* pBox
= GetTabSortBoxes()[ 0 ];
2201 pBox
= GetTblBox( pBox
->GetSttNd()->StartOfSectionNode()->GetIndex() + 1 );
2202 SelLineFromBox( pBox
, aSelBoxes
, TRUE
);
2204 _FndBox
aFndBox( 0, 0 );
2206 _FndPara
aPara( aSelBoxes
, &aFndBox
);
2207 ((SwTableLines
&)GetTabLines()).ForEach( &_FndLineCopyCol
, &aPara
);
2209 if( !aFndBox
.GetLines().Count() )
2213 // Tabellen-Formeln in die relative Darstellung umwandeln
2214 SwTableFmlUpdate
aMsgHnt( this );
2215 aMsgHnt
.eFlags
= TBL_RELBOXNAME
;
2216 GetFrmFmt()->GetDoc()->UpdateTblFlds( &aMsgHnt
);
2219 _CpyTabFrms aCpyFmt
;
2220 _CpyPara
aPara( &rTblNd
, 1, aCpyFmt
, TRUE
);
2221 aPara
.nNewSize
= aPara
.nOldSize
= rTblNd
.GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
2224 lcl_CalcNewWidths( aFndBox
.GetLines(), aPara
);
2225 aFndBox
.GetLines().ForEach( &lcl_CopyLineToDoc
, &aPara
);
2226 if( rTblNd
.GetTable().IsNewModel() )
2227 { // The copied line must not contain any row span attributes > 1
2228 SwTableLine
* pLine
= rTblNd
.GetTable().GetTabLines()[0];
2229 USHORT nColCount
= pLine
->GetTabBoxes().Count();
2230 ASSERT( nColCount
, "Empty Table Line" )
2231 for( USHORT nCurrCol
= 0; nCurrCol
< nColCount
; ++nCurrCol
)
2233 SwTableBox
* pTableBox
= pLine
->GetTabBoxes()[nCurrCol
];
2234 ASSERT( pTableBox
, "Missing Table Box" );
2235 pTableBox
->setRowSpan( 1 );
2242 BOOL
SwTable::MakeCopy( SwDoc
* pInsDoc
, const SwPosition
& rPos
,
2243 const SwSelBoxes
& rSelBoxes
, BOOL bCpyNds
,
2244 BOOL bCpyName
) const
2246 // suche alle Boxen / Lines
2247 _FndBox
aFndBox( 0, 0 );
2249 _FndPara
aPara( rSelBoxes
, &aFndBox
);
2250 ((SwTableLines
&)GetTabLines()).ForEach( &_FndLineCopyCol
, &aPara
);
2252 if( !aFndBox
.GetLines().Count() )
2255 // erst die Poolvorlagen fuer die Tabelle kopieren, damit die dann
2256 // wirklich kopiert und damit die gueltigen Werte haben.
2257 SwDoc
* pSrcDoc
= GetFrmFmt()->GetDoc();
2258 if( pSrcDoc
!= pInsDoc
)
2260 pInsDoc
->CopyTxtColl( *pSrcDoc
->GetTxtCollFromPool( RES_POOLCOLL_TABLE
) );
2261 pInsDoc
->CopyTxtColl( *pSrcDoc
->GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN
) );
2264 SwTable
* pNewTbl
= (SwTable
*)pInsDoc
->InsertTable(
2265 SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER
, 1 ),
2266 rPos
, 1, 1, GetFrmFmt()->GetHoriOrient().GetHoriOrient(),
2267 0, 0, FALSE
, IsNewModel() );
2271 SwNodeIndex
aIdx( rPos
.nNode
, -1 );
2272 SwTableNode
* pTblNd
= aIdx
.GetNode().FindTableNode();
2274 ASSERT( pTblNd
, "wo ist denn nun der TableNode?" );
2276 pTblNd
->GetTable().SetRowsToRepeat( GetRowsToRepeat() );
2278 if( IS_TYPE( SwDDETable
, this ))
2280 // es wird eine DDE-Tabelle kopiert
2281 // ist im neuen Dokument ueberhaupt der FeldTyp vorhanden ?
2282 SwFieldType
* pFldType
= pInsDoc
->InsertFldType(
2283 *((SwDDETable
*)this)->GetDDEFldType() );
2284 ASSERT( pFldType
, "unbekannter FieldType" );
2286 // tauschen am Node den Tabellen-Pointer aus
2287 pNewTbl
= new SwDDETable( *pNewTbl
,
2288 (SwDDEFieldType
*)pFldType
);
2289 pTblNd
->SetNewTable( pNewTbl
, FALSE
);
2292 pNewTbl
->GetFrmFmt()->CopyAttrs( *GetFrmFmt() );
2293 pNewTbl
->SetTblChgMode( GetTblChgMode() );
2295 //Vernichten der Frms die bereits angelegt wurden.
2299 // Tabellen-Formeln in die relative Darstellung umwandeln
2300 SwTableFmlUpdate
aMsgHnt( this );
2301 aMsgHnt
.eFlags
= TBL_RELBOXNAME
;
2302 pSrcDoc
->UpdateTblFlds( &aMsgHnt
);
2305 SwTblNumFmtMerge
aTNFM( *pSrcDoc
, *pInsDoc
);
2307 // Namen auch kopieren oder neuen eindeutigen erzeugen
2309 pNewTbl
->GetFrmFmt()->SetName( GetFrmFmt()->GetName() );
2311 _CpyTabFrms aCpyFmt
;
2312 _CpyPara
aPara( pTblNd
, 1, aCpyFmt
, bCpyNds
);
2313 aPara
.nNewSize
= aPara
.nOldSize
= GetFrmFmt()->GetFrmSize().GetWidth();
2316 lcl_CalcNewWidths( aFndBox
.GetLines(), aPara
);
2318 aFndBox
.GetLines().ForEach( &lcl_CopyLineToDoc
, &aPara
);
2320 // dann setze oben und unten noch die "richtigen" Raender:
2322 _FndLine
* pFndLn
= aFndBox
.GetLines()[ 0 ];
2323 SwTableLine
* pLn
= pFndLn
->GetLine();
2324 const SwTableLine
* pTmp
= pLn
;
2325 USHORT nLnPos
= GetTabLines().GetPos( pTmp
);
2326 if( USHRT_MAX
!= nLnPos
&& nLnPos
)
2328 // es gibt eine Line davor
2329 SwCollectTblLineBoxes
aLnPara( FALSE
, HEADLINE_BORDERCOPY
);
2331 pLn
= GetTabLines()[ nLnPos
- 1 ];
2332 pLn
->GetTabBoxes().ForEach( &lcl_Box_CollectBox
, &aLnPara
);
2334 if( aLnPara
.Resize( lcl_GetBoxOffset( aFndBox
),
2335 lcl_GetLineWidth( *pFndLn
)) )
2337 aLnPara
.SetValues( TRUE
);
2338 pLn
= pNewTbl
->GetTabLines()[ 0 ];
2339 pLn
->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts
, &aLnPara
);
2343 pFndLn
= aFndBox
.GetLines()[ aFndBox
.GetLines().Count() -1 ];
2344 pLn
= pFndLn
->GetLine();
2346 nLnPos
= GetTabLines().GetPos( pTmp
);
2347 if( nLnPos
< GetTabLines().Count() - 1 )
2349 // es gibt eine Line dahinter
2350 SwCollectTblLineBoxes
aLnPara( TRUE
, HEADLINE_BORDERCOPY
);
2352 pLn
= GetTabLines()[ nLnPos
+ 1 ];
2353 pLn
->GetTabBoxes().ForEach( &lcl_Box_CollectBox
, &aLnPara
);
2355 if( aLnPara
.Resize( lcl_GetBoxOffset( aFndBox
),
2356 lcl_GetLineWidth( *pFndLn
)) )
2358 aLnPara
.SetValues( FALSE
);
2359 pLn
= pNewTbl
->GetTabLines()[ pNewTbl
->GetTabLines().Count()-1 ];
2360 pLn
->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts
, &aLnPara
);
2365 // die initiale Box muss noch geloescht werden
2366 _DeleteBox( *pNewTbl
, pNewTbl
->GetTabLines()[
2367 pNewTbl
->GetTabLines().Count() - 1 ]->GetTabBoxes()[0],
2370 if( pNewTbl
->IsNewModel() )
2371 lcl_CheckRowSpan( *pNewTbl
);
2372 // Mal kurz aufraeumen:
2375 pTblNd
->MakeFrms( &aIdx
); // erzeuge die Frames neu
2384 // ---------------------------------------------------------------
2386 // suche ab dieser Line nach der naechsten Box mit Inhalt
2387 SwTableBox
* SwTableLine::FindNextBox( const SwTable
& rTbl
,
2388 const SwTableBox
* pSrchBox
, BOOL bOvrTblLns
) const
2390 const SwTableLine
* pLine
= this; // fuer M800
2393 if( GetTabBoxes().Count() && pSrchBox
&&
2394 USHRT_MAX
!= ( nFndPos
= GetTabBoxes().GetPos( pSrchBox
)) &&
2395 nFndPos
+ 1 != GetTabBoxes().Count() )
2397 pBox
= GetTabBoxes()[ nFndPos
+ 1 ];
2398 while( pBox
->GetTabLines().Count() )
2399 pBox
= pBox
->GetTabLines()[0]->GetTabBoxes()[0];
2405 nFndPos
= GetUpper()->GetTabLines().GetPos( pLine
);
2406 ASSERT( USHRT_MAX
!= nFndPos
, "Line nicht in der Tabelle" );
2407 // gibts eine weitere Line
2408 if( nFndPos
+1 >= GetUpper()->GetTabLines().Count() )
2409 return GetUpper()->GetUpper()->FindNextBox( rTbl
, GetUpper(), bOvrTblLns
);
2410 pLine
= GetUpper()->GetTabLines()[nFndPos
+1];
2412 else if( bOvrTblLns
) // ueber die "GrundLines" einer Tabelle ?
2414 // suche in der Tabelle nach der naechsten Line
2415 nFndPos
= rTbl
.GetTabLines().GetPos( pLine
);
2416 if( nFndPos
+ 1 >= rTbl
.GetTabLines().Count() )
2417 return 0; // es gibt keine weitere Box mehr
2419 pLine
= rTbl
.GetTabLines()[ nFndPos
+1 ];
2424 if( pLine
->GetTabBoxes().Count() )
2426 pBox
= pLine
->GetTabBoxes()[0];
2427 while( pBox
->GetTabLines().Count() )
2428 pBox
= pBox
->GetTabLines()[0]->GetTabBoxes()[0];
2431 return pLine
->FindNextBox( rTbl
, 0, bOvrTblLns
);
2434 // suche ab dieser Line nach der vorherigen Box
2435 SwTableBox
* SwTableLine::FindPreviousBox( const SwTable
& rTbl
,
2436 const SwTableBox
* pSrchBox
, BOOL bOvrTblLns
) const
2438 const SwTableLine
* pLine
= this; // fuer M800
2441 if( GetTabBoxes().Count() && pSrchBox
&&
2442 USHRT_MAX
!= ( nFndPos
= GetTabBoxes().GetPos( pSrchBox
)) &&
2445 pBox
= GetTabBoxes()[ nFndPos
- 1 ];
2446 while( pBox
->GetTabLines().Count() )
2448 pLine
= pBox
->GetTabLines()[pBox
->GetTabLines().Count()-1];
2449 pBox
= pLine
->GetTabBoxes()[pLine
->GetTabBoxes().Count()-1];
2456 nFndPos
= GetUpper()->GetTabLines().GetPos( pLine
);
2457 ASSERT( USHRT_MAX
!= nFndPos
, "Line nicht in der Tabelle" );
2458 // gibts eine weitere Line
2460 return GetUpper()->GetUpper()->FindPreviousBox( rTbl
, GetUpper(), bOvrTblLns
);
2461 pLine
= GetUpper()->GetTabLines()[nFndPos
-1];
2463 else if( bOvrTblLns
) // ueber die "GrundLines" einer Tabelle ?
2465 // suche in der Tabelle nach der naechsten Line
2466 nFndPos
= rTbl
.GetTabLines().GetPos( pLine
);
2468 return 0; // es gibt keine weitere Box mehr
2470 pLine
= rTbl
.GetTabLines()[ nFndPos
-1 ];
2475 if( pLine
->GetTabBoxes().Count() )
2477 pBox
= pLine
->GetTabBoxes()[pLine
->GetTabBoxes().Count()-1];
2478 while( pBox
->GetTabLines().Count() )
2480 pLine
= pBox
->GetTabLines()[pBox
->GetTabLines().Count()-1];
2481 pBox
= pLine
->GetTabBoxes()[pLine
->GetTabBoxes().Count()-1];
2485 return pLine
->FindPreviousBox( rTbl
, 0, bOvrTblLns
);
2488 // suche ab dieser Line nach der naechsten Box mit Inhalt
2489 SwTableBox
* SwTableBox::FindNextBox( const SwTable
& rTbl
,
2490 const SwTableBox
* pSrchBox
, BOOL bOvrTblLns
) const
2492 if( !pSrchBox
&& !GetTabLines().Count() )
2493 return (SwTableBox
*)this;
2494 return GetUpper()->FindNextBox( rTbl
, pSrchBox
? pSrchBox
: this,
2499 // suche ab dieser Line nach der naechsten Box mit Inhalt
2500 SwTableBox
* SwTableBox::FindPreviousBox( const SwTable
& rTbl
,
2501 const SwTableBox
* pSrchBox
, BOOL bOvrTblLns
) const
2503 if( !pSrchBox
&& !GetTabLines().Count() )
2504 return (SwTableBox
*)this;
2505 return GetUpper()->FindPreviousBox( rTbl
, pSrchBox
? pSrchBox
: this,
2510 BOOL
lcl_BoxSetHeadCondColl( const SwTableBox
*& rpBox
, void* )
2512 // in der HeadLine sind die Absaetze mit BedingtenVorlage anzupassen
2513 const SwStartNode
* pSttNd
= rpBox
->GetSttNd();
2515 pSttNd
->CheckSectionCondColl();
2517 ((SwTableBox
*)rpBox
)->GetTabLines().ForEach( &lcl_LineSetHeadCondColl
, 0 );
2521 BOOL
lcl_LineSetHeadCondColl( const SwTableLine
*& rpLine
, void* )
2523 ((SwTableLine
*)rpLine
)->GetTabBoxes().ForEach( &lcl_BoxSetHeadCondColl
, 0 );
2529 SwTwips
lcl_GetDistance( SwTableBox
* pBox
, BOOL bLeft
)
2534 while( pBox
&& 0 != ( pLine
= pBox
->GetUpper() ) )
2536 USHORT nStt
= 0, nPos
= pLine
->GetTabBoxes().C40_GETPOS( SwTableBox
, pBox
);
2538 if( bFirst
&& !bLeft
)
2542 while( nStt
< nPos
)
2543 nRet
+= pLine
->GetTabBoxes()[ nStt
++ ]->GetFrmFmt()
2544 ->GetFrmSize().GetWidth();
2545 pBox
= pLine
->GetUpper();
2550 BOOL
lcl_SetSelBoxWidth( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
2551 SwTwips nDist
, BOOL bCheck
)
2553 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
2554 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
2556 SwTableBox
* pBox
= rBoxes
[ n
];
2557 SwFrmFmt
* pFmt
= pBox
->GetFrmFmt();
2558 const SwFmtFrmSize
& rSz
= pFmt
->GetFrmSize();
2559 SwTwips nWidth
= rSz
.GetWidth();
2560 BOOL bGreaterBox
= FALSE
;
2564 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2565 if( !::lcl_SetSelBoxWidth( pBox
->GetTabLines()[ i
], rParam
,
2569 // dann noch mal alle "ContentBoxen" sammeln
2570 if( ( 0 != ( bGreaterBox
= TBLFIX_CHGABS
!= rParam
.nMode
&& ( nDist
+ ( rParam
.bLeft
? 0 : nWidth
) ) >= rParam
.nSide
)) ||
2571 ( !rParam
.bBigger
&& ( Abs( nDist
+ (( rParam
.nMode
&& rParam
.bLeft
) ? 0 : nWidth
) - rParam
.nSide
) < COLFUZZY
) ) )
2573 rParam
.bAnyBoxFnd
= TRUE
;
2575 if( bGreaterBox
&& TBLFIX_CHGPROP
== rParam
.nMode
)
2577 // die "anderen Boxen" wurden angepasst,
2578 // also sich um diesen Betrag aendern
2579 nLowerDiff
= (nDist
+ ( rParam
.bLeft
? 0 : nWidth
) ) - rParam
.nSide
;
2580 nLowerDiff
*= rParam
.nDiff
;
2581 nLowerDiff
/= rParam
.nMaxSize
;
2582 nLowerDiff
= rParam
.nDiff
- nLowerDiff
;
2585 nLowerDiff
= rParam
.nDiff
;
2587 if( nWidth
< nLowerDiff
|| nWidth
- nLowerDiff
< MINLAY
)
2593 SwTwips nLowerDiff
= 0, nOldLower
= rParam
.nLowerDiff
;
2594 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2596 rParam
.nLowerDiff
= 0;
2597 lcl_SetSelBoxWidth( pBox
->GetTabLines()[ i
], rParam
, nDist
, FALSE
);
2599 if( nLowerDiff
< rParam
.nLowerDiff
)
2600 nLowerDiff
= rParam
.nLowerDiff
;
2602 rParam
.nLowerDiff
= nOldLower
;
2606 ( 0 != ( bGreaterBox
= !nOldLower
&& TBLFIX_CHGABS
!= rParam
.nMode
&&
2607 ( nDist
+ ( rParam
.bLeft
? 0 : nWidth
) ) >= rParam
.nSide
)) ||
2608 ( Abs( nDist
+ ( (rParam
.nMode
&& rParam
.bLeft
) ? 0 : nWidth
)
2609 - rParam
.nSide
) < COLFUZZY
))
2611 // in dieser Spalte ist der Cursor - also verkleinern / vergroessern
2612 SwFmtFrmSize
aNew( rSz
);
2616 if( bGreaterBox
&& TBLFIX_CHGPROP
== rParam
.nMode
)
2618 // die "anderen Boxen" wurden angepasst,
2619 // also sich um diesen Betrag aendern
2620 nLowerDiff
= (nDist
+ ( rParam
.bLeft
? 0 : nWidth
) ) - rParam
.nSide
;
2621 nLowerDiff
*= rParam
.nDiff
;
2622 nLowerDiff
/= rParam
.nMaxSize
;
2623 nLowerDiff
= rParam
.nDiff
- nLowerDiff
;
2626 nLowerDiff
= rParam
.nDiff
;
2629 rParam
.nLowerDiff
+= nLowerDiff
;
2631 if( rParam
.bBigger
)
2632 aNew
.SetWidth( nWidth
+ nLowerDiff
);
2634 aNew
.SetWidth( nWidth
- nLowerDiff
);
2635 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
2640 if( rParam
.bLeft
&& rParam
.nMode
&& nDist
>= rParam
.nSide
)
2645 // wenns groesser wird, dann wars das
2646 if( ( TBLFIX_CHGABS
== rParam
.nMode
|| !rParam
.bLeft
) &&
2647 nDist
>= rParam
.nSide
)
2653 BOOL
lcl_SetOtherBoxWidth( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
2654 SwTwips nDist
, BOOL bCheck
)
2656 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
2657 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
2659 SwTableBox
* pBox
= rBoxes
[ n
];
2660 SwFrmFmt
* pFmt
= pBox
->GetFrmFmt();
2661 const SwFmtFrmSize
& rSz
= pFmt
->GetFrmSize();
2662 SwTwips nWidth
= rSz
.GetWidth();
2666 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2667 if( !::lcl_SetOtherBoxWidth( pBox
->GetTabLines()[ i
],
2668 rParam
, nDist
, TRUE
))
2671 if( rParam
.bBigger
&& ( TBLFIX_CHGABS
== rParam
.nMode
2672 ? Abs( nDist
- rParam
.nSide
) < COLFUZZY
2673 : ( rParam
.bLeft
? nDist
< rParam
.nSide
- COLFUZZY
2674 : nDist
>= rParam
.nSide
- COLFUZZY
)) )
2676 rParam
.bAnyBoxFnd
= TRUE
;
2678 if( TBLFIX_CHGPROP
== rParam
.nMode
) // Tabelle fix, proport.
2680 // relativ berechnen
2682 nDiff
*= rParam
.nDiff
;
2683 nDiff
/= rParam
.nMaxSize
;
2686 nDiff
= rParam
.nDiff
;
2688 if( nWidth
< nDiff
|| nWidth
- nDiff
< MINLAY
)
2694 SwTwips nLowerDiff
= 0, nOldLower
= rParam
.nLowerDiff
;
2695 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2697 rParam
.nLowerDiff
= 0;
2698 lcl_SetOtherBoxWidth( pBox
->GetTabLines()[ i
], rParam
,
2701 if( nLowerDiff
< rParam
.nLowerDiff
)
2702 nLowerDiff
= rParam
.nLowerDiff
;
2704 rParam
.nLowerDiff
= nOldLower
;
2707 ( TBLFIX_CHGABS
== rParam
.nMode
2708 ? Abs( nDist
- rParam
.nSide
) < COLFUZZY
2709 : ( rParam
.bLeft
? nDist
< rParam
.nSide
- COLFUZZY
2710 : nDist
>= rParam
.nSide
- COLFUZZY
)
2713 SwFmtFrmSize
aNew( rSz
);
2717 if( TBLFIX_CHGPROP
== rParam
.nMode
) // Tabelle fix, proport.
2719 // relativ berechnen
2720 nLowerDiff
= nWidth
;
2721 nLowerDiff
*= rParam
.nDiff
;
2722 nLowerDiff
/= rParam
.nMaxSize
;
2725 nLowerDiff
= rParam
.nDiff
;
2728 rParam
.nLowerDiff
+= nLowerDiff
;
2730 if( rParam
.bBigger
)
2731 aNew
.SetWidth( nWidth
- nLowerDiff
);
2733 aNew
.SetWidth( nWidth
+ nLowerDiff
);
2735 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
2740 if( ( TBLFIX_CHGABS
== rParam
.nMode
|| rParam
.bLeft
) &&
2741 nDist
> rParam
.nSide
)
2749 BOOL
lcl_InsSelBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
2750 SwTwips nDist
, BOOL bCheck
)
2752 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
2754 for( n
= 0; n
< rBoxes
.Count(); ++n
)
2756 SwTableBox
* pBox
= rBoxes
[ n
];
2757 SwTableBoxFmt
* pFmt
= (SwTableBoxFmt
*)pBox
->GetFrmFmt();
2758 const SwFmtFrmSize
& rSz
= pFmt
->GetFrmSize();
2759 SwTwips nWidth
= rSz
.GetWidth();
2763 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2764 if( !::lcl_InsSelBox( pBox
->GetTabLines()[ i
], rParam
,
2768 // dann noch mal alle "ContentBoxen" sammeln
2769 if( Abs( nDist
+ ( rParam
.bLeft
? 0 : nWidth
)
2770 - rParam
.nSide
) < COLFUZZY
)
2772 else if( nDist
+ ( rParam
.bLeft
? 0 : nWidth
/2 ) > rParam
.nSide
)
2779 rParam
.bAnyBoxFnd
= TRUE
;
2780 if( pFmt
->GetProtect().IsCntntProtected() )
2783 if( rParam
.bSplittBox
&&
2784 nWidth
- rParam
.nDiff
<= COLFUZZY
+
2785 ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
2788 if( pBox
->GetSttNd() )
2789 rParam
.aBoxes
.Insert( pBox
);
2796 SwTwips nLowerDiff
= 0, nOldLower
= rParam
.nLowerDiff
;
2797 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2799 rParam
.nLowerDiff
= 0;
2800 lcl_InsSelBox( pBox
->GetTabLines()[ i
], rParam
, nDist
, FALSE
);
2802 if( nLowerDiff
< rParam
.nLowerDiff
)
2803 nLowerDiff
= rParam
.nLowerDiff
;
2805 rParam
.nLowerDiff
= nOldLower
;
2809 else if( Abs( nDist
+ ( rParam
.bLeft
? 0 : nWidth
)
2810 - rParam
.nSide
) < COLFUZZY
)
2812 else if( nDist
+ nWidth
/ 2 > rParam
.nSide
)
2819 // in dieser Spalte ist der Cursor - also verkleinern / vergroessern
2822 if( !rParam
.bSplittBox
)
2825 SwFmtFrmSize
aNew( rSz
);
2826 aNew
.SetWidth( nWidth
+ rParam
.nDiff
);
2827 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
2832 ASSERT( pBox
->GetSttNd(), "Das muss eine EndBox sein!");
2834 if( !rParam
.bLeft
&& 3 != nCmp
)
2837 ::_InsTblBox( pFmt
->GetDoc(), rParam
.pTblNd
,
2838 pLine
, pFmt
, pBox
, n
);
2840 SwTableBox
* pNewBox
= rBoxes
[ n
];
2841 SwFmtFrmSize
aNew( rSz
);
2842 aNew
.SetWidth( rParam
.nDiff
);
2843 rParam
.aShareFmts
.SetSize( *pNewBox
, aNew
);
2845 // Sonderfall: kein Platz in den anderen Boxen
2846 // aber in der Zelle
2847 if( rParam
.bSplittBox
)
2850 SwFmtFrmSize
aNewSize( rSz
);
2851 aNewSize
.SetWidth( nWidth
- rParam
.nDiff
);
2852 rParam
.aShareFmts
.SetSize( *pBox
, aNewSize
);
2855 // Sonderbehandlung fuer Umrandung die Rechte muss
2858 const SvxBoxItem
& rBoxItem
= pBox
->GetFrmFmt()->GetBox();
2859 if( rBoxItem
.GetRight() )
2861 SvxBoxItem
aTmp( rBoxItem
);
2862 aTmp
.SetLine( 0, BOX_LINE_RIGHT
);
2863 rParam
.aShareFmts
.SetAttr( rParam
.bLeft
2870 rParam
.nLowerDiff
= rParam
.nDiff
;
2875 if( rParam
.bLeft
&& rParam
.nMode
&& nDist
>= rParam
.nSide
)
2883 BOOL
lcl_InsOtherBox( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
,
2884 SwTwips nDist
, BOOL bCheck
)
2886 // Sonderfall: kein Platz in den anderen Boxen aber in der Zelle
2887 if( rParam
.bSplittBox
)
2890 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
2893 // Tabelle fix, proport.
2894 if( !rParam
.nRemainWidth
&& TBLFIX_CHGPROP
== rParam
.nMode
)
2896 // dann die richtige Breite suchen, auf die sich die relative
2897 // Breitenanpassung bezieht.
2898 SwTwips nTmpDist
= nDist
;
2899 for( n
= 0; n
< rBoxes
.Count(); ++n
)
2901 SwTwips nWidth
= rBoxes
[ n
]->GetFrmFmt()->GetFrmSize().GetWidth();
2902 if( (nTmpDist
+ nWidth
/ 2 ) > rParam
.nSide
)
2904 rParam
.nRemainWidth
= rParam
.bLeft
2906 : USHORT(rParam
.nTblWidth
- nTmpDist
);
2913 for( n
= 0; n
< rBoxes
.Count(); ++n
)
2915 SwTableBox
* pBox
= rBoxes
[ n
];
2916 SwFrmFmt
* pFmt
= pBox
->GetFrmFmt();
2917 const SwFmtFrmSize
& rSz
= pFmt
->GetFrmSize();
2918 SwTwips nWidth
= rSz
.GetWidth();
2922 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2923 if( !::lcl_InsOtherBox( pBox
->GetTabLines()[ i
],
2924 rParam
, nDist
, TRUE
))
2928 rParam
.bLeft
? ((nDist
+ nWidth
/ 2 ) <= rParam
.nSide
&&
2929 (TBLFIX_CHGABS
!= rParam
.nMode
||
2930 n
< rBoxes
.Count() &&
2931 (nDist
+ nWidth
+ rBoxes
[ n
+1 ]->
2932 GetFrmFmt()->GetFrmSize().GetWidth() / 2)
2934 : (nDist
+ nWidth
/ 2 ) > rParam
.nSide
2937 rParam
.bAnyBoxFnd
= TRUE
;
2939 if( TBLFIX_CHGPROP
== rParam
.nMode
) // Tabelle fix, proport.
2941 // relativ berechnen
2943 nDiff
*= rParam
.nDiff
;
2944 nDiff
/= rParam
.nRemainWidth
;
2946 if( nWidth
< nDiff
|| nWidth
- nDiff
< MINLAY
)
2951 nDiff
= rParam
.nDiff
;
2953 // teste ob die linke oder rechte Box gross genug
2954 // ist, um den Platz abzugeben!
2955 // es wird davor oder dahinter eine Box eingefuegt!
2956 SwTwips nTmpWidth
= nWidth
;
2957 if( rParam
.bLeft
&& pBox
->GetUpper()->GetUpper() )
2959 const SwTableBox
* pTmpBox
= pBox
;
2961 while( !nBoxPos
&& pTmpBox
->GetUpper()->GetUpper() )
2963 pTmpBox
= pTmpBox
->GetUpper()->GetUpper();
2964 nBoxPos
= pTmpBox
->GetUpper()->GetTabBoxes().GetPos( pTmpBox
);
2967 nTmpWidth
= pTmpBox
->GetFrmFmt()->GetFrmSize().GetWidth();
2972 if( nTmpWidth
< nDiff
|| nTmpWidth
- nDiff
< MINLAY
)
2980 SwTwips nLowerDiff
= 0, nOldLower
= rParam
.nLowerDiff
;
2981 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
2983 rParam
.nLowerDiff
= 0;
2984 lcl_InsOtherBox( pBox
->GetTabLines()[ i
], rParam
,
2987 if( nLowerDiff
< rParam
.nLowerDiff
)
2988 nLowerDiff
= rParam
.nLowerDiff
;
2990 rParam
.nLowerDiff
= nOldLower
;
2993 (rParam
.bLeft
? ((nDist
+ nWidth
/ 2 ) <= rParam
.nSide
&&
2994 (TBLFIX_CHGABS
!= rParam
.nMode
||
2995 n
< rBoxes
.Count() &&
2996 (nDist
+ nWidth
+ rBoxes
[ n
+1 ]->
2997 GetFrmFmt()->GetFrmSize().GetWidth() / 2)
2999 : (nDist
+ nWidth
/ 2 ) > rParam
.nSide
))
3003 if( TBLFIX_CHGPROP
== rParam
.nMode
) // Tabelle fix, proport.
3005 // relativ berechnen
3006 nLowerDiff
= nWidth
;
3007 nLowerDiff
*= rParam
.nDiff
;
3008 nLowerDiff
/= rParam
.nRemainWidth
;
3011 nLowerDiff
= rParam
.nDiff
;
3014 SwFmtFrmSize
aNew( rSz
);
3015 rParam
.nLowerDiff
+= nLowerDiff
;
3017 if( rParam
.bBigger
)
3018 aNew
.SetWidth( nWidth
- nLowerDiff
);
3020 aNew
.SetWidth( nWidth
+ nLowerDiff
);
3021 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
3023 if( TBLFIX_CHGABS
== rParam
.nMode
)
3034 // das Ergebnis des Positions Vergleiches
3035 // POS_BEFORE, // Box liegt davor
3036 // POS_BEHIND, // Box liegt dahinter
3037 // POS_INSIDE, // Box liegt vollstaendig in Start/End
3038 // POS_OUTSIDE, // Box ueberlappt Start/End vollstaendig
3039 // POS_EQUAL, // Box und Start/End sind gleich
3040 // POS_OVERLAP_BEFORE, // Box ueberlappt den Start
3041 // POS_OVERLAP_BEHIND // Box ueberlappt das Ende
3043 SwComparePosition
_CheckBoxInRange( USHORT nStt
, USHORT nEnd
,
3044 USHORT nBoxStt
, USHORT nBoxEnd
)
3046 // COLFUZZY noch beachten!!
3047 SwComparePosition nRet
;
3048 if( nBoxStt
+ COLFUZZY
< nStt
)
3050 if( nBoxEnd
> nStt
+ COLFUZZY
)
3052 if( nBoxEnd
>= nEnd
+ COLFUZZY
)
3055 nRet
= POS_OVERLAP_BEFORE
;
3060 else if( nEnd
> nBoxStt
+ COLFUZZY
)
3062 if( nEnd
+ COLFUZZY
>= nBoxEnd
)
3064 if( COLFUZZY
> Abs( long(nEnd
) - long(nBoxEnd
) ) &&
3065 COLFUZZY
> Abs( long(nStt
) - long(nBoxStt
) ) )
3071 nRet
= POS_OVERLAP_BEHIND
;
3079 void lcl_DelSelBox_CorrLowers( SwTableLine
& rLine
, CR_SetBoxWidth
& rParam
,
3082 // 1. Schritt die eigene Breite feststellen
3083 SwTableBoxes
& rBoxes
= rLine
.GetTabBoxes();
3084 SwTwips nBoxWidth
= 0;
3087 for( n
= rBoxes
.Count(); n
; )
3088 nBoxWidth
+= rBoxes
[ --n
]->GetFrmFmt()->GetFrmSize().GetWidth();
3090 if( COLFUZZY
< Abs( nWidth
- nBoxWidth
))
3092 // sie muessen also angepasst werden
3093 for( n
= rBoxes
.Count(); n
; )
3095 SwTableBox
* pBox
= rBoxes
[ --n
];
3096 SwFmtFrmSize
aNew( pBox
->GetFrmFmt()->GetFrmSize() );
3097 long nDiff
= aNew
.GetWidth();
3100 aNew
.SetWidth( nDiff
);
3102 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
3104 if( !pBox
->GetSttNd() )
3106 // hat selbst auch Lower, also auch die anpassen
3107 for( USHORT i
= pBox
->GetTabLines().Count(); i
; )
3108 ::lcl_DelSelBox_CorrLowers( *pBox
->GetTabLines()[ --i
],
3115 void lcl_ChgBoxSize( SwTableBox
& rBox
, CR_SetBoxWidth
& rParam
,
3116 const SwFmtFrmSize
& rOldSz
,
3117 USHORT
& rDelWidth
, SwTwips nDist
)
3120 BOOL bSetSize
= FALSE
;
3122 switch( rParam
.nMode
)
3124 case TBLFIX_CHGABS
: // Tabelle feste Breite, den Nachbar andern
3125 nDiff
= rDelWidth
+ rParam
.nLowerDiff
;
3129 case TBLFIX_CHGPROP
: // Tabelle feste Breite, alle Nachbarn aendern
3130 if( !rParam
.nRemainWidth
)
3132 // dann kurz berechnen:
3134 rParam
.nRemainWidth
= USHORT(nDist
);
3136 rParam
.nRemainWidth
= USHORT(rParam
.nTblWidth
- nDist
);
3139 // relativ berechnen
3140 nDiff
= rOldSz
.GetWidth();
3141 nDiff
*= rDelWidth
+ rParam
.nLowerDiff
;
3142 nDiff
/= rParam
.nRemainWidth
;
3147 case TBLVAR_CHGABS
: // Tabelle variable, alle Nachbarn aendern
3148 if( COLFUZZY
< Abs( rParam
.nBoxWidth
-
3149 ( rDelWidth
+ rParam
.nLowerDiff
)))
3151 nDiff
= rDelWidth
+ rParam
.nLowerDiff
- rParam
.nBoxWidth
;
3153 rDelWidth
= rDelWidth
- USHORT(nDiff
);
3155 rDelWidth
= rDelWidth
+ USHORT(-nDiff
);
3163 SwFmtFrmSize
aNew( rOldSz
);
3164 aNew
.SetWidth( aNew
.GetWidth() + nDiff
);
3165 rParam
.aShareFmts
.SetSize( rBox
, aNew
);
3167 // dann leider nochmals die Lower anpassen
3168 for( USHORT i
= rBox
.GetTabLines().Count(); i
; )
3169 ::lcl_DelSelBox_CorrLowers( *rBox
.GetTabLines()[ --i
], rParam
,
3174 BOOL
lcl_DeleteBox_Rekursiv( CR_SetBoxWidth
& rParam
, SwTableBox
& rBox
,
3178 if( rBox
.GetSttNd() )
3182 rParam
.bAnyBoxFnd
= TRUE
;
3183 if( rBox
.GetFrmFmt()->GetProtect().IsCntntProtected() )
3187 SwTableBox
* pBox
= &rBox
;
3188 rParam
.aBoxes
.Insert( pBox
);
3192 ::_DeleteBox( rParam
.pTblNd
->GetTable(), &rBox
,
3193 rParam
.pUndo
, FALSE
, TRUE
, &rParam
.aShareFmts
);
3197 // die muessen leider alle sequentiel ueber die
3198 // Contentboxen geloescht werden
3199 for( USHORT i
= rBox
.GetTabLines().Count(); i
; )
3201 SwTableLine
& rLine
= *rBox
.GetTabLines()[ --i
];
3202 for( USHORT n
= rLine
.GetTabBoxes().Count(); n
; )
3203 if( !::lcl_DeleteBox_Rekursiv( rParam
,
3204 *rLine
.GetTabBoxes()[ --n
], bCheck
))
3211 BOOL
lcl_DelSelBox( SwTableLine
* pTabLine
, CR_SetBoxWidth
& rParam
,
3212 SwTwips nDist
, BOOL bCheck
)
3214 SwTableBoxes
& rBoxes
= pTabLine
->GetTabBoxes();
3215 USHORT n
, nCntEnd
, nBoxChkStt
, nBoxChkEnd
, nDelWidth
= 0;
3220 nBoxChkStt
= (USHORT
)rParam
.nSide
;
3221 nBoxChkEnd
= static_cast<USHORT
>(rParam
.nSide
+ rParam
.nBoxWidth
);
3226 nCntEnd
= rBoxes
.Count();
3227 nBoxChkStt
= static_cast<USHORT
>(rParam
.nSide
- rParam
.nBoxWidth
);
3228 nBoxChkEnd
= (USHORT
)rParam
.nSide
;
3232 while( n
!= nCntEnd
)
3236 pBox
= rBoxes
[ --n
];
3238 pBox
= rBoxes
[ n
++ ];
3240 SwFrmFmt
* pFmt
= pBox
->GetFrmFmt();
3241 const SwFmtFrmSize
& rSz
= pFmt
->GetFrmSize();
3242 long nWidth
= rSz
.GetWidth();
3243 BOOL bDelBox
= FALSE
, bChgLowers
= FALSE
;
3245 // die Boxenbreite testen und entpsrechend reagieren
3246 SwComparePosition ePosType
= ::_CheckBoxInRange(
3247 nBoxChkStt
, nBoxChkEnd
,
3248 USHORT(rParam
.bLeft
? nDist
- nWidth
: nDist
),
3249 USHORT(rParam
.bLeft
? nDist
: nDist
+ nWidth
));
3259 else if( rParam
.bLeft
)
3261 ::lcl_ChgBoxSize( *pBox
, rParam
, rSz
, nDelWidth
, nDist
);
3262 if( TBLFIX_CHGABS
== rParam
.nMode
)
3273 else if( !rParam
.bLeft
)
3275 ::lcl_ChgBoxSize( *pBox
, rParam
, rSz
, nDelWidth
, nDist
);
3276 if( TBLFIX_CHGABS
== rParam
.nMode
)
3281 case POS_OUTSIDE
: // Box ueberlappt Start/End vollstaendig
3282 case POS_INSIDE
: // Box liegt vollstaendig in Start/End
3283 case POS_EQUAL
: // Box und Start/End sind gleich
3287 case POS_OVERLAP_BEFORE
: // Box ueberlappt den Start
3288 if( nBoxChkStt
<= ( nDist
+ (rParam
.bLeft
? - nWidth
/ 2
3291 if( !pBox
->GetSttNd() )
3296 else if( !bCheck
&& rParam
.bLeft
)
3298 if( !pBox
->GetSttNd() )
3302 ::lcl_ChgBoxSize( *pBox
, rParam
, rSz
, nDelWidth
, nDist
);
3303 if( TBLFIX_CHGABS
== rParam
.nMode
)
3309 case POS_OVERLAP_BEHIND
: // Box ueberlappt das Ende
3311 // generell loeschen oder wie beim OVERLAP_Before nur die, die
3312 // bis zur Haelfte in die "Loesch-"Box reicht ???
3313 if( !pBox
->GetSttNd() )
3323 nDelWidth
= nDelWidth
+ USHORT(nWidth
);
3326 // die letzte/erste Box kann nur bei Tbl-Var geloescht werden,
3327 // wenn diese so gross ist, wie die Aenderung an der Tabelle
3328 if( (( TBLVAR_CHGABS
!= rParam
.nMode
||
3329 nDelWidth
!= rParam
.nBoxWidth
) &&
3330 COLFUZZY
> Abs( rParam
.bLeft
3332 : (nDist
+ nWidth
- rParam
.nTblWidth
)))
3333 || !::lcl_DeleteBox_Rekursiv( rParam
, *pBox
, bCheck
) )
3336 if( pFmt
->GetProtect().IsCntntProtected() )
3341 ::lcl_DeleteBox_Rekursiv( rParam
, *pBox
, bCheck
);
3347 else if( bChgLowers
)
3349 BOOL bFirst
= TRUE
, bCorrLowers
= FALSE
;
3350 long nLowerDiff
= 0;
3351 long nOldLower
= rParam
.nLowerDiff
;
3352 USHORT nOldRemain
= rParam
.nRemainWidth
;
3355 for( i
= pBox
->GetTabLines().Count(); i
; )
3357 rParam
.nLowerDiff
= nDelWidth
+ nOldLower
;
3358 rParam
.nRemainWidth
= nOldRemain
;
3359 SwTableLine
* pLine
= pBox
->GetTabLines()[ --i
];
3360 if( !::lcl_DelSelBox( pLine
, rParam
, nDist
, bCheck
))
3363 // gibt es die Box und die darin enthaltenen Lines noch??
3364 if( n
< rBoxes
.Count() &&
3365 pBox
== rBoxes
[ rParam
.bLeft
? n
: n
-1 ] &&
3366 i
< pBox
->GetTabLines().Count() &&
3367 pLine
== pBox
->GetTabLines()[ i
] )
3369 if( !bFirst
&& !bCorrLowers
&&
3370 COLFUZZY
< Abs( nLowerDiff
- rParam
.nLowerDiff
) )
3373 // die groesste "loesch" Breite entscheidet, aber nur wenn
3374 // nicht die gesamte Line geloescht wurde
3375 if( nLowerDiff
< rParam
.nLowerDiff
)
3376 nLowerDiff
= rParam
.nLowerDiff
;
3381 rParam
.nLowerDiff
= nOldLower
;
3382 rParam
.nRemainWidth
= nOldRemain
;
3384 // wurden alle Boxen geloescht? Dann ist die DelBreite natuerlich
3387 nLowerDiff
= nWidth
;
3389 // DelBreite anpassen!!
3390 nDelWidth
= nDelWidth
+ USHORT(nLowerDiff
);
3394 // wurde die Box schon entfernt?
3395 if( n
> rBoxes
.Count() ||
3396 pBox
!= rBoxes
[ ( rParam
.bLeft
? n
: n
-1 ) ] )
3398 // dann beim Loeschen nach rechts die Laufvar. anpassen
3404 // sonst muss die Groesse der Box angepasst werden
3405 SwFmtFrmSize
aNew( rSz
);
3406 BOOL bCorrRel
= FALSE
;
3408 if( TBLVAR_CHGABS
!= rParam
.nMode
)
3412 case POS_OVERLAP_BEFORE
: // Box ueberlappt den Start
3413 if( TBLFIX_CHGPROP
== rParam
.nMode
)
3414 bCorrRel
= rParam
.bLeft
;
3415 else if( rParam
.bLeft
) // TBLFIX_CHGABS
3417 nLowerDiff
= nLowerDiff
- nDelWidth
;
3423 case POS_OVERLAP_BEHIND
: // Box ueberlappt das Ende
3424 if( TBLFIX_CHGPROP
== rParam
.nMode
)
3425 bCorrRel
= !rParam
.bLeft
;
3426 else if( !rParam
.bLeft
) // TBLFIX_CHGABS
3428 nLowerDiff
= nLowerDiff
- nDelWidth
;
3435 ASSERT( !pBox
, "hier sollte man nie hinkommen" );
3442 if( !rParam
.nRemainWidth
)
3444 // dann kurz berechnen:
3446 rParam
.nRemainWidth
= USHORT(nDist
- nLowerDiff
);
3448 rParam
.nRemainWidth
= USHORT(rParam
.nTblWidth
- nDist
3452 long nDiff
= aNew
.GetWidth() - nLowerDiff
;
3453 nDiff
*= nDelWidth
+ rParam
.nLowerDiff
;
3454 nDiff
/= rParam
.nRemainWidth
;
3456 aNew
.SetWidth( aNew
.GetWidth() - nLowerDiff
+ nDiff
);
3459 aNew
.SetWidth( aNew
.GetWidth() - nLowerDiff
);
3460 rParam
.aShareFmts
.SetSize( *pBox
, aNew
);
3464 // dann leider nochmals die Lower anpassen
3465 for( i
= pBox
->GetTabLines().Count(); i
; )
3466 ::lcl_DelSelBox_CorrLowers( *pBox
->
3467 GetTabLines()[ --i
], rParam
, aNew
.GetWidth() );
3478 rParam
.nLowerDiff
= nDelWidth
;
3482 // Dummy Funktion fuer die Methode SetColWidth
3483 BOOL
lcl_DelOtherBox( SwTableLine
* , CR_SetBoxWidth
& , SwTwips
, BOOL
)
3490 void lcl_AjustLines( SwTableLine
* pLine
, CR_SetBoxWidth
& rParam
)
3492 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
3493 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
3495 SwTableBox
* pBox
= rBoxes
[ n
];
3497 SwFmtFrmSize
aSz( pBox
->GetFrmFmt()->GetFrmSize() );
3498 SwTwips nWidth
= aSz
.GetWidth();
3499 nWidth
*= rParam
.nDiff
;
3500 nWidth
/= rParam
.nMaxSize
;
3501 aSz
.SetWidth( nWidth
);
3502 rParam
.aShareFmts
.SetSize( *pBox
, aSz
);
3504 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
3505 ::lcl_AjustLines( pBox
->GetTabLines()[ i
], rParam
);
3509 #if !defined( PRODUCT ) || defined( JP_DEBUG )
3511 void _CheckBoxWidth( const SwTableLine
& rLine
, SwTwips nSize
)
3513 const SwTableBoxes
& rBoxes
= rLine
.GetTabBoxes();
3515 SwTwips nAktSize
= 0;
3516 // checke doch mal ob die Tabellen korrekte Breiten haben
3517 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
3519 const SwTableBox
* pBox
= rBoxes
[ n
];
3520 const SwTwips nBoxW
= pBox
->GetFrmFmt()->GetFrmSize().GetWidth();
3523 for( USHORT i
= 0; i
< pBox
->GetTabLines().Count(); ++i
)
3524 _CheckBoxWidth( *pBox
->GetTabLines()[ i
], nBoxW
);
3527 if( Abs( nAktSize
- nSize
) > ( COLFUZZY
* rBoxes
.Count() ) )
3529 DBG_ERROR( "Boxen der Line zu klein/gross" );
3530 #if defined( WNT ) && defined( JP_DEBUG )
3538 _FndBox
* lcl_SaveInsDelData( CR_SetBoxWidth
& rParam
, SwUndo
** ppUndo
,
3539 SwTableSortBoxes
& rTmpLst
, SwTwips nDistStt
)
3541 // suche alle Boxen / Lines
3542 SwTable
& rTbl
= rParam
.pTblNd
->GetTable();
3544 if( !rParam
.aBoxes
.Count() )
3546 // erstmal die Boxen besorgen !
3547 if( rParam
.bBigger
)
3548 for( USHORT n
= 0; n
< rTbl
.GetTabLines().Count(); ++n
)
3549 ::lcl_DelSelBox( rTbl
.GetTabLines()[ n
], rParam
, nDistStt
, TRUE
);
3551 for( USHORT n
= 0; n
< rTbl
.GetTabLines().Count(); ++n
)
3552 ::lcl_InsSelBox( rTbl
.GetTabLines()[ n
], rParam
, nDistStt
, TRUE
);
3555 // loeschen der gesamten Tabelle verhindern
3556 if( rParam
.bBigger
&& rParam
.aBoxes
.Count() ==
3557 rTbl
.GetTabSortBoxes().Count() )
3560 _FndBox
* pFndBox
= new _FndBox( 0, 0 );
3561 if( rParam
.bBigger
)
3562 pFndBox
->SetTableLines( rParam
.aBoxes
, rTbl
);
3565 _FndPara
aPara( rParam
.aBoxes
, pFndBox
);
3566 rTbl
.GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
3567 ASSERT( pFndBox
->GetLines().Count(), "Wo sind die Boxen" );
3568 pFndBox
->SetTableLines( rTbl
);
3571 rTmpLst
.Insert( &rTbl
.GetTabSortBoxes(), 0, rTbl
.GetTabSortBoxes().Count() );
3574 //Lines fuer das Layout-Update herausuchen.
3575 pFndBox
->DelFrms( rTbl
);
3577 // TL_CHART2: this function gest called from SetColWidth exclusively,
3578 // thus it is currently speculated that nothing needs to be done here.
3579 // Note: that SetColWidth is currently not completely understood though :-(
3584 BOOL
SwTable::SetColWidth( SwTableBox
& rAktBox
, USHORT eType
,
3585 SwTwips nAbsDiff
, SwTwips nRelDiff
, SwUndo
** ppUndo
)
3587 SetHTMLTableLayout( 0 ); // MIB 9.7.97: HTML-Layout loeschen
3589 const SwFmtFrmSize
& rSz
= GetFrmFmt()->GetFrmSize();
3590 const SvxLRSpaceItem
& rLR
= GetFrmFmt()->GetLRSpace();
3592 _FndBox
* pFndBox
= 0; // fuers Einfuegen/Loeschen
3593 SwTableSortBoxes
aTmpLst( 0, 5 ); // fuers Undo
3596 bLeft
= nsTblChgWidthHeightType::WH_COL_LEFT
== ( eType
& 0xff ) ||
3597 nsTblChgWidthHeightType::WH_CELL_LEFT
== ( eType
& 0xff ),
3598 bInsDel
= 0 != (eType
& nsTblChgWidthHeightType::WH_FLAG_INSDEL
);
3600 ULONG nBoxIdx
= rAktBox
.GetSttIdx();
3602 // bestimme die akt. Kante der Box
3603 // wird nur fuer die Breitenmanipulation benoetigt!
3604 const SwTwips nDist
= ::lcl_GetDistance( &rAktBox
, bLeft
);
3605 SwTwips nDistStt
= 0;
3606 CR_SetBoxWidth
aParam( eType
, nRelDiff
, nDist
, rSz
.GetWidth(),
3607 bLeft
? nDist
: rSz
.GetWidth() - nDist
,
3608 (SwTableNode
*)rAktBox
.GetSttNd()->FindTableNode() );
3609 bBigger
= aParam
.bBigger
;
3611 FN_lcl_SetBoxWidth fnSelBox
, fnOtherBox
;
3616 fnSelBox
= lcl_DelSelBox
;
3617 fnOtherBox
= lcl_DelOtherBox
;
3618 aParam
.nBoxWidth
= (USHORT
)rAktBox
.GetFrmFmt()->GetFrmSize().GetWidth();
3620 nDistStt
= rSz
.GetWidth();
3624 fnSelBox
= lcl_InsSelBox
;
3625 fnOtherBox
= lcl_InsOtherBox
;
3630 fnSelBox
= lcl_SetSelBoxWidth
;
3631 fnOtherBox
= lcl_SetOtherBoxWidth
;
3635 switch( eType
& 0xff )
3637 case nsTblChgWidthHeightType::WH_COL_RIGHT
:
3638 case nsTblChgWidthHeightType::WH_COL_LEFT
:
3639 if( TBLVAR_CHGABS
== eTblChgMode
)
3644 // erstmal testen, ob ueberhaupt Platz ist
3645 BOOL bChgLRSpace
= TRUE
;
3648 if( GetFrmFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) &&
3649 !rSz
.GetWidthPercent() )
3651 bRet
= rSz
.GetWidth() < USHRT_MAX
- nRelDiff
;
3652 bChgLRSpace
= bLeft
? rLR
.GetLeft() >= nAbsDiff
3653 : rLR
.GetRight() >= nAbsDiff
;
3656 bRet
= bLeft
? rLR
.GetLeft() >= nAbsDiff
3657 : rLR
.GetRight() >= nAbsDiff
;
3659 if( !bRet
&& bInsDel
&&
3660 // auf der anderen Seite Platz?
3661 ( bLeft
? rLR
.GetRight() >= nAbsDiff
3662 : rLR
.GetLeft() >= nAbsDiff
))
3664 bRet
= TRUE
; bLeft
= !bLeft
;
3669 // dann sich selbst rekursiv aufrufen; nur mit
3670 // einem anderen Mode -> proprotional
3671 TblChgMode eOld
= eTblChgMode
;
3672 eTblChgMode
= TBLFIX_CHGPROP
;
3674 bRet
= SetColWidth( rAktBox
, eType
, nAbsDiff
, nRelDiff
,
3683 for( n
= 0; n
< aLines
.Count(); ++n
)
3686 if( !(*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, TRUE
))
3698 pFndBox
= ::lcl_SaveInsDelData( aParam
, ppUndo
,
3699 aTmpLst
, nDistStt
);
3700 if( aParam
.bBigger
&& aParam
.aBoxes
.Count() ==
3701 aSortCntBoxes
.Count() )
3703 // dies gesamte Tabelle soll geloescht werden!!
3704 GetFrmFmt()->GetDoc()->DeleteRowCol( aParam
.aBoxes
);
3709 *ppUndo
= aParam
.CreateUndo(
3710 aParam
.bBigger
? UNDO_COL_DELETE
3711 : UNDO_TABLE_INSCOL
);
3714 *ppUndo
= new SwUndoAttrTbl( *aParam
.pTblNd
, TRUE
);
3716 long nFrmWidth
= LONG_MAX
;
3718 SwFmtFrmSize
aSz( rSz
);
3719 SvxLRSpaceItem
aLR( rLR
);
3722 // falls die Tabelle keinen Platz zum Wachsen hat, dann
3723 // muessen wir welchen schaffen!
3724 if( aSz
.GetWidth() + nRelDiff
> USHRT_MAX
)
3726 // dann mal herunterbrechen auf USHRT_MAX / 2
3727 CR_SetBoxWidth
aTmpPara( 0, aSz
.GetWidth() / 2,
3728 0, aSz
.GetWidth(), aSz
.GetWidth(), aParam
.pTblNd
);
3729 for( USHORT nLn
= 0; nLn
< aLines
.Count(); ++nLn
)
3730 ::lcl_AjustLines( aLines
[ nLn
], aTmpPara
);
3731 aSz
.SetWidth( aSz
.GetWidth() / 2 );
3732 aParam
.nDiff
= nRelDiff
/= 2;
3734 aParam
.nMaxSize
/= 2;
3738 aLR
.SetLeft( USHORT( aLR
.GetLeft() - nAbsDiff
) );
3740 aLR
.SetRight( USHORT( aLR
.GetRight() - nAbsDiff
) );
3743 aLR
.SetLeft( USHORT( aLR
.GetLeft() + nAbsDiff
) );
3745 aLR
.SetRight( USHORT( aLR
.GetRight() + nAbsDiff
) );
3748 GetFrmFmt()->SetFmtAttr( aLR
);
3749 const SwFmtHoriOrient
& rHOri
= GetFrmFmt()->GetHoriOrient();
3750 if( text::HoriOrientation::FULL
== rHOri
.GetHoriOrient() ||
3751 (text::HoriOrientation::LEFT
== rHOri
.GetHoriOrient() && aLR
.GetLeft()) ||
3752 (text::HoriOrientation::RIGHT
== rHOri
.GetHoriOrient() && aLR
.GetRight()))
3754 SwFmtHoriOrient
aHOri( rHOri
);
3755 aHOri
.SetHoriOrient( text::HoriOrientation::NONE
);
3756 GetFrmFmt()->SetFmtAttr( aHOri
);
3758 // sollte die Tabelle noch auf relativen Werten
3759 // (USHRT_MAX) stehen dann muss es jetzt auf absolute
3760 // umgerechnet werden. Bug 61494
3761 if( GetFrmFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) &&
3762 !rSz
.GetWidthPercent() )
3764 SwTabFrm
* pTabFrm
= (SwTabFrm
*)SwClientIter(
3765 *GetFrmFmt() ).First( TYPE( SwTabFrm
));
3767 pTabFrm
->Prt().Width() != rSz
.GetWidth() )
3769 nFrmWidth
= pTabFrm
->Prt().Width();
3771 nFrmWidth
+= nAbsDiff
;
3773 nFrmWidth
-= nAbsDiff
;
3779 aSz
.SetWidth( aSz
.GetWidth() + nRelDiff
);
3781 aSz
.SetWidth( aSz
.GetWidth() - nRelDiff
);
3783 if( rSz
.GetWidthPercent() )
3784 aSz
.SetWidthPercent( static_cast<BYTE
>(( aSz
.GetWidth() * 100 ) /
3785 ( aSz
.GetWidth() + aLR
.GetRight() + aLR
.GetLeft())));
3787 GetFrmFmt()->SetFmtAttr( aSz
);
3788 aParam
.nTblWidth
= USHORT( aSz
.GetWidth() );
3792 for( n
= aLines
.Count(); n
; )
3796 (*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, FALSE
);
3799 // sollte die Tabelle noch auf relativen Werten
3800 // (USHRT_MAX) stehen dann muss es jetzt auf absolute
3801 // umgerechnet werden. Bug 61494
3802 if( LONG_MAX
!= nFrmWidth
)
3804 SwFmtFrmSize
aAbsSz( aSz
);
3805 aAbsSz
.SetWidth( nFrmWidth
);
3806 GetFrmFmt()->SetFmtAttr( aAbsSz
);
3811 ( bLeft
? nDist
: Abs( rSz
.GetWidth() - nDist
) > COLFUZZY
) )
3814 if( bLeft
&& TBLFIX_CHGABS
== eTblChgMode
&& !bInsDel
)
3815 aParam
.bBigger
= !bBigger
;
3817 // erstmal testen, ob ueberhaupt Platz ist
3820 if( aParam
.bBigger
)
3822 for( n
= 0; n
< aLines
.Count(); ++n
)
3825 if( !(*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, TRUE
))
3834 if( 0 != ( bRet
= bLeft
? nDist
!= 0
3835 : ( rSz
.GetWidth() - nDist
) > COLFUZZY
) )
3837 for( n
= 0; n
< aLines
.Count(); ++n
)
3840 if( !(*fnOtherBox
)( aLines
[ n
], aParam
, 0, TRUE
))
3846 if( bRet
&& !aParam
.bAnyBoxFnd
)
3850 if( !bRet
&& rAktBox
.GetFrmFmt()->GetFrmSize().GetWidth()
3851 - nRelDiff
> COLFUZZY
+
3852 ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
3854 // dann den Platz von der akt. Zelle nehmen
3855 aParam
.bSplittBox
= TRUE
;
3856 // aber das muss auch mal getestet werden!
3859 for( n
= 0; n
< aLines
.Count(); ++n
)
3862 if( !(*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, TRUE
))
3871 else if( aParam
.bBigger
)
3873 for( n
= 0; n
< aLines
.Count(); ++n
)
3876 if( !(*fnOtherBox
)( aLines
[ n
], aParam
, 0, TRUE
))
3885 for( n
= 0; n
< aLines
.Count(); ++n
)
3888 if( !(*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, TRUE
))
3896 // wenn ja, dann setzen
3899 CR_SetBoxWidth
aParam1( aParam
);
3902 aParam1
.bBigger
= !aParam
.bBigger
;
3903 pFndBox
= ::lcl_SaveInsDelData( aParam
, ppUndo
,
3904 aTmpLst
, nDistStt
);
3906 *ppUndo
= aParam
.CreateUndo(
3907 aParam
.bBigger
? UNDO_TABLE_DELBOX
3908 : UNDO_TABLE_INSCOL
);
3911 *ppUndo
= new SwUndoAttrTbl( *aParam
.pTblNd
, TRUE
);
3914 ? ( TBLFIX_CHGABS
== eTblChgMode
? bLeft
: bLeft
)
3915 : ( TBLFIX_CHGABS
!= eTblChgMode
&& bLeft
) )
3917 for( n
= aLines
.Count(); n
; )
3921 aParam1
.LoopClear();
3922 (*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, FALSE
);
3923 (*fnOtherBox
)( aLines
[ n
], aParam1
, nDistStt
, FALSE
);
3927 for( n
= aLines
.Count(); n
; )
3931 aParam1
.LoopClear();
3932 (*fnOtherBox
)( aLines
[ n
], aParam1
, nDistStt
, FALSE
);
3933 (*fnSelBox
)( aLines
[ n
], aParam
, nDistStt
, FALSE
);
3939 case nsTblChgWidthHeightType::WH_CELL_RIGHT
:
3940 case nsTblChgWidthHeightType::WH_CELL_LEFT
:
3941 if( TBLVAR_CHGABS
== eTblChgMode
)
3943 // dann sich selbst rekursiv aufrufen; nur mit
3944 // einem anderen Mode -> Nachbarn
3945 TblChgMode eOld
= eTblChgMode
;
3946 eTblChgMode
= TBLFIX_CHGABS
;
3948 bRet
= SetColWidth( rAktBox
, eType
, nAbsDiff
, nRelDiff
,
3953 else if( bInsDel
|| ( bLeft
? nDist
3954 : (rSz
.GetWidth() - nDist
) > COLFUZZY
))
3956 if( bLeft
&& TBLFIX_CHGABS
== eTblChgMode
&& !bInsDel
)
3957 aParam
.bBigger
= !bBigger
;
3959 // erstmal testen, ob ueberhaupt Platz ist
3960 SwTableBox
* pBox
= &rAktBox
;
3961 SwTableLine
* pLine
= rAktBox
.GetUpper();
3962 while( pLine
->GetUpper() )
3964 USHORT nPos
= pLine
->GetTabBoxes().C40_GETPOS( SwTableBox
, pBox
);
3965 if( bLeft
? nPos
: nPos
+ 1 != pLine
->GetTabBoxes().Count() )
3968 pBox
= pLine
->GetUpper();
3969 pLine
= pBox
->GetUpper();
3972 if( pLine
->GetUpper() )
3974 // dann muss die Distanz wieder korriegiert werden!
3975 aParam
.nSide
-= ::lcl_GetDistance( pLine
->GetUpper(), TRUE
);
3978 aParam
.nMaxSize
= aParam
.nSide
;
3980 aParam
.nMaxSize
= pLine
->GetUpper()->GetFrmFmt()->
3981 GetFrmSize().GetWidth() - aParam
.nSide
;
3984 // erstmal testen, ob ueberhaupt Platz ist
3987 if( 0 != ( bRet
= bLeft
? nDist
!= 0
3988 : ( rSz
.GetWidth() - nDist
) > COLFUZZY
) &&
3991 bRet
= (*fnOtherBox
)( pLine
, aParam
, 0, TRUE
);
3992 if( bRet
&& !aParam
.bAnyBoxFnd
)
3996 if( !bRet
&& !aParam
.bBigger
&& rAktBox
.GetFrmFmt()->
3997 GetFrmSize().GetWidth() - nRelDiff
> COLFUZZY
+
3998 ( 567 / 2 /* min. 0,5 cm Platz lassen*/) )
4000 // dann den Platz von der akt. Zelle nehmen
4001 aParam
.bSplittBox
= TRUE
;
4007 FN_lcl_SetBoxWidth fnTmp
= aParam
.bBigger
? fnOtherBox
: fnSelBox
;
4008 bRet
= (*fnTmp
)( pLine
, aParam
, nDistStt
, TRUE
);
4011 // wenn ja, dann setzen
4014 CR_SetBoxWidth
aParam1( aParam
);
4017 aParam1
.bBigger
= !aParam
.bBigger
;
4018 pFndBox
= ::lcl_SaveInsDelData( aParam
, ppUndo
, aTmpLst
, nDistStt
);
4020 *ppUndo
= aParam
.CreateUndo(
4021 aParam
.bBigger
? UNDO_TABLE_DELBOX
4022 : UNDO_TABLE_INSCOL
);
4025 *ppUndo
= new SwUndoAttrTbl( *aParam
.pTblNd
, TRUE
);
4028 ? ( TBLFIX_CHGABS
== eTblChgMode
? (bBigger
&& bLeft
) : bLeft
)
4029 : ( TBLFIX_CHGABS
!= eTblChgMode
&& bLeft
) )
4031 (*fnSelBox
)( pLine
, aParam
, nDistStt
, FALSE
);
4032 (*fnOtherBox
)( pLine
, aParam1
, nDistStt
, FALSE
);
4036 (*fnOtherBox
)( pLine
, aParam1
, nDistStt
, FALSE
);
4037 (*fnSelBox
)( pLine
, aParam
, nDistStt
, FALSE
);
4047 // dann raeume die Struktur aller Lines auf
4051 if( !bBigger
|| pFndBox
->AreLinesToRestore( *this ) )
4052 pFndBox
->MakeFrms( *this );
4054 // TL_CHART2: it is currently unclear if sth has to be done here.
4055 // The function name hints that nothing needs to be done, on the other
4056 // hand there is a case where sth gets deleted. :-(
4060 if( ppUndo
&& *ppUndo
)
4062 aParam
.pUndo
->SetColWidthParam( nBoxIdx
, static_cast<USHORT
>(eTblChgMode
), eType
,
4063 nAbsDiff
, nRelDiff
);
4064 if( !aParam
.bBigger
)
4065 aParam
.pUndo
->SaveNewBoxes( *aParam
.pTblNd
, aTmpLst
);
4079 _FndBox
* lcl_SaveInsDelData( CR_SetLineHeight
& rParam
, SwUndo
** ppUndo
,
4080 SwTableSortBoxes
& rTmpLst
)
4082 // suche alle Boxen / Lines
4083 SwTable
& rTbl
= rParam
.pTblNd
->GetTable();
4085 ASSERT( rParam
.aBoxes
.Count(), "ohne Boxen ist nichts zu machen!" );
4087 // loeschen der gesamten Tabelle verhindern
4088 if( !rParam
.bBigger
&& rParam
.aBoxes
.Count() ==
4089 rTbl
.GetTabSortBoxes().Count() )
4092 _FndBox
* pFndBox
= new _FndBox( 0, 0 );
4093 if( !rParam
.bBigger
)
4094 pFndBox
->SetTableLines( rParam
.aBoxes
, rTbl
);
4097 _FndPara
aPara( rParam
.aBoxes
, pFndBox
);
4098 rTbl
.GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
4099 ASSERT( pFndBox
->GetLines().Count(), "Wo sind die Boxen" );
4100 pFndBox
->SetTableLines( rTbl
);
4103 rTmpLst
.Insert( &rTbl
.GetTabSortBoxes(), 0, rTbl
.GetTabSortBoxes().Count() );
4106 //Lines fuer das Layout-Update heraussuchen.
4107 pFndBox
->DelFrms( rTbl
);
4109 // TL_CHART2: it is currently unclear if sth has to be done here.
4114 void SetLineHeight( SwTableLine
& rLine
, SwTwips nOldHeight
, SwTwips nNewHeight
,
4117 SwLayoutFrm
* pLineFrm
= GetRowFrm( rLine
);
4118 ASSERT( pLineFrm
, "wo ist der Frm von der SwTableLine?" );
4120 SwFrmFmt
* pFmt
= rLine
.ClaimFrmFmt();
4122 SwTwips nMyNewH
, nMyOldH
= pLineFrm
->Frm().Height();
4123 if( !nOldHeight
) // die BaseLine und absolut
4124 nMyNewH
= nMyOldH
+ nNewHeight
;
4127 // moeglichst genau rechnen
4128 Fraction
aTmp( nMyOldH
);
4129 aTmp
*= Fraction( nNewHeight
, nOldHeight
);
4130 aTmp
+= Fraction( 1, 2 ); // ggfs. aufrunden
4134 SwFrmSize eSize
= ATT_MIN_SIZE
;
4136 ( nMyOldH
- nMyNewH
) > ( CalcRowRstHeight( pLineFrm
) + ROWFUZZY
))
4137 eSize
= ATT_FIX_SIZE
;
4139 pFmt
->SetFmtAttr( SwFmtFrmSize( eSize
, 0, nMyNewH
) );
4141 // erst alle inneren anpassen
4142 SwTableBoxes
& rBoxes
= rLine
.GetTabBoxes();
4143 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
4145 SwTableBox
& rBox
= *rBoxes
[ n
];
4146 for( USHORT i
= 0; i
< rBox
.GetTabLines().Count(); ++i
)
4147 SetLineHeight( *rBox
.GetTabLines()[ i
], nMyOldH
, nMyNewH
, bMinSize
);
4151 BOOL
lcl_SetSelLineHeight( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
4152 SwTwips nDist
, BOOL bCheck
)
4157 // Zeilenhoehe einstellen
4158 SetLineHeight( *pLine
, 0, rParam
.bBigger
? nDist
: -nDist
,
4161 else if( !rParam
.bBigger
)
4163 // anhand der alten Size die neue relative errechnen
4164 SwLayoutFrm
* pLineFrm
= GetRowFrm( *pLine
);
4165 ASSERT( pLineFrm
, "wo ist der Frm von der SwTableLine?" );
4166 SwTwips nRstHeight
= CalcRowRstHeight( pLineFrm
);
4167 if( (nRstHeight
+ ROWFUZZY
) < nDist
)
4173 BOOL
lcl_SetOtherLineHeight( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
4174 SwTwips nDist
, BOOL bCheck
)
4179 if( rParam
.bBigger
)
4181 // anhand der alten Size die neue relative errechnen
4182 SwLayoutFrm
* pLineFrm
= GetRowFrm( *pLine
);
4183 ASSERT( pLineFrm
, "wo ist der Frm von der SwTableLine?" );
4185 if( TBLFIX_CHGPROP
== rParam
.nMode
)
4187 nDist
*= pLineFrm
->Frm().Height();
4188 nDist
/= rParam
.nMaxHeight
;
4190 bRet
= nDist
<= CalcRowRstHeight( pLineFrm
);
4195 // Zeilenhoehe einstellen
4196 // pLine ist die nachfolgende / vorhergehende -> also anpassen
4197 if( TBLFIX_CHGPROP
== rParam
.nMode
)
4199 SwLayoutFrm
* pLineFrm
= GetRowFrm( *pLine
);
4200 ASSERT( pLineFrm
, "wo ist der Frm von der SwTableLine?" );
4202 // aus der alten Size die neue relative errechnen
4203 // Wird die selektierte Box groesser ueber den MaxSpace anpassen,
4204 // sonst ueber die MaxHeight
4205 if( 1 /*!rParam.bBigger*/ )
4207 nDist
*= pLineFrm
->Frm().Height();
4208 nDist
/= rParam
.nMaxHeight
;
4212 // aus der alten Size die neue relative errechnen
4213 nDist
*= CalcRowRstHeight( pLineFrm
);
4214 nDist
/= rParam
.nMaxSpace
;
4217 SetLineHeight( *pLine
, 0, rParam
.bBigger
? -nDist
: nDist
,
4223 BOOL
lcl_InsDelSelLine( SwTableLine
* pLine
, CR_SetLineHeight
& rParam
,
4224 SwTwips nDist
, BOOL bCheck
)
4229 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
4230 SwDoc
* pDoc
= pLine
->GetFrmFmt()->GetDoc();
4231 if( !rParam
.bBigger
)
4235 for( n
= rBoxes
.Count(); n
; )
4236 ::lcl_SaveUpperLowerBorder( rParam
.pTblNd
->GetTable(),
4238 rParam
.aShareFmts
);
4239 for( n
= rBoxes
.Count(); n
; )
4240 ::_DeleteBox( rParam
.pTblNd
->GetTable(),
4241 rBoxes
[ --n
], rParam
.pUndo
, FALSE
,
4242 FALSE
, &rParam
.aShareFmts
);
4247 SwTableLine
* pNewLine
= new SwTableLine( (SwTableLineFmt
*)pLine
->GetFrmFmt(),
4248 rBoxes
.Count(), pLine
->GetUpper() );
4249 SwTableLines
* pLines
;
4250 if( pLine
->GetUpper() )
4251 pLines
= &pLine
->GetUpper()->GetTabLines();
4253 pLines
= &rParam
.pTblNd
->GetTable().GetTabLines();
4254 USHORT nPos
= pLines
->C40_GETPOS( SwTableLine
, pLine
);
4257 pLines
->C40_INSERT( SwTableLine
, pNewLine
, nPos
);
4259 SwFrmFmt
* pNewFmt
= pNewLine
->ClaimFrmFmt();
4260 pNewFmt
->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE
, 0, nDist
) );
4262 // und noch mal die Anzahl Boxen erzeugen
4263 SwTableBoxes
& rNewBoxes
= pNewLine
->GetTabBoxes();
4264 for( USHORT n
= 0; n
< rBoxes
.Count(); ++n
)
4267 SwTableBox
* pOld
= rBoxes
[ n
];
4268 if( !pOld
->GetSttNd() )
4270 // keine normale "Content"-Box also auf die 1. naechste
4271 // Box zurueckfallen
4272 nWidth
= pOld
->GetFrmFmt()->GetFrmSize().GetWidth();
4273 while( !pOld
->GetSttNd() )
4274 pOld
= pOld
->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ];
4276 ::_InsTblBox( pDoc
, rParam
.pTblNd
, pNewLine
,
4277 (SwTableBoxFmt
*)pOld
->GetFrmFmt(), pOld
, n
);
4279 // Sonderbehandlung fuer Umrandung die Obere muss
4281 const SvxBoxItem
& rBoxItem
= pOld
->GetFrmFmt()->GetBox();
4282 if( rBoxItem
.GetTop() )
4284 SvxBoxItem
aTmp( rBoxItem
);
4285 aTmp
.SetLine( 0, BOX_LINE_TOP
);
4286 rParam
.aShareFmts
.SetAttr( rParam
.bTop
4288 : *rNewBoxes
[ n
], aTmp
);
4292 rParam
.aShareFmts
.SetAttr( *rNewBoxes
[ n
],
4293 SwFmtFrmSize( ATT_FIX_SIZE
, nWidth
, 0 ) );
4299 // Boxen einsammeln!
4300 SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
4301 for( USHORT n
= rBoxes
.Count(); n
; )
4303 SwTableBox
* pBox
= rBoxes
[ --n
];
4304 if( pBox
->GetFrmFmt()->GetProtect().IsCntntProtected() )
4307 if( pBox
->GetSttNd() )
4308 rParam
.aBoxes
.Insert( pBox
);
4311 for( USHORT i
= pBox
->GetTabLines().Count(); i
; )
4312 lcl_InsDelSelLine( pBox
->GetTabLines()[ --i
],
4320 BOOL
SwTable::SetRowHeight( SwTableBox
& rAktBox
, USHORT eType
,
4321 SwTwips nAbsDiff
, SwTwips nRelDiff
,SwUndo
** ppUndo
)
4323 SwTableLine
* pLine
= rAktBox
.GetUpper();
4325 SwTableLine
* pBaseLine
= pLine
;
4326 while( pBaseLine
->GetUpper() )
4327 pBaseLine
= pBaseLine
->GetUpper()->GetUpper();
4329 _FndBox
* pFndBox
= 0; // fuers Einfuegen/Loeschen
4330 SwTableSortBoxes
aTmpLst( 0, 5 ); // fuers Undo
4333 bTop
= nsTblChgWidthHeightType::WH_ROW_TOP
== ( eType
& 0xff ) ||
4334 nsTblChgWidthHeightType::WH_CELL_TOP
== ( eType
& 0xff ),
4335 bInsDel
= 0 != (eType
& nsTblChgWidthHeightType::WH_FLAG_INSDEL
);
4336 USHORT n
, nBaseLinePos
= GetTabLines().C40_GETPOS( SwTableLine
, pBaseLine
);
4337 ULONG nBoxIdx
= rAktBox
.GetSttIdx();
4339 CR_SetLineHeight
aParam( eType
,
4340 (SwTableNode
*)rAktBox
.GetSttNd()->FindTableNode() );
4341 bBigger
= aParam
.bBigger
;
4343 FN_lcl_SetLineHeight fnSelLine
, fnOtherLine
= lcl_SetOtherLineHeight
;
4345 fnSelLine
= lcl_InsDelSelLine
;
4347 fnSelLine
= lcl_SetSelLineHeight
;
4349 SwTableLines
* pLines
= &aLines
;
4351 // wie kommt man an die Hoehen heran?
4352 switch( eType
& 0xff )
4354 case nsTblChgWidthHeightType::WH_CELL_TOP
:
4355 case nsTblChgWidthHeightType::WH_CELL_BOTTOM
:
4356 if( pLine
== pBaseLine
)
4357 break; // dann geht es nicht!
4359 // ist eine verschachtelte Line (Box!)
4360 pLines
= &pLine
->GetUpper()->GetTabLines();
4361 nBaseLinePos
= pLines
->C40_GETPOS( SwTableLine
, pLine
);
4365 case nsTblChgWidthHeightType::WH_ROW_TOP
:
4366 case nsTblChgWidthHeightType::WH_ROW_BOTTOM
:
4368 if( bInsDel
&& !bBigger
) // um wieviel wird es Hoeher?
4370 nAbsDiff
= GetRowFrm( *pBaseLine
)->Frm().Height();
4373 if( TBLVAR_CHGABS
== eTblChgMode
)
4375 // erstmal testen, ob ueberhaupt Platz ist
4379 // was ist mit Top, was ist mit Tabelle im Rahmen oder in Kopf-/Fusszeile
4380 // mit fester Hoehe ??
4383 // dann sich selbst rekursiv aufrufen; nur mit
4384 // einem anderen Mode -> proprotional
4385 TblChgMode eOld
= eTblChgMode
;
4386 eTblChgMode
= TBLFIX_CHGPROP
;
4388 bRet
= SetRowHeight( rAktBox
, eType
, nAbsDiff
,
4396 bRet
= (*fnSelLine
)( (*pLines
)[ nBaseLinePos
], aParam
,
4403 if( !aParam
.aBoxes
.Count() )
4404 ::lcl_InsDelSelLine( (*pLines
)[ nBaseLinePos
],
4407 pFndBox
= ::lcl_SaveInsDelData( aParam
, ppUndo
, aTmpLst
);
4409 // #110525# delete complete table when last row is
4412 aParam
.aBoxes
.Count() == aSortCntBoxes
.Count() )
4414 GetFrmFmt()->GetDoc()->DeleteRowCol( aParam
.aBoxes
);
4420 *ppUndo
= aParam
.CreateUndo(
4421 bBigger
? UNDO_TABLE_INSROW
4422 : UNDO_ROW_DELETE
);
4425 *ppUndo
= new SwUndoAttrTbl( *aParam
.pTblNd
, TRUE
);
4427 (*fnSelLine
)( (*pLines
)[ nBaseLinePos
], aParam
,
4436 nStt
= 0, nEnd
= nBaseLinePos
;
4438 nStt
= nBaseLinePos
+ 1, nEnd
= pLines
->Count();
4440 // die akt. Hoehe der Lines besorgen
4441 if( TBLFIX_CHGPROP
== eTblChgMode
)
4443 for( n
= nStt
; n
< nEnd
; ++n
)
4445 SwLayoutFrm
* pLineFrm
= GetRowFrm( *(*pLines
)[ n
] );
4446 ASSERT( pLineFrm
, "wo ist der Frm von der SwTableLine?" );
4447 aParam
.nMaxSpace
+= CalcRowRstHeight( pLineFrm
);
4448 aParam
.nMaxHeight
+= pLineFrm
->Frm().Height();
4450 if( bBigger
&& aParam
.nMaxSpace
< nAbsDiff
)
4455 if( bTop
? nEnd
: nStt
< nEnd
)
4470 for( n
= nStt
; n
< nEnd
; ++n
)
4472 if( !(*fnOtherLine
)( (*pLines
)[ n
], aParam
,
4481 bRet
= (*fnSelLine
)( (*pLines
)[ nBaseLinePos
], aParam
,
4487 // dann mal anpassen
4490 if( !aParam
.aBoxes
.Count() )
4491 ::lcl_InsDelSelLine( (*pLines
)[ nBaseLinePos
],
4493 pFndBox
= ::lcl_SaveInsDelData( aParam
, ppUndo
, aTmpLst
);
4495 *ppUndo
= aParam
.CreateUndo(
4496 bBigger
? UNDO_TABLE_INSROW
4497 : UNDO_ROW_DELETE
);
4500 *ppUndo
= new SwUndoAttrTbl( *aParam
.pTblNd
, TRUE
);
4502 CR_SetLineHeight
aParam1( aParam
);
4503 if( TBLFIX_CHGPROP
== eTblChgMode
&& !bBigger
&&
4506 // dann muss der gesamte Platz auf alle Lines
4507 // gleichmaessig verteilt werden. Dafuer wird die
4509 aParam1
.nLines
= nEnd
- nStt
;
4514 (*fnSelLine
)( (*pLines
)[ nBaseLinePos
], aParam
,
4516 for( n
= nStt
; n
< nEnd
; ++n
)
4517 (*fnOtherLine
)( (*pLines
)[ n
], aParam1
,
4522 for( n
= nStt
; n
< nEnd
; ++n
)
4523 (*fnOtherLine
)( (*pLines
)[ n
], aParam1
,
4525 (*fnSelLine
)( (*pLines
)[ nBaseLinePos
], aParam
,
4531 // dann sich selbst rekursiv aufrufen; nur mit
4532 // einem anderen Mode -> proprotional
4533 TblChgMode eOld
= eTblChgMode
;
4534 eTblChgMode
= TBLVAR_CHGABS
;
4536 bRet
= SetRowHeight( rAktBox
, eType
, nAbsDiff
,
4549 // dann raeume die Struktur aller Lines auf
4553 if( bBigger
|| pFndBox
->AreLinesToRestore( *this ) )
4554 pFndBox
->MakeFrms( *this );
4556 // TL_CHART2: it is currently unclear if sth has to be done here.
4560 if( ppUndo
&& *ppUndo
)
4562 aParam
.pUndo
->SetColWidthParam( nBoxIdx
, static_cast<USHORT
>(eTblChgMode
), eType
,
4563 nAbsDiff
, nRelDiff
);
4565 aParam
.pUndo
->SaveNewBoxes( *aParam
.pTblNd
, aTmpLst
);
4576 SwFrmFmt
* SwShareBoxFmt::GetFormat( long nWidth
) const
4578 SwFrmFmt
*pRet
= 0, *pTmp
;
4579 for( USHORT n
= aNewFmts
.Count(); n
; )
4580 if( ( pTmp
= (SwFrmFmt
*)aNewFmts
[ --n
])->GetFrmSize().GetWidth()
4589 SwFrmFmt
* SwShareBoxFmt::GetFormat( const SfxPoolItem
& rItem
) const
4591 const SfxPoolItem
* pItem
;
4592 USHORT nWhich
= rItem
.Which();
4593 SwFrmFmt
*pRet
= 0, *pTmp
;
4594 const SfxPoolItem
& rFrmSz
= pOldFmt
->GetFmtAttr( RES_FRM_SIZE
, FALSE
);
4595 for( USHORT n
= aNewFmts
.Count(); n
; )
4596 if( SFX_ITEM_SET
== ( pTmp
= (SwFrmFmt
*)aNewFmts
[ --n
])->
4597 GetItemState( nWhich
, FALSE
, &pItem
) && *pItem
== rItem
&&
4598 pTmp
->GetFmtAttr( RES_FRM_SIZE
, FALSE
) == rFrmSz
)
4606 void SwShareBoxFmt::AddFormat( const SwFrmFmt
& rNew
)
4608 void* pFmt
= (void*)&rNew
;
4609 aNewFmts
.Insert( pFmt
, aNewFmts
.Count() );
4612 BOOL
SwShareBoxFmt::RemoveFormat( const SwFrmFmt
& rFmt
)
4614 // returnt TRUE, wenn geloescht werden kann
4615 if( pOldFmt
== &rFmt
)
4618 void* p
= (void*)&rFmt
;
4619 USHORT nFnd
= aNewFmts
.GetPos( p
);
4620 if( USHRT_MAX
!= nFnd
)
4621 aNewFmts
.Remove( nFnd
);
4622 return 0 == aNewFmts
.Count();
4625 SwShareBoxFmts::~SwShareBoxFmts()
4629 SwFrmFmt
* SwShareBoxFmts::GetFormat( const SwFrmFmt
& rFmt
, long nWidth
) const
4632 return Seek_Entry( rFmt
, &nPos
)
4633 ? aShareArr
[ nPos
]->GetFormat( nWidth
)
4636 SwFrmFmt
* SwShareBoxFmts::GetFormat( const SwFrmFmt
& rFmt
,
4637 const SfxPoolItem
& rItem
) const
4640 return Seek_Entry( rFmt
, &nPos
)
4641 ? aShareArr
[ nPos
]->GetFormat( rItem
)
4645 void SwShareBoxFmts::AddFormat( const SwFrmFmt
& rOld
, const SwFrmFmt
& rNew
)
4647 // wenn das Format nicht geshared ist, braucht es auch nicht in die
4648 // Liste aufgenommen werden. Denn es gibt keinen 2. der es sucht.
4649 //leider werden auch die CellFrms gefunden
4650 // if( !rOld.IsLastDepend() )
4653 SwShareBoxFmt
* pEntry
;
4654 if( !Seek_Entry( rOld
, &nPos
))
4656 pEntry
= new SwShareBoxFmt( rOld
);
4657 aShareArr
.C40_INSERT( SwShareBoxFmt
, pEntry
, nPos
);
4660 pEntry
= aShareArr
[ nPos
];
4662 pEntry
->AddFormat( rNew
);
4665 void SwShareBoxFmts::ChangeFrmFmt( SwTableBox
* pBox
, SwTableLine
* pLn
,
4672 pOld
= pBox
->GetFrmFmt();
4674 pBox
->ChgFrmFmt( (SwTableBoxFmt
*)&rFmt
);
4678 pOld
= pLn
->GetFrmFmt();
4680 pLn
->ChgFrmFmt( (SwTableLineFmt
*)&rFmt
);
4682 if( pOld
&& pOld
->IsLastDepend() )
4684 RemoveFormat( *pOld
);
4689 void SwShareBoxFmts::SetSize( SwTableBox
& rBox
, const SwFmtFrmSize
& rSz
)
4691 SwFrmFmt
*pBoxFmt
= rBox
.GetFrmFmt(),
4692 *pRet
= GetFormat( *pBoxFmt
, rSz
.GetWidth() );
4694 ChangeFrmFmt( &rBox
, 0, *pRet
);
4697 pRet
= rBox
.ClaimFrmFmt();
4698 pRet
->SetFmtAttr( rSz
);
4699 AddFormat( *pBoxFmt
, *pRet
);
4703 void SwShareBoxFmts::SetAttr( SwTableBox
& rBox
, const SfxPoolItem
& rItem
)
4705 SwFrmFmt
*pBoxFmt
= rBox
.GetFrmFmt(),
4706 *pRet
= GetFormat( *pBoxFmt
, rItem
);
4708 ChangeFrmFmt( &rBox
, 0, *pRet
);
4711 pRet
= rBox
.ClaimFrmFmt();
4712 pRet
->SetFmtAttr( rItem
);
4713 AddFormat( *pBoxFmt
, *pRet
);
4717 void SwShareBoxFmts::SetAttr( SwTableLine
& rLine
, const SfxPoolItem
& rItem
)
4719 SwFrmFmt
*pLineFmt
= rLine
.GetFrmFmt(),
4720 *pRet
= GetFormat( *pLineFmt
, rItem
);
4722 ChangeFrmFmt( 0, &rLine
, *pRet
);
4725 pRet
= rLine
.ClaimFrmFmt();
4726 pRet
->SetFmtAttr( rItem
);
4727 AddFormat( *pLineFmt
, *pRet
);
4731 void SwShareBoxFmts::RemoveFormat( const SwFrmFmt
& rFmt
)
4733 for( USHORT i
= aShareArr
.Count(); i
; )
4734 if( aShareArr
[ --i
]->RemoveFormat( rFmt
))
4735 aShareArr
.DeleteAndDestroy( i
);
4738 BOOL
SwShareBoxFmts::Seek_Entry( const SwFrmFmt
& rFmt
, USHORT
* pPos
) const
4740 ULONG nIdx
= (ULONG
)&rFmt
;
4741 USHORT nO
= aShareArr
.Count(), nM
, nU
= 0;
4747 nM
= nU
+ ( nO
- nU
) / 2;
4748 ULONG nFmt
= (ULONG
)&aShareArr
[ nM
]->GetOldFormat();
4755 else if( nFmt
< nIdx
)