xref: /AOO41X/main/sw/source/core/docnode/ndtbl1.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "hintids.hxx"
28cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
29cdf0e10cSrcweir #include <editeng/boxitem.hxx>
30cdf0e10cSrcweir #include <editeng/brshitem.hxx>
31cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
32cdf0e10cSrcweir #include <fmtornt.hxx>
33cdf0e10cSrcweir #include <fmtfsize.hxx>
34cdf0e10cSrcweir #include <fmtlsplt.hxx>
35cdf0e10cSrcweir #include <fmtrowsplt.hxx>
36cdf0e10cSrcweir #include <tabcol.hxx>
37cdf0e10cSrcweir #include <frmatr.hxx>
38cdf0e10cSrcweir #include <cellfrm.hxx>
39cdf0e10cSrcweir #include <tabfrm.hxx>
40cdf0e10cSrcweir #include <cntfrm.hxx>
41cdf0e10cSrcweir #include <txtfrm.hxx>
42cdf0e10cSrcweir #include <svx/svxids.hrc>
43cdf0e10cSrcweir #include <doc.hxx>
44cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
45cdf0e10cSrcweir #include "pam.hxx"
46cdf0e10cSrcweir #include "swcrsr.hxx"
47cdf0e10cSrcweir #include "viscrs.hxx"
48cdf0e10cSrcweir #include "swtable.hxx"
49cdf0e10cSrcweir #include "htmltbl.hxx"
50cdf0e10cSrcweir #include "tblsel.hxx"
51cdf0e10cSrcweir #include "swtblfmt.hxx"
52cdf0e10cSrcweir #include "docary.hxx"
53cdf0e10cSrcweir #include "ndindex.hxx"
54cdf0e10cSrcweir #include "undobj.hxx"
55cdf0e10cSrcweir #include "switerator.hxx"
56cdf0e10cSrcweir #include <UndoTable.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir using namespace ::com::sun::star;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 
61cdf0e10cSrcweir extern void ClearFEShellTabCols();
62cdf0e10cSrcweir 
63cdf0e10cSrcweir //siehe auch swtable.cxx
64cdf0e10cSrcweir #define COLFUZZY 20L
65cdf0e10cSrcweir 
IsSame(long nA,long nB)66cdf0e10cSrcweir inline sal_Bool IsSame( long nA, long nB ) { return  Abs(nA-nB) <= COLFUZZY; }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir class SwTblFmtCmp
69cdf0e10cSrcweir {
70cdf0e10cSrcweir public:
71cdf0e10cSrcweir 	SwFrmFmt *pOld,
72cdf0e10cSrcweir 			 *pNew;
73cdf0e10cSrcweir 	sal_Int16     nType;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	SwTblFmtCmp( SwFrmFmt *pOld, SwFrmFmt *pNew, sal_Int16 nType );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 	static SwFrmFmt *FindNewFmt( SvPtrarr &rArr, SwFrmFmt*pOld, sal_Int16 nType );
78cdf0e10cSrcweir 	static void Delete( SvPtrarr &rArr );
79cdf0e10cSrcweir };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 
SwTblFmtCmp(SwFrmFmt * pO,SwFrmFmt * pN,sal_Int16 nT)82cdf0e10cSrcweir SwTblFmtCmp::SwTblFmtCmp( SwFrmFmt *pO, SwFrmFmt *pN, sal_Int16 nT )
83cdf0e10cSrcweir 	: pOld ( pO ), pNew ( pN ), nType( nT )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
FindNewFmt(SvPtrarr & rArr,SwFrmFmt * pOld,sal_Int16 nType)87cdf0e10cSrcweir SwFrmFmt *SwTblFmtCmp::FindNewFmt( SvPtrarr &rArr, SwFrmFmt *pOld, sal_Int16 nType )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
90cdf0e10cSrcweir 	{
91cdf0e10cSrcweir 		SwTblFmtCmp *pCmp = (SwTblFmtCmp*)rArr[i];
92cdf0e10cSrcweir 		if ( pCmp->pOld == pOld && pCmp->nType == nType )
93cdf0e10cSrcweir 			return pCmp->pNew;
94cdf0e10cSrcweir 	}
95cdf0e10cSrcweir 	return 0;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
Delete(SvPtrarr & rArr)98cdf0e10cSrcweir void SwTblFmtCmp::Delete( SvPtrarr &rArr )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
101cdf0e10cSrcweir 		delete (SwTblFmtCmp*)rArr[i];
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
lcl_GetStartEndCell(const SwCursor & rCrsr,SwLayoutFrm * & prStart,SwLayoutFrm * & prEnd)104cdf0e10cSrcweir void lcl_GetStartEndCell( const SwCursor& rCrsr,
105cdf0e10cSrcweir 						SwLayoutFrm *&prStart, SwLayoutFrm *&prEnd )
106cdf0e10cSrcweir {
107cdf0e10cSrcweir 	ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( sal_False ),
108cdf0e10cSrcweir 			"Tabselection nicht auf Cnt." );
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 	Point aPtPos, aMkPos;
111cdf0e10cSrcweir     const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
112cdf0e10cSrcweir 	if( pShCrsr )
113cdf0e10cSrcweir 	{
114cdf0e10cSrcweir 		aPtPos = pShCrsr->GetPtPos();
115cdf0e10cSrcweir 		aMkPos = pShCrsr->GetMkPos();
116cdf0e10cSrcweir 	}
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     // robust:
119cdf0e10cSrcweir     SwCntntNode* pPointNd = rCrsr.GetCntntNode();
120cdf0e10cSrcweir     SwCntntNode* pMarkNd  = rCrsr.GetCntntNode(sal_False);
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     SwFrm* pPointFrm = pPointNd ? pPointNd->getLayoutFrm( pPointNd->GetDoc()->GetCurrentLayout(), &aPtPos ) : 0;
123cdf0e10cSrcweir     SwFrm* pMarkFrm  = pMarkNd  ? pMarkNd->getLayoutFrm( pMarkNd->GetDoc()->GetCurrentLayout(), &aMkPos )  : 0;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     prStart = pPointFrm ? pPointFrm->GetUpper() : 0;
126cdf0e10cSrcweir     prEnd   = pMarkFrm  ? pMarkFrm->GetUpper() : 0;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
lcl_GetBoxSel(const SwCursor & rCursor,SwSelBoxes & rBoxes,sal_Bool bAllCrsr=sal_False)129cdf0e10cSrcweir sal_Bool lcl_GetBoxSel( const SwCursor& rCursor, SwSelBoxes& rBoxes,
130cdf0e10cSrcweir 					sal_Bool bAllCrsr = sal_False )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     const SwTableCursor* pTblCrsr =
133cdf0e10cSrcweir         dynamic_cast<const SwTableCursor*>(&rCursor);
134cdf0e10cSrcweir 	if( pTblCrsr )
135cdf0e10cSrcweir 		::GetTblSelCrs( *pTblCrsr, rBoxes );
136cdf0e10cSrcweir 	else
137cdf0e10cSrcweir 	{
138cdf0e10cSrcweir 		const SwPaM *pCurPam = &rCursor, *pSttPam = pCurPam;
139cdf0e10cSrcweir 		do {
140cdf0e10cSrcweir 			const SwNode* pNd = pCurPam->GetNode()->FindTableBoxStartNode();
141cdf0e10cSrcweir 			if( pNd )
142cdf0e10cSrcweir 			{
143cdf0e10cSrcweir 				SwTableBox* pBox = (SwTableBox*)pNd->FindTableNode()->GetTable().
144cdf0e10cSrcweir 											GetTblBox( pNd->GetIndex() );
145cdf0e10cSrcweir 				rBoxes.Insert( pBox );
146cdf0e10cSrcweir 			}
147cdf0e10cSrcweir 		} while( bAllCrsr &&
148cdf0e10cSrcweir 				pSttPam != ( pCurPam = (SwPaM*)pCurPam->GetNext()) );
149cdf0e10cSrcweir 	}
150cdf0e10cSrcweir 	return 0 != rBoxes.Count();
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir /***********************************************************************
154cdf0e10cSrcweir #*	Class	   :  SwDoc
155cdf0e10cSrcweir #*	Methoden   :  SetRowHeight(), GetRowHeight()
156cdf0e10cSrcweir #*	Datum	   :  MA 17. May. 93
157cdf0e10cSrcweir #*	Update	   :  JP 28.04.98
158cdf0e10cSrcweir #***********************************************************************/
159cdf0e10cSrcweir //Die Zeilenhoehe wird ausgehend von der Selektion ermittelt/gesetzt.
160cdf0e10cSrcweir //Ausgehend von jeder Zelle innerhalb der Selektion werden nach oben alle
161cdf0e10cSrcweir //Zeilen abgeklappert, die oberste Zeile erhaelt den gewuenschten Wert alle
162cdf0e10cSrcweir //tieferliegenden Zeilen einen entsprechenden Wert der sich aus der
163cdf0e10cSrcweir //Relation der alten und neuen Groesse der obersten Zeile und ihrer
164cdf0e10cSrcweir //eigenen Groesse ergiebt.
165cdf0e10cSrcweir //Alle veraenderten Zeilen erhalten ggf. ein eigenes FrmFmt.
166cdf0e10cSrcweir //Natuerlich darf jede Zeile nur einmal angefasst werden.
167cdf0e10cSrcweir 
InsertLine(SvPtrarr & rLineArr,SwTableLine * pLine)168cdf0e10cSrcweir inline void InsertLine( SvPtrarr& rLineArr, SwTableLine* pLine )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir 	if( USHRT_MAX == rLineArr.GetPos( pLine ) )
171cdf0e10cSrcweir 		rLineArr.Insert( pLine, rLineArr.Count() );
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir //-----------------------------------------------------------------------------
175cdf0e10cSrcweir 
lcl_IsAnLower(const SwTableLine * pLine,const SwTableLine * pAssumed)176cdf0e10cSrcweir sal_Bool lcl_IsAnLower( const SwTableLine *pLine, const SwTableLine *pAssumed )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir 	const SwTableLine *pTmp = pAssumed->GetUpper() ?
179cdf0e10cSrcweir 									pAssumed->GetUpper()->GetUpper() : 0;
180cdf0e10cSrcweir 	while ( pTmp )
181cdf0e10cSrcweir 	{
182cdf0e10cSrcweir 		if ( pTmp == pLine )
183cdf0e10cSrcweir 			return sal_True;
184cdf0e10cSrcweir 		pTmp = pTmp->GetUpper() ? pTmp->GetUpper()->GetUpper() : 0;
185cdf0e10cSrcweir 	}
186cdf0e10cSrcweir 	return sal_False;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir //-----------------------------------------------------------------------------
189cdf0e10cSrcweir 
190cdf0e10cSrcweir struct LinesAndTable
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 		  SvPtrarr &rLines;
193cdf0e10cSrcweir 	const SwTable  &rTable;
194cdf0e10cSrcweir 		  sal_Bool		bInsertLines;
195cdf0e10cSrcweir 
LinesAndTableLinesAndTable196cdf0e10cSrcweir 	LinesAndTable( SvPtrarr &rL, const SwTable &rTbl ) :
197cdf0e10cSrcweir 		  rLines( rL ), rTable( rTbl ), bInsertLines( sal_True ) {}
198cdf0e10cSrcweir };
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 
201cdf0e10cSrcweir sal_Bool _FindLine( const _FndLine*& rpLine, void* pPara );
202cdf0e10cSrcweir 
_FindBox(const _FndBox * & rpBox,void * pPara)203cdf0e10cSrcweir sal_Bool _FindBox( const _FndBox*& rpBox, void* pPara )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir 	if ( rpBox->GetLines().Count() )
206cdf0e10cSrcweir 	{
207cdf0e10cSrcweir 		((LinesAndTable*)pPara)->bInsertLines = sal_True;
208cdf0e10cSrcweir 		((_FndBox*)rpBox)->GetLines().ForEach( _FindLine, pPara );
209cdf0e10cSrcweir 		if ( ((LinesAndTable*)pPara)->bInsertLines )
210cdf0e10cSrcweir 		{
211cdf0e10cSrcweir 			const SwTableLines &rLines = rpBox->GetBox()
212cdf0e10cSrcweir 									? rpBox->GetBox()->GetTabLines()
213cdf0e10cSrcweir 									: ((LinesAndTable*)pPara)->rTable.GetTabLines();
214cdf0e10cSrcweir 			if ( rpBox->GetLines().Count() == rLines.Count() )
215cdf0e10cSrcweir 			{
216cdf0e10cSrcweir 				for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
217cdf0e10cSrcweir 					::InsertLine( ((LinesAndTable*)pPara)->rLines,
218cdf0e10cSrcweir 								  (SwTableLine*)rLines[i] );
219cdf0e10cSrcweir 			}
220cdf0e10cSrcweir 			else
221cdf0e10cSrcweir 				((LinesAndTable*)pPara)->bInsertLines = sal_False;
222cdf0e10cSrcweir 		}
223cdf0e10cSrcweir 	}
224cdf0e10cSrcweir 	else if ( rpBox->GetBox() )
225cdf0e10cSrcweir 		::InsertLine( ((LinesAndTable*)pPara)->rLines,
226cdf0e10cSrcweir 					  (SwTableLine*)rpBox->GetBox()->GetUpper() );
227cdf0e10cSrcweir 	return sal_True;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
_FindLine(const _FndLine * & rpLine,void * pPara)230cdf0e10cSrcweir sal_Bool _FindLine( const _FndLine*& rpLine, void* pPara )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	((_FndLine*)rpLine)->GetBoxes().ForEach( _FindBox, pPara );
233cdf0e10cSrcweir 	return sal_True;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
lcl_CollectLines(SvPtrarr & rArr,const SwCursor & rCursor,bool bRemoveLines)236cdf0e10cSrcweir void lcl_CollectLines( SvPtrarr &rArr, const SwCursor& rCursor, bool bRemoveLines )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir 	//Zuerst die selektierten Boxen einsammeln.
239cdf0e10cSrcweir 	SwSelBoxes aBoxes;
240cdf0e10cSrcweir 	if( !::lcl_GetBoxSel( rCursor, aBoxes ))
241cdf0e10cSrcweir 		return ;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 	//Die selektierte Struktur kopieren.
244cdf0e10cSrcweir 	const SwTable &rTable = aBoxes[0]->GetSttNd()->FindTableNode()->GetTable();
245cdf0e10cSrcweir 	LinesAndTable aPara( rArr, rTable );
246cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
247cdf0e10cSrcweir 	{
248cdf0e10cSrcweir 		_FndPara aTmpPara( aBoxes, &aFndBox );
249cdf0e10cSrcweir 		((SwTableLines&)rTable.GetTabLines()).ForEach( &_FndLineCopyCol, &aTmpPara );
250cdf0e10cSrcweir 	}
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	//Diejenigen Lines einsammeln, die nur selektierte Boxen enthalten.
253cdf0e10cSrcweir 	const _FndBox *pTmp = &aFndBox;
254cdf0e10cSrcweir 	::_FindBox( pTmp, &aPara );
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     // Remove lines, that have a common superordinate row.
257cdf0e10cSrcweir     // (Not for row split)
258cdf0e10cSrcweir     if ( bRemoveLines )
259cdf0e10cSrcweir     {
260cdf0e10cSrcweir     	for ( sal_uInt16 i = 0; i < rArr.Count(); ++i )
261cdf0e10cSrcweir 	    {
262cdf0e10cSrcweir 		    SwTableLine *pUpLine = (SwTableLine*)rArr[i];
263cdf0e10cSrcweir 		    for ( sal_uInt16 k = 0; k < rArr.Count(); ++k )
264cdf0e10cSrcweir 		    {
265cdf0e10cSrcweir     			if ( k != i && ::lcl_IsAnLower( pUpLine, (SwTableLine*)rArr[k] ) )
266cdf0e10cSrcweir 			    {
267cdf0e10cSrcweir     				rArr.Remove( k );
268cdf0e10cSrcweir 				    if ( k <= i )
269cdf0e10cSrcweir     					--i;
270cdf0e10cSrcweir 				    --k;
271cdf0e10cSrcweir 			    }
272cdf0e10cSrcweir 		    }
273cdf0e10cSrcweir 	    }
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir //-----------------------------------------------------------------------------
278cdf0e10cSrcweir 
lcl_ProcessRowAttr(SvPtrarr & rFmtCmp,SwTableLine * pLine,const SfxPoolItem & rNew)279cdf0e10cSrcweir void lcl_ProcessRowAttr( SvPtrarr& rFmtCmp, SwTableLine* pLine, const SfxPoolItem& rNew )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     SwFrmFmt *pNewFmt;
282cdf0e10cSrcweir     if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( rFmtCmp, pLine->GetFrmFmt(), 0 )))
283cdf0e10cSrcweir         pLine->ChgFrmFmt( (SwTableLineFmt*)pNewFmt );
284cdf0e10cSrcweir     else
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         SwFrmFmt *pOld = pLine->GetFrmFmt();
287cdf0e10cSrcweir         SwFrmFmt *pNew = pLine->ClaimFrmFmt();
288cdf0e10cSrcweir         pNew->SetFmtAttr( rNew );
289cdf0e10cSrcweir         rFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), rFmtCmp.Count());
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //-----------------------------------------------------------------------------
294cdf0e10cSrcweir 
295cdf0e10cSrcweir void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew );
296cdf0e10cSrcweir 
lcl_ProcessRowSize(SvPtrarr & rFmtCmp,SwTableLine * pLine,const SwFmtFrmSize & rNew)297cdf0e10cSrcweir void lcl_ProcessRowSize( SvPtrarr &rFmtCmp, SwTableLine *pLine, const SwFmtFrmSize &rNew )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir     lcl_ProcessRowAttr( rFmtCmp, pLine, rNew );
300cdf0e10cSrcweir     SwTableBoxes &rBoxes = pLine->GetTabBoxes();
301cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
302cdf0e10cSrcweir 		::lcl_ProcessBoxSize( rFmtCmp, rBoxes[i], rNew );
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir //-----------------------------------------------------------------------------
306cdf0e10cSrcweir 
lcl_ProcessBoxSize(SvPtrarr & rFmtCmp,SwTableBox * pBox,const SwFmtFrmSize & rNew)307cdf0e10cSrcweir void lcl_ProcessBoxSize( SvPtrarr &rFmtCmp, SwTableBox *pBox, const SwFmtFrmSize &rNew )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir 	SwTableLines &rLines = pBox->GetTabLines();
310cdf0e10cSrcweir 	if ( rLines.Count() )
311cdf0e10cSrcweir 	{
312cdf0e10cSrcweir 		SwFmtFrmSize aSz( rNew );
313cdf0e10cSrcweir 		aSz.SetHeight( rNew.GetHeight() ? rNew.GetHeight() / rLines.Count() : 0 );
314cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < rLines.Count(); ++i )
315cdf0e10cSrcweir 			::lcl_ProcessRowSize( rFmtCmp, rLines[i], aSz );
316cdf0e10cSrcweir 	}
317cdf0e10cSrcweir }
318cdf0e10cSrcweir 
319cdf0e10cSrcweir //-----------------------------------------------------------------------------
320cdf0e10cSrcweir 
321cdf0e10cSrcweir /******************************************************************************
322cdf0e10cSrcweir  *              void SwDoc::SetRowSplit()
323cdf0e10cSrcweir  ******************************************************************************/
SetRowSplit(const SwCursor & rCursor,const SwFmtRowSplit & rNew)324cdf0e10cSrcweir void SwDoc::SetRowSplit( const SwCursor& rCursor, const SwFmtRowSplit &rNew )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
327cdf0e10cSrcweir     if( pTblNd )
328cdf0e10cSrcweir     {
329cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln Lines.
330cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, false );
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         if( aRowArr.Count() )
333cdf0e10cSrcweir         {
334cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
337cdf0e10cSrcweir             }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 			SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 			for( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
342cdf0e10cSrcweir 				::lcl_ProcessRowAttr( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
343cdf0e10cSrcweir 
344cdf0e10cSrcweir             SwTblFmtCmp::Delete( aFmtCmp );
345cdf0e10cSrcweir             SetModified();
346cdf0e10cSrcweir         }
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 
351cdf0e10cSrcweir /******************************************************************************
352cdf0e10cSrcweir  *               SwTwips SwDoc::GetRowSplit() const
353cdf0e10cSrcweir  ******************************************************************************/
GetRowSplit(const SwCursor & rCursor,SwFmtRowSplit * & rpSz) const354cdf0e10cSrcweir void SwDoc::GetRowSplit( const SwCursor& rCursor, SwFmtRowSplit *& rpSz ) const
355cdf0e10cSrcweir {
356cdf0e10cSrcweir     rpSz = 0;
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
359cdf0e10cSrcweir     if( pTblNd )
360cdf0e10cSrcweir     {
361cdf0e10cSrcweir         SvPtrarr aRowArr( 25, 50 ); //Zum sammeln der Lines.
362cdf0e10cSrcweir         ::lcl_CollectLines( aRowArr, rCursor, false );
363cdf0e10cSrcweir 
364cdf0e10cSrcweir         if( aRowArr.Count() )
365cdf0e10cSrcweir         {
366cdf0e10cSrcweir             rpSz = &(SwFmtRowSplit&)((SwTableLine*)aRowArr[0])->
367cdf0e10cSrcweir                                                 GetFrmFmt()->GetRowSplit();
368cdf0e10cSrcweir 
369cdf0e10cSrcweir             for ( sal_uInt16 i = 1; i < aRowArr.Count() && rpSz; ++i )
370cdf0e10cSrcweir             {
371cdf0e10cSrcweir                 if ( (*rpSz).GetValue() != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetRowSplit().GetValue() )
372cdf0e10cSrcweir                     rpSz = 0;
373cdf0e10cSrcweir             }
374cdf0e10cSrcweir             if ( rpSz )
375cdf0e10cSrcweir                 rpSz = new SwFmtRowSplit( *rpSz );
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 
381cdf0e10cSrcweir /******************************************************************************
382cdf0e10cSrcweir  *				void SwDoc::SetRowHeight( SwTwips nNew )
383cdf0e10cSrcweir  ******************************************************************************/
SetRowHeight(const SwCursor & rCursor,const SwFmtFrmSize & rNew)384cdf0e10cSrcweir void SwDoc::SetRowHeight( const SwCursor& rCursor, const SwFmtFrmSize &rNew )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
387cdf0e10cSrcweir 	if( pTblNd )
388cdf0e10cSrcweir 	{
389cdf0e10cSrcweir 		SvPtrarr aRowArr( 25, 50 );	//Zum sammeln Lines.
390cdf0e10cSrcweir 		::lcl_CollectLines( aRowArr, rCursor, true );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 		if( aRowArr.Count() )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
397cdf0e10cSrcweir             }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 			SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
400cdf0e10cSrcweir 			for ( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
401cdf0e10cSrcweir 				::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
402cdf0e10cSrcweir 			SwTblFmtCmp::Delete( aFmtCmp );
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 			SetModified();
405cdf0e10cSrcweir 		}
406cdf0e10cSrcweir 	}
407cdf0e10cSrcweir }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir /******************************************************************************
411cdf0e10cSrcweir  *				 SwTwips SwDoc::GetRowHeight() const
412cdf0e10cSrcweir  ******************************************************************************/
GetRowHeight(const SwCursor & rCursor,SwFmtFrmSize * & rpSz) const413cdf0e10cSrcweir void SwDoc::GetRowHeight( const SwCursor& rCursor, SwFmtFrmSize *& rpSz ) const
414cdf0e10cSrcweir {
415cdf0e10cSrcweir 	rpSz = 0;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
418cdf0e10cSrcweir 	if( pTblNd )
419cdf0e10cSrcweir 	{
420cdf0e10cSrcweir 		SvPtrarr aRowArr( 25, 50 );	//Zum sammeln der Lines.
421cdf0e10cSrcweir 		::lcl_CollectLines( aRowArr, rCursor, true );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 		if( aRowArr.Count() )
424cdf0e10cSrcweir 		{
425cdf0e10cSrcweir 			rpSz = &(SwFmtFrmSize&)((SwTableLine*)aRowArr[0])->
426cdf0e10cSrcweir 												GetFrmFmt()->GetFrmSize();
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 			for ( sal_uInt16 i = 1; i < aRowArr.Count() && rpSz; ++i )
429cdf0e10cSrcweir 			{
430cdf0e10cSrcweir 				if ( *rpSz != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetFrmSize() )
431cdf0e10cSrcweir 					rpSz = 0;
432cdf0e10cSrcweir 			}
433cdf0e10cSrcweir 			if ( rpSz )
434cdf0e10cSrcweir 				rpSz = new SwFmtFrmSize( *rpSz );
435cdf0e10cSrcweir 		}
436cdf0e10cSrcweir 	}
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
BalanceRowHeight(const SwCursor & rCursor,sal_Bool bTstOnly)439cdf0e10cSrcweir sal_Bool SwDoc::BalanceRowHeight( const SwCursor& rCursor, sal_Bool bTstOnly )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
442cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
443cdf0e10cSrcweir 	if( pTblNd )
444cdf0e10cSrcweir 	{
445cdf0e10cSrcweir 		SvPtrarr aRowArr( 25, 50 );	//Zum sammeln der Lines.
446cdf0e10cSrcweir 		::lcl_CollectLines( aRowArr, rCursor, true );
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 		if( 1 < aRowArr.Count() )
449cdf0e10cSrcweir 		{
450cdf0e10cSrcweir 			if( !bTstOnly )
451cdf0e10cSrcweir 			{
452cdf0e10cSrcweir 				long nHeight = 0;
453cdf0e10cSrcweir 				sal_uInt16 i;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 				for ( i = 0; i < aRowArr.Count(); ++i )
456cdf0e10cSrcweir 				{
457cdf0e10cSrcweir 					SwIterator<SwFrm,SwFmt> aIter( *((SwTableLine*)aRowArr[i])->GetFrmFmt() );
458cdf0e10cSrcweir 					SwFrm* pFrm = aIter.First();
459cdf0e10cSrcweir 					while ( pFrm )
460cdf0e10cSrcweir 					{
461cdf0e10cSrcweir 						nHeight = Max( nHeight, pFrm->Frm().Height() );
462cdf0e10cSrcweir 						pFrm = aIter.Next();
463cdf0e10cSrcweir 					}
464cdf0e10cSrcweir 				}
465cdf0e10cSrcweir 				SwFmtFrmSize aNew( ATT_MIN_SIZE, 0, nHeight );
466cdf0e10cSrcweir 
467cdf0e10cSrcweir                 if (GetIDocumentUndoRedo().DoesUndo())
468cdf0e10cSrcweir                 {
469cdf0e10cSrcweir                     GetIDocumentUndoRedo().AppendUndo(
470cdf0e10cSrcweir                             new SwUndoAttrTbl(*pTblNd));
471cdf0e10cSrcweir                 }
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 				SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
474cdf0e10cSrcweir 				for( i = 0; i < aRowArr.Count(); ++i )
475cdf0e10cSrcweir 					::lcl_ProcessRowSize( aFmtCmp, (SwTableLine*)aRowArr[i], aNew );
476cdf0e10cSrcweir 				SwTblFmtCmp::Delete( aFmtCmp );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 				SetModified();
479cdf0e10cSrcweir 			}
480cdf0e10cSrcweir 			bRet = sal_True;
481cdf0e10cSrcweir 		}
482cdf0e10cSrcweir 	}
483cdf0e10cSrcweir 	return bRet;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir /******************************************************************************
487cdf0e10cSrcweir  *				void SwDoc::SetRowBackground()
488cdf0e10cSrcweir  ******************************************************************************/
SetRowBackground(const SwCursor & rCursor,const SvxBrushItem & rNew)489cdf0e10cSrcweir void SwDoc::SetRowBackground( const SwCursor& rCursor, const SvxBrushItem &rNew )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
492cdf0e10cSrcweir 	if( pTblNd )
493cdf0e10cSrcweir 	{
494cdf0e10cSrcweir 		SvPtrarr aRowArr( 25, 50 );	//Zum sammeln Lines.
495cdf0e10cSrcweir 		::lcl_CollectLines( aRowArr, rCursor, true );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 		if( aRowArr.Count() )
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
500cdf0e10cSrcweir             {
501cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 			SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aRowArr.Count()) ), 255 );
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 			for( sal_uInt16 i = 0; i < aRowArr.Count(); ++i )
507cdf0e10cSrcweir                 ::lcl_ProcessRowAttr( aFmtCmp, (SwTableLine*)aRowArr[i], rNew );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 			SwTblFmtCmp::Delete( aFmtCmp );
510cdf0e10cSrcweir 			SetModified();
511cdf0e10cSrcweir 		}
512cdf0e10cSrcweir 	}
513cdf0e10cSrcweir }
514cdf0e10cSrcweir 
515cdf0e10cSrcweir /******************************************************************************
516cdf0e10cSrcweir  *				 SwTwips SwDoc::GetRowBackground() const
517cdf0e10cSrcweir  ******************************************************************************/
GetRowBackground(const SwCursor & rCursor,SvxBrushItem & rToFill) const518cdf0e10cSrcweir sal_Bool SwDoc::GetRowBackground( const SwCursor& rCursor, SvxBrushItem &rToFill ) const
519cdf0e10cSrcweir {
520cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
521cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
522cdf0e10cSrcweir 	if( pTblNd )
523cdf0e10cSrcweir 	{
524cdf0e10cSrcweir 		SvPtrarr aRowArr( 25, 50 );	//Zum sammeln Lines.
525cdf0e10cSrcweir 		::lcl_CollectLines( aRowArr, rCursor, true );
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 		if( aRowArr.Count() )
528cdf0e10cSrcweir 		{
529cdf0e10cSrcweir 			rToFill = ((SwTableLine*)aRowArr[0])->GetFrmFmt()->GetBackground();
530cdf0e10cSrcweir 
531cdf0e10cSrcweir 			bRet = sal_True;
532cdf0e10cSrcweir 			for ( sal_uInt16 i = 1; i < aRowArr.Count(); ++i )
533cdf0e10cSrcweir 				if ( rToFill != ((SwTableLine*)aRowArr[i])->GetFrmFmt()->GetBackground() )
534cdf0e10cSrcweir 				{
535cdf0e10cSrcweir 					bRet = sal_False;
536cdf0e10cSrcweir 					break;
537cdf0e10cSrcweir 				}
538cdf0e10cSrcweir 		}
539cdf0e10cSrcweir 	}
540cdf0e10cSrcweir 	return bRet;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir /***********************************************************************
544cdf0e10cSrcweir #*	Class	   :  SwDoc
545cdf0e10cSrcweir #*	Methoden   :  SetTabBorders(), GetTabBorders()
546cdf0e10cSrcweir #*	Datum	   :  MA 18. May. 93
547cdf0e10cSrcweir #*	Update	   :  JP 29.04.98
548cdf0e10cSrcweir #***********************************************************************/
InsertCell(SvPtrarr & rCellArr,SwCellFrm * pCellFrm)549cdf0e10cSrcweir inline void InsertCell( SvPtrarr& rCellArr, SwCellFrm* pCellFrm )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir 	if( USHRT_MAX == rCellArr.GetPos( pCellFrm ) )
552cdf0e10cSrcweir 		rCellArr.Insert( pCellFrm, rCellArr.Count() );
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir //-----------------------------------------------------------------------------
lcl_CollectCells(SvPtrarr & rArr,const SwRect & rUnion,SwTabFrm * pTab)556cdf0e10cSrcweir void lcl_CollectCells( SvPtrarr &rArr, const SwRect &rUnion,
557cdf0e10cSrcweir 						  SwTabFrm *pTab )
558cdf0e10cSrcweir {
559cdf0e10cSrcweir 	SwLayoutFrm *pCell = pTab->FirstCell();
560cdf0e10cSrcweir 	do
561cdf0e10cSrcweir 	{
562cdf0e10cSrcweir 		// Wenn in der Zelle ein spaltiger Bereich sitzt, muessen wir
563cdf0e10cSrcweir 		// uns erst wieder zur Zelle hochhangeln
564cdf0e10cSrcweir 		while ( !pCell->IsCellFrm() )
565cdf0e10cSrcweir 			pCell = pCell->GetUpper();
566cdf0e10cSrcweir 		ASSERT( pCell, "Frame ist keine Zelle." );
567cdf0e10cSrcweir 		if ( rUnion.IsOver( pCell->Frm() ) )
568cdf0e10cSrcweir 			::InsertCell( rArr, (SwCellFrm*)pCell );
569cdf0e10cSrcweir 		//Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
570cdf0e10cSrcweir 		SwLayoutFrm *pTmp = pCell;
571cdf0e10cSrcweir 		do
572cdf0e10cSrcweir 		{	pTmp = pTmp->GetNextLayoutLeaf();
573cdf0e10cSrcweir 		} while ( pCell->IsAnLower( pTmp ) );
574cdf0e10cSrcweir 		pCell = pTmp;
575cdf0e10cSrcweir 	} while( pCell && pTab->IsAnLower( pCell ) );
576cdf0e10cSrcweir }
577cdf0e10cSrcweir 
SetTabBorders(const SwCursor & rCursor,const SfxItemSet & rSet)578cdf0e10cSrcweir void SwDoc::SetTabBorders( const SwCursor& rCursor, const SfxItemSet& rSet )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir 	SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
581cdf0e10cSrcweir 	SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
582cdf0e10cSrcweir 	if( !pTblNd )
583cdf0e10cSrcweir 		return ;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 	SwLayoutFrm *pStart, *pEnd;
586cdf0e10cSrcweir 	::lcl_GetStartEndCell( rCursor, pStart, pEnd );
587cdf0e10cSrcweir 
588cdf0e10cSrcweir 	SwSelUnions aUnions;
589cdf0e10cSrcweir 	::MakeSelUnions( aUnions, pStart, pEnd );
590cdf0e10cSrcweir 
591cdf0e10cSrcweir 	if( aUnions.Count() )
592cdf0e10cSrcweir 	{
593cdf0e10cSrcweir 		SwTable& rTable = pTblNd->GetTable();
594cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( new SwUndoAttrTbl(*pTblNd) );
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 		SvPtrarr aFmtCmp( 255, 255 );
600cdf0e10cSrcweir 		const SvxBoxItem* pSetBox;
601cdf0e10cSrcweir 		const SvxBoxInfoItem *pSetBoxInfo;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 		const SvxBorderLine* pLeft = 0;
604cdf0e10cSrcweir 		const SvxBorderLine* pRight = 0;
605cdf0e10cSrcweir 		const SvxBorderLine* pTop = 0;
606cdf0e10cSrcweir 		const SvxBorderLine* pBottom = 0;
607cdf0e10cSrcweir 		const SvxBorderLine* pHori = 0;
608cdf0e10cSrcweir 		const SvxBorderLine* pVert = 0;
609cdf0e10cSrcweir 		sal_Bool bHoriValid = sal_True, bVertValid = sal_True,
610cdf0e10cSrcweir 			 bTopValid = sal_True, bBottomValid = sal_True,
611cdf0e10cSrcweir 			 bLeftValid = sal_True, bRightValid = sal_True;
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 		// JP 21.07.95: die Flags im BoxInfo-Item entscheiden, wann eine
614cdf0e10cSrcweir 		//				BorderLine gueltig ist!!
615cdf0e10cSrcweir 		if( SFX_ITEM_SET == rSet.GetItemState( SID_ATTR_BORDER_INNER, sal_False,
616cdf0e10cSrcweir 			(const SfxPoolItem**)&pSetBoxInfo) )
617cdf0e10cSrcweir 		{
618cdf0e10cSrcweir 			pHori = pSetBoxInfo->GetHori();
619cdf0e10cSrcweir 			pVert = pSetBoxInfo->GetVert();
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 			bHoriValid = pSetBoxInfo->IsValid(VALID_HORI);
622cdf0e10cSrcweir 			bVertValid = pSetBoxInfo->IsValid(VALID_VERT);
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 			// wollen wir die auswerten ??
625cdf0e10cSrcweir 			bTopValid = pSetBoxInfo->IsValid(VALID_TOP);
626cdf0e10cSrcweir 			bBottomValid = pSetBoxInfo->IsValid(VALID_BOTTOM);
627cdf0e10cSrcweir 			bLeftValid = pSetBoxInfo->IsValid(VALID_LEFT);
628cdf0e10cSrcweir 			bRightValid = pSetBoxInfo->IsValid(VALID_RIGHT);
629cdf0e10cSrcweir 		}
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 		if( SFX_ITEM_SET == rSet.GetItemState( RES_BOX, sal_False,
632cdf0e10cSrcweir 			(const SfxPoolItem**)&pSetBox) )
633cdf0e10cSrcweir 		{
634cdf0e10cSrcweir 			pLeft = pSetBox->GetLeft();
635cdf0e10cSrcweir 			pRight = pSetBox->GetRight();
636cdf0e10cSrcweir 			pTop = pSetBox->GetTop();
637cdf0e10cSrcweir 			pBottom = pSetBox->GetBottom();
638cdf0e10cSrcweir 		}
639cdf0e10cSrcweir 		else
640cdf0e10cSrcweir 		{
641cdf0e10cSrcweir 			// nicht gesetzt, also keine gueltigen Werte
642cdf0e10cSrcweir 			bTopValid = bBottomValid = bLeftValid = bRightValid = sal_False;
643cdf0e10cSrcweir 			pSetBox = 0;
644cdf0e10cSrcweir 		}
645cdf0e10cSrcweir 
646cdf0e10cSrcweir 		sal_Bool bFirst = sal_True;
647cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
648cdf0e10cSrcweir 		{
649cdf0e10cSrcweir 			SwSelUnion *pUnion = aUnions[i];
650cdf0e10cSrcweir 			SwTabFrm *pTab = pUnion->GetTable();
651cdf0e10cSrcweir 			const SwRect &rUnion = pUnion->GetUnion();
652cdf0e10cSrcweir 			const sal_Bool bLast  = i == aUnions.Count() - 1 ? sal_True : sal_False;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 			SvPtrarr aCellArr( 255, 255 );
655cdf0e10cSrcweir 			::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 			//Alle Zellenkanten, die mit dem UnionRect uebereinstimmen oder
658cdf0e10cSrcweir 			//darueber hinausragen sind Aussenkanten. Alle anderen sind
659cdf0e10cSrcweir 			//Innenkanten.
660cdf0e10cSrcweir 			//neu: Die Aussenkanten koennen abhaengig davon, ob es sich um eine
661cdf0e10cSrcweir 			//Start/Mittlere/Folge -Tabelle (bei Selektionen ueber FollowTabs)
662cdf0e10cSrcweir 			//handelt doch keine Aussenkanten sein.
663cdf0e10cSrcweir 			//Aussenkanten werden links, rechts, oben und unten gesetzt.
664cdf0e10cSrcweir 			//Innenkanten werden nur oben und links gesetzt.
665cdf0e10cSrcweir 			for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
666cdf0e10cSrcweir 			{
667cdf0e10cSrcweir 				SwCellFrm *pCell = (SwCellFrm*)aCellArr[j];
668cdf0e10cSrcweir                 const sal_Bool bVert = pTab->IsVertical();
669cdf0e10cSrcweir                 const sal_Bool bRTL = pTab->IsRightToLeft();
670cdf0e10cSrcweir                 sal_Bool bTopOver, bLeftOver, bRightOver, bBottomOver;
671cdf0e10cSrcweir                 if ( bVert )
672cdf0e10cSrcweir                 {
673cdf0e10cSrcweir                     bTopOver = pCell->Frm().Right() >= rUnion.Right();
674cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Top() <= rUnion.Top();
675cdf0e10cSrcweir                     bRightOver = pCell->Frm().Bottom() >= rUnion.Bottom();
676cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Left() <= rUnion.Left();
677cdf0e10cSrcweir                 }
678cdf0e10cSrcweir                 else
679cdf0e10cSrcweir                 {
680cdf0e10cSrcweir                     bTopOver = pCell->Frm().Top() <= rUnion.Top();
681cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Left() <= rUnion.Left();
682cdf0e10cSrcweir                     bRightOver = pCell->Frm().Right() >= rUnion.Right();
683cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Bottom() >= rUnion.Bottom();
684cdf0e10cSrcweir                 }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir                 if ( bRTL )
687cdf0e10cSrcweir                 {
688cdf0e10cSrcweir                     sal_Bool bTmp = bRightOver;
689cdf0e10cSrcweir                     bRightOver = bLeftOver;
690cdf0e10cSrcweir                     bLeftOver = bTmp;
691cdf0e10cSrcweir                 }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir                 //Grundsaetzlich nichts setzen in HeadlineRepeats.
694cdf0e10cSrcweir                 if ( pTab->IsFollow() &&
695cdf0e10cSrcweir                      ( pTab->IsInHeadline( *pCell ) ||
696cdf0e10cSrcweir                        // --> FME 2006-02-07 #126092# Same holds for follow flow rows.
697cdf0e10cSrcweir                        pCell->IsInFollowFlowRow() ) )
698cdf0e10cSrcweir                        // <--
699cdf0e10cSrcweir                     continue;
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 				SvxBoxItem aBox( pCell->GetFmt()->GetBox() );
702cdf0e10cSrcweir 
703cdf0e10cSrcweir 				sal_Int16 nType = 0;
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 				//Obere Kante
706cdf0e10cSrcweir 				if( bTopValid )
707cdf0e10cSrcweir 				{
708cdf0e10cSrcweir                     if ( bFirst && bTopOver )
709cdf0e10cSrcweir 					{
710cdf0e10cSrcweir 						aBox.SetLine( pTop, BOX_LINE_TOP );
711cdf0e10cSrcweir 						nType |= 0x0001;
712cdf0e10cSrcweir 					}
713cdf0e10cSrcweir 					else if ( bHoriValid )
714cdf0e10cSrcweir 					{
715cdf0e10cSrcweir 						aBox.SetLine( 0, BOX_LINE_TOP );
716cdf0e10cSrcweir 						nType |= 0x0002;
717cdf0e10cSrcweir 					}
718cdf0e10cSrcweir 				}
719cdf0e10cSrcweir 
720cdf0e10cSrcweir 				//Linke Kante
721cdf0e10cSrcweir                 if ( bLeftOver )
722cdf0e10cSrcweir 				{
723cdf0e10cSrcweir 					if( bLeftValid )
724cdf0e10cSrcweir 					{
725cdf0e10cSrcweir 						aBox.SetLine( pLeft, BOX_LINE_LEFT );
726cdf0e10cSrcweir 						nType |= 0x0004;
727cdf0e10cSrcweir 					}
728cdf0e10cSrcweir 				}
729cdf0e10cSrcweir 				else if( bVertValid )
730cdf0e10cSrcweir 				{
731cdf0e10cSrcweir 					aBox.SetLine( pVert, BOX_LINE_LEFT );
732cdf0e10cSrcweir 					nType |= 0x0008;
733cdf0e10cSrcweir 				}
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 				//Rechte Kante
736cdf0e10cSrcweir 				if( bRightValid )
737cdf0e10cSrcweir 				{
738cdf0e10cSrcweir                     if ( bRightOver )
739cdf0e10cSrcweir 					{
740cdf0e10cSrcweir 						aBox.SetLine( pRight, BOX_LINE_RIGHT );
741cdf0e10cSrcweir 						nType |= 0x0010;
742cdf0e10cSrcweir 					}
743cdf0e10cSrcweir 					else if ( bVertValid )
744cdf0e10cSrcweir 					{
745cdf0e10cSrcweir 						aBox.SetLine( 0, BOX_LINE_RIGHT );
746cdf0e10cSrcweir 						nType |= 0x0020;
747cdf0e10cSrcweir 					}
748cdf0e10cSrcweir 				}
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 				//Untere Kante
751cdf0e10cSrcweir                 if ( bLast && bBottomOver )
752cdf0e10cSrcweir 				{
753cdf0e10cSrcweir 					if( bBottomValid )
754cdf0e10cSrcweir 					{
755cdf0e10cSrcweir 						aBox.SetLine( pBottom, BOX_LINE_BOTTOM );
756cdf0e10cSrcweir 						nType |= 0x0040;
757cdf0e10cSrcweir 					}
758cdf0e10cSrcweir 				}
759cdf0e10cSrcweir 				else if( bHoriValid )
760cdf0e10cSrcweir 				{
761cdf0e10cSrcweir 					aBox.SetLine( pHori, BOX_LINE_BOTTOM );
762cdf0e10cSrcweir 					nType |= 0x0080;
763cdf0e10cSrcweir 				}
764cdf0e10cSrcweir 
765cdf0e10cSrcweir 				if( pSetBox )
766cdf0e10cSrcweir 				{
767cdf0e10cSrcweir 					static sal_uInt16 __READONLY_DATA aBorders[] = {
768cdf0e10cSrcweir 						BOX_LINE_BOTTOM, BOX_LINE_TOP,
769cdf0e10cSrcweir 						BOX_LINE_RIGHT, BOX_LINE_LEFT };
770cdf0e10cSrcweir 					const sal_uInt16* pBrd = aBorders;
771cdf0e10cSrcweir 					for( int k = 0; k < 4; ++k, ++pBrd )
772cdf0e10cSrcweir 						aBox.SetDistance( pSetBox->GetDistance( *pBrd ), *pBrd );
773cdf0e10cSrcweir 				}
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 				SwTableBox *pBox = (SwTableBox*)pCell->GetTabBox();
776cdf0e10cSrcweir 				SwFrmFmt *pNewFmt;
777cdf0e10cSrcweir 				if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), nType )))
778cdf0e10cSrcweir 					pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
779cdf0e10cSrcweir 				else
780cdf0e10cSrcweir 				{
781cdf0e10cSrcweir 					SwFrmFmt *pOld = pBox->GetFrmFmt();
782cdf0e10cSrcweir 					SwFrmFmt *pNew = pBox->ClaimFrmFmt();
783cdf0e10cSrcweir                     pNew->SetFmtAttr( aBox );
784cdf0e10cSrcweir 					aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, nType ), aFmtCmp.Count());
785cdf0e10cSrcweir 				}
786cdf0e10cSrcweir 			}
787cdf0e10cSrcweir 
788cdf0e10cSrcweir 			bFirst = sal_False;
789cdf0e10cSrcweir 		}
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 		SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
792cdf0e10cSrcweir 		if( pTableLayout )
793cdf0e10cSrcweir 		{
794cdf0e10cSrcweir 			SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
795cdf0e10cSrcweir 			SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
796cdf0e10cSrcweir 
797cdf0e10cSrcweir 			pTableLayout->BordersChanged(
798cdf0e10cSrcweir 				pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
799cdf0e10cSrcweir 		}
800cdf0e10cSrcweir 		SwTblFmtCmp::Delete( aFmtCmp );
801cdf0e10cSrcweir 		::ClearFEShellTabCols();
802cdf0e10cSrcweir 		SetModified();
803cdf0e10cSrcweir 	}
804cdf0e10cSrcweir }
805cdf0e10cSrcweir 
lcl_SetLineStyle(SvxBorderLine * pToSet,const Color * pColor,const SvxBorderLine * pBorderLine)806cdf0e10cSrcweir void lcl_SetLineStyle( SvxBorderLine *pToSet,
807cdf0e10cSrcweir 						  const Color *pColor, const SvxBorderLine *pBorderLine)
808cdf0e10cSrcweir {
809cdf0e10cSrcweir 	if ( pBorderLine )
810cdf0e10cSrcweir 	{
811cdf0e10cSrcweir 		if ( !pColor )
812cdf0e10cSrcweir 		{
813cdf0e10cSrcweir 			Color aTmp( pToSet->GetColor() );
814cdf0e10cSrcweir 			*pToSet = *pBorderLine;
815cdf0e10cSrcweir 			pToSet->SetColor( aTmp );
816cdf0e10cSrcweir 		}
817cdf0e10cSrcweir 		else
818cdf0e10cSrcweir 			*pToSet = *pBorderLine;
819cdf0e10cSrcweir 	}
820cdf0e10cSrcweir 	if ( pColor )
821cdf0e10cSrcweir 		pToSet->SetColor( *pColor );
822cdf0e10cSrcweir }
823cdf0e10cSrcweir 
SetTabLineStyle(const SwCursor & rCursor,const Color * pColor,sal_Bool bSetLine,const SvxBorderLine * pBorderLine)824cdf0e10cSrcweir void SwDoc::SetTabLineStyle( const SwCursor& rCursor,
825cdf0e10cSrcweir 							 const Color* pColor, sal_Bool bSetLine,
826cdf0e10cSrcweir 							 const SvxBorderLine* pBorderLine )
827cdf0e10cSrcweir {
828cdf0e10cSrcweir 	SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
829cdf0e10cSrcweir 	SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
830cdf0e10cSrcweir 	if( !pTblNd )
831cdf0e10cSrcweir 		return ;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir 	SwLayoutFrm *pStart, *pEnd;
834cdf0e10cSrcweir 	::lcl_GetStartEndCell( rCursor, pStart, pEnd );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir 	SwSelUnions aUnions;
837cdf0e10cSrcweir 	::MakeSelUnions( aUnions, pStart, pEnd );
838cdf0e10cSrcweir 
839cdf0e10cSrcweir 	if( aUnions.Count() )
840cdf0e10cSrcweir 	{
841cdf0e10cSrcweir 		SwTable& rTable = pTblNd->GetTable();
842cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
843cdf0e10cSrcweir         {
844cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(new SwUndoAttrTbl(*pTblNd));
845cdf0e10cSrcweir         }
846cdf0e10cSrcweir 
847cdf0e10cSrcweir 		for( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
848cdf0e10cSrcweir 		{
849cdf0e10cSrcweir 			SwSelUnion *pUnion = aUnions[i];
850cdf0e10cSrcweir 			SwTabFrm *pTab = pUnion->GetTable();
851cdf0e10cSrcweir 			SvPtrarr aCellArr( 255, 255 );
852cdf0e10cSrcweir 			::lcl_CollectCells( aCellArr, pUnion->GetUnion(), pTab );
853cdf0e10cSrcweir 
854cdf0e10cSrcweir 			for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
855cdf0e10cSrcweir 			{
856cdf0e10cSrcweir 				SwCellFrm *pCell = ( SwCellFrm* )aCellArr[j];
857cdf0e10cSrcweir 
858cdf0e10cSrcweir                 //Grundsaetzlich nichts setzen in HeadlineRepeats.
859cdf0e10cSrcweir                 if ( pTab->IsFollow() && pTab->IsInHeadline( *pCell ) )
860cdf0e10cSrcweir                     continue;
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 				((SwTableBox*)pCell->GetTabBox())->ClaimFrmFmt();
863cdf0e10cSrcweir 				SwFrmFmt *pFmt = pCell->GetFmt();
864cdf0e10cSrcweir 				SvxBoxItem aBox( pFmt->GetBox() );
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 				if ( !pBorderLine && bSetLine )
867cdf0e10cSrcweir 					aBox = *(SvxBoxItem*)::GetDfltAttr( RES_BOX );
868cdf0e10cSrcweir 				else
869cdf0e10cSrcweir 				{
870cdf0e10cSrcweir 					if ( aBox.GetTop() )
871cdf0e10cSrcweir 						::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetTop(),
872cdf0e10cSrcweir 										pColor, pBorderLine );
873cdf0e10cSrcweir 					if ( aBox.GetBottom() )
874cdf0e10cSrcweir 						::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetBottom(),
875cdf0e10cSrcweir 										pColor, pBorderLine );
876cdf0e10cSrcweir 					if ( aBox.GetLeft() )
877cdf0e10cSrcweir 						::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetLeft(),
878cdf0e10cSrcweir 										pColor, pBorderLine );
879cdf0e10cSrcweir 					if ( aBox.GetRight() )
880cdf0e10cSrcweir 						::lcl_SetLineStyle( (SvxBorderLine*)aBox.GetRight(),
881cdf0e10cSrcweir 										pColor, pBorderLine );
882cdf0e10cSrcweir 				}
883cdf0e10cSrcweir                 pFmt->SetFmtAttr( aBox );
884cdf0e10cSrcweir 			}
885cdf0e10cSrcweir 		}
886cdf0e10cSrcweir 
887cdf0e10cSrcweir 		SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
888cdf0e10cSrcweir 		if( pTableLayout )
889cdf0e10cSrcweir 		{
890cdf0e10cSrcweir 			SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
891cdf0e10cSrcweir 			SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
892cdf0e10cSrcweir 
893cdf0e10cSrcweir 			pTableLayout->BordersChanged(
894cdf0e10cSrcweir 				pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
895cdf0e10cSrcweir 		}
896cdf0e10cSrcweir 		::ClearFEShellTabCols();
897cdf0e10cSrcweir 		SetModified();
898cdf0e10cSrcweir 	}
899cdf0e10cSrcweir }
900cdf0e10cSrcweir 
GetTabBorders(const SwCursor & rCursor,SfxItemSet & rSet) const901cdf0e10cSrcweir void SwDoc::GetTabBorders( const SwCursor& rCursor, SfxItemSet& rSet ) const
902cdf0e10cSrcweir {
903cdf0e10cSrcweir 	SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
904cdf0e10cSrcweir 	SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
905cdf0e10cSrcweir 	if( !pTblNd )
906cdf0e10cSrcweir 		return ;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir 	SwLayoutFrm *pStart, *pEnd;
909cdf0e10cSrcweir 	::lcl_GetStartEndCell( rCursor, pStart, pEnd );
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 	SwSelUnions aUnions;
912cdf0e10cSrcweir 	::MakeSelUnions( aUnions, pStart, pEnd );
913cdf0e10cSrcweir 
914cdf0e10cSrcweir 	if( aUnions.Count() )
915cdf0e10cSrcweir 	{
916cdf0e10cSrcweir 		SvxBoxItem	   aSetBox	  ((const SvxBoxItem	&) rSet.Get(RES_BOX    ));
917cdf0e10cSrcweir 		SvxBoxInfoItem aSetBoxInfo((const SvxBoxInfoItem&) rSet.Get(SID_ATTR_BORDER_INNER));
918cdf0e10cSrcweir 
919cdf0e10cSrcweir 		sal_Bool bTopSet	  =	sal_False,
920cdf0e10cSrcweir 			 bBottomSet   =	sal_False,
921cdf0e10cSrcweir 			 bLeftSet	  =	sal_False,
922cdf0e10cSrcweir 			 bRightSet	  =	sal_False,
923cdf0e10cSrcweir 			 bHoriSet	  = sal_False,
924cdf0e10cSrcweir 			 bVertSet	  = sal_False,
925cdf0e10cSrcweir 			 bDistanceSet = sal_False;
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 		aSetBoxInfo.ResetFlags();
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
930cdf0e10cSrcweir 		{
931cdf0e10cSrcweir 			SwSelUnion *pUnion = aUnions[i];
932cdf0e10cSrcweir 			const SwTabFrm *pTab = pUnion->GetTable();
933cdf0e10cSrcweir 			const SwRect &rUnion = pUnion->GetUnion();
934cdf0e10cSrcweir 			const sal_Bool bFirst = i == 0 ? sal_True : sal_False;
935cdf0e10cSrcweir 			const sal_Bool bLast  = i == aUnions.Count() - 1 ? sal_True : sal_False;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir 			SvPtrarr aCellArr( 255, 255 );
938cdf0e10cSrcweir 			::lcl_CollectCells( aCellArr, rUnion, (SwTabFrm*)pTab );
939cdf0e10cSrcweir 
940cdf0e10cSrcweir 			for ( sal_uInt16 j = 0; j < aCellArr.Count(); ++j )
941cdf0e10cSrcweir 			{
942cdf0e10cSrcweir 				const SwCellFrm *pCell = (const SwCellFrm*)aCellArr[j];
943cdf0e10cSrcweir                 const sal_Bool bVert = pTab->IsVertical();
944cdf0e10cSrcweir                 const sal_Bool bRTL = pTab->IsRightToLeft();
945cdf0e10cSrcweir                 sal_Bool bTopOver, bLeftOver, bRightOver, bBottomOver;
946cdf0e10cSrcweir                 if ( bVert )
947cdf0e10cSrcweir                 {
948cdf0e10cSrcweir                     bTopOver = pCell->Frm().Right() >= rUnion.Right();
949cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Top() <= rUnion.Top();
950cdf0e10cSrcweir                     bRightOver = pCell->Frm().Bottom() >= rUnion.Bottom();
951cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Left() <= rUnion.Left();
952cdf0e10cSrcweir                 }
953cdf0e10cSrcweir                 else
954cdf0e10cSrcweir                 {
955cdf0e10cSrcweir                     bTopOver = pCell->Frm().Top() <= rUnion.Top();
956cdf0e10cSrcweir                     bLeftOver = pCell->Frm().Left() <= rUnion.Left();
957cdf0e10cSrcweir                     bRightOver = pCell->Frm().Right() >= rUnion.Right();
958cdf0e10cSrcweir                     bBottomOver = pCell->Frm().Bottom() >= rUnion.Bottom();
959cdf0e10cSrcweir                 }
960cdf0e10cSrcweir 
961cdf0e10cSrcweir                 if ( bRTL )
962cdf0e10cSrcweir                 {
963cdf0e10cSrcweir                     sal_Bool bTmp = bRightOver;
964cdf0e10cSrcweir                     bRightOver = bLeftOver;
965cdf0e10cSrcweir                     bLeftOver = bTmp;
966cdf0e10cSrcweir                 }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir 				const SwFrmFmt	*pFmt  = pCell->GetFmt();
969cdf0e10cSrcweir 				const SvxBoxItem  &rBox  = pFmt->GetBox();
970cdf0e10cSrcweir 
971cdf0e10cSrcweir 				//Obere Kante
972cdf0e10cSrcweir                 if ( bFirst && bTopOver )
973cdf0e10cSrcweir 				{
974cdf0e10cSrcweir 					if (aSetBoxInfo.IsValid(VALID_TOP))
975cdf0e10cSrcweir 					{
976cdf0e10cSrcweir 						if ( !bTopSet )
977cdf0e10cSrcweir 						{	bTopSet = sal_True;
978cdf0e10cSrcweir 							aSetBox.SetLine( rBox.GetTop(), BOX_LINE_TOP );
979cdf0e10cSrcweir 						}
980cdf0e10cSrcweir 						else if ((aSetBox.GetTop() && rBox.GetTop() &&
981cdf0e10cSrcweir 								 !(*aSetBox.GetTop() == *rBox.GetTop())) ||
982cdf0e10cSrcweir 								 ((!aSetBox.GetTop()) ^ (!rBox.GetTop()))) // XOR-Ausdruck ist sal_True, wenn genau einer der beiden Pointer 0 ist
983cdf0e10cSrcweir 						{
984cdf0e10cSrcweir 							aSetBoxInfo.SetValid(VALID_TOP, sal_False );
985cdf0e10cSrcweir 							aSetBox.SetLine( 0, BOX_LINE_TOP );
986cdf0e10cSrcweir 						}
987cdf0e10cSrcweir 					}
988cdf0e10cSrcweir 				}
989cdf0e10cSrcweir 
990cdf0e10cSrcweir 				//Linke Kante
991cdf0e10cSrcweir                 if ( bLeftOver )
992cdf0e10cSrcweir                 {
993cdf0e10cSrcweir 					if (aSetBoxInfo.IsValid(VALID_LEFT))
994cdf0e10cSrcweir 					{
995cdf0e10cSrcweir 						if ( !bLeftSet )
996cdf0e10cSrcweir 						{	bLeftSet = sal_True;
997cdf0e10cSrcweir 							aSetBox.SetLine( rBox.GetLeft(), BOX_LINE_LEFT );
998cdf0e10cSrcweir 						}
999cdf0e10cSrcweir 						else if ((aSetBox.GetLeft() && rBox.GetLeft() &&
1000cdf0e10cSrcweir 								 !(*aSetBox.GetLeft() == *rBox.GetLeft())) ||
1001cdf0e10cSrcweir 								 ((!aSetBox.GetLeft()) ^ (!rBox.GetLeft())))
1002cdf0e10cSrcweir 						{
1003cdf0e10cSrcweir 							aSetBoxInfo.SetValid(VALID_LEFT, sal_False );
1004cdf0e10cSrcweir 							aSetBox.SetLine( 0, BOX_LINE_LEFT );
1005cdf0e10cSrcweir 						}
1006cdf0e10cSrcweir 					}
1007cdf0e10cSrcweir 				}
1008cdf0e10cSrcweir 				else
1009cdf0e10cSrcweir 				{
1010cdf0e10cSrcweir 					if (aSetBoxInfo.IsValid(VALID_VERT))
1011cdf0e10cSrcweir 					{
1012cdf0e10cSrcweir 						if ( !bVertSet )
1013cdf0e10cSrcweir 						{	bVertSet = sal_True;
1014cdf0e10cSrcweir 							aSetBoxInfo.SetLine( rBox.GetLeft(), BOXINFO_LINE_VERT );
1015cdf0e10cSrcweir 						}
1016cdf0e10cSrcweir 						else if ((aSetBoxInfo.GetVert() && rBox.GetLeft() &&
1017cdf0e10cSrcweir 								 !(*aSetBoxInfo.GetVert() == *rBox.GetLeft())) ||
1018cdf0e10cSrcweir 								 ((!aSetBoxInfo.GetVert()) ^ (!rBox.GetLeft())))
1019cdf0e10cSrcweir 						{	aSetBoxInfo.SetValid( VALID_VERT, sal_False );
1020cdf0e10cSrcweir 							aSetBoxInfo.SetLine( 0, BOXINFO_LINE_VERT );
1021cdf0e10cSrcweir 						}
1022cdf0e10cSrcweir 					}
1023cdf0e10cSrcweir 				}
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir 				//Rechte Kante
1026cdf0e10cSrcweir                 if ( aSetBoxInfo.IsValid(VALID_RIGHT) && bRightOver )
1027cdf0e10cSrcweir 				{
1028cdf0e10cSrcweir 					if ( !bRightSet )
1029cdf0e10cSrcweir 					{	bRightSet = sal_True;
1030cdf0e10cSrcweir 						aSetBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
1031cdf0e10cSrcweir 					}
1032cdf0e10cSrcweir 					else if ((aSetBox.GetRight() && rBox.GetRight() &&
1033cdf0e10cSrcweir 							 !(*aSetBox.GetRight() == *rBox.GetRight())) ||
1034cdf0e10cSrcweir 							 (!aSetBox.GetRight() ^ !rBox.GetRight()))
1035cdf0e10cSrcweir 					{	aSetBoxInfo.SetValid( VALID_RIGHT, sal_False );
1036cdf0e10cSrcweir 						aSetBox.SetLine( 0, BOX_LINE_RIGHT );
1037cdf0e10cSrcweir 					}
1038cdf0e10cSrcweir 				}
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir 				//Untere Kante
1041cdf0e10cSrcweir                 if ( bLast && bBottomOver )
1042cdf0e10cSrcweir 				{
1043cdf0e10cSrcweir 					if ( aSetBoxInfo.IsValid(VALID_BOTTOM) )
1044cdf0e10cSrcweir 					{
1045cdf0e10cSrcweir 						if ( !bBottomSet )
1046cdf0e10cSrcweir 						{	bBottomSet = sal_True;
1047cdf0e10cSrcweir 							aSetBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
1048cdf0e10cSrcweir 						}
1049cdf0e10cSrcweir 						else if ((aSetBox.GetBottom() && rBox.GetBottom() &&
1050cdf0e10cSrcweir 								 !(*aSetBox.GetBottom() == *rBox.GetBottom())) ||
1051cdf0e10cSrcweir 								 (!aSetBox.GetBottom() ^ !rBox.GetBottom()))
1052cdf0e10cSrcweir 						{	aSetBoxInfo.SetValid( VALID_BOTTOM, sal_False );
1053cdf0e10cSrcweir 							aSetBox.SetLine( 0, BOX_LINE_BOTTOM );
1054cdf0e10cSrcweir 						}
1055cdf0e10cSrcweir 					}
1056cdf0e10cSrcweir 				}
1057cdf0e10cSrcweir 				//in allen Zeilen ausser der letzten werden die
1058cdf0e10cSrcweir 				// horiz. Linien aus der Bottom-Linie entnommen
1059cdf0e10cSrcweir 				else
1060cdf0e10cSrcweir 				{
1061cdf0e10cSrcweir 					if (aSetBoxInfo.IsValid(VALID_HORI))
1062cdf0e10cSrcweir 					{
1063cdf0e10cSrcweir 						if ( !bHoriSet )
1064cdf0e10cSrcweir 						{	bHoriSet = sal_True;
1065cdf0e10cSrcweir 							aSetBoxInfo.SetLine( rBox.GetBottom(), BOXINFO_LINE_HORI );
1066cdf0e10cSrcweir 						}
1067cdf0e10cSrcweir 						else if ((aSetBoxInfo.GetHori() && rBox.GetBottom() &&
1068cdf0e10cSrcweir 								 !(*aSetBoxInfo.GetHori() == *rBox.GetBottom())) ||
1069cdf0e10cSrcweir 								 ((!aSetBoxInfo.GetHori()) ^ (!rBox.GetBottom())))
1070cdf0e10cSrcweir 						{
1071cdf0e10cSrcweir 							aSetBoxInfo.SetValid( VALID_HORI, sal_False );
1072cdf0e10cSrcweir 							aSetBoxInfo.SetLine( 0, BOXINFO_LINE_HORI );
1073cdf0e10cSrcweir 						}
1074cdf0e10cSrcweir 					}
1075cdf0e10cSrcweir 				}
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir 				// Abstand zum Text
1078cdf0e10cSrcweir 				if (aSetBoxInfo.IsValid(VALID_DISTANCE))
1079cdf0e10cSrcweir 				{
1080cdf0e10cSrcweir 					static sal_uInt16 __READONLY_DATA aBorders[] = {
1081cdf0e10cSrcweir 						BOX_LINE_BOTTOM, BOX_LINE_TOP,
1082cdf0e10cSrcweir 						BOX_LINE_RIGHT, BOX_LINE_LEFT };
1083cdf0e10cSrcweir 					const sal_uInt16* pBrd = aBorders;
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir 					if( !bDistanceSet )		// bei 1. Durchlauf erstmal setzen
1086cdf0e10cSrcweir 					{
1087cdf0e10cSrcweir 						bDistanceSet = sal_True;
1088cdf0e10cSrcweir 						for( int k = 0; k < 4; ++k, ++pBrd )
1089cdf0e10cSrcweir 							aSetBox.SetDistance( rBox.GetDistance( *pBrd ),
1090cdf0e10cSrcweir 												*pBrd );
1091cdf0e10cSrcweir 					}
1092cdf0e10cSrcweir 					else
1093cdf0e10cSrcweir 					{
1094cdf0e10cSrcweir 						for( int k = 0; k < 4; ++k, ++pBrd )
1095cdf0e10cSrcweir 							if( aSetBox.GetDistance( *pBrd ) !=
1096cdf0e10cSrcweir 								rBox.GetDistance( *pBrd ) )
1097cdf0e10cSrcweir 							{
1098cdf0e10cSrcweir 								aSetBoxInfo.SetValid( VALID_DISTANCE, sal_False );
1099cdf0e10cSrcweir 								aSetBox.SetDistance( (sal_uInt16) 0 );
1100cdf0e10cSrcweir 								break;
1101cdf0e10cSrcweir 							}
1102cdf0e10cSrcweir 					}
1103cdf0e10cSrcweir 				}
1104cdf0e10cSrcweir 			}
1105cdf0e10cSrcweir 		}
1106cdf0e10cSrcweir 		rSet.Put( aSetBox );
1107cdf0e10cSrcweir 		rSet.Put( aSetBoxInfo );
1108cdf0e10cSrcweir 	}
1109cdf0e10cSrcweir }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir /***********************************************************************
1112cdf0e10cSrcweir #*	Class	   :  SwDoc
1113cdf0e10cSrcweir #*	Methoden   :  SetBoxAttr
1114cdf0e10cSrcweir #*	Datum	   :  MA 18. Dec. 96
1115cdf0e10cSrcweir #*	Update	   :  JP 29.04.98
1116cdf0e10cSrcweir #***********************************************************************/
SetBoxAttr(const SwCursor & rCursor,const SfxPoolItem & rNew)1117cdf0e10cSrcweir void SwDoc::SetBoxAttr( const SwCursor& rCursor, const SfxPoolItem &rNew )
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1120cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1121cdf0e10cSrcweir 	if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes, sal_True ) )
1122cdf0e10cSrcweir 	{
1123cdf0e10cSrcweir 		SwTable& rTable = pTblNd->GetTable();
1124cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
1125cdf0e10cSrcweir         {
1126cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( new SwUndoAttrTbl(*pTblNd) );
1127cdf0e10cSrcweir         }
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir 		SvPtrarr aFmtCmp( Max( sal_uInt8(255), sal_uInt8(aBoxes.Count()) ), 255 );
1130cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1131cdf0e10cSrcweir 		{
1132cdf0e10cSrcweir 			SwTableBox *pBox = aBoxes[i];
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir 			SwFrmFmt *pNewFmt;
1135cdf0e10cSrcweir 			if ( 0 != (pNewFmt = SwTblFmtCmp::FindNewFmt( aFmtCmp, pBox->GetFrmFmt(), 0 )))
1136cdf0e10cSrcweir 				pBox->ChgFrmFmt( (SwTableBoxFmt*)pNewFmt );
1137cdf0e10cSrcweir 			else
1138cdf0e10cSrcweir 			{
1139cdf0e10cSrcweir 				SwFrmFmt *pOld = pBox->GetFrmFmt();
1140cdf0e10cSrcweir 				SwFrmFmt *pNew = pBox->ClaimFrmFmt();
1141cdf0e10cSrcweir                 pNew->SetFmtAttr( rNew );
1142cdf0e10cSrcweir 				aFmtCmp.Insert( new SwTblFmtCmp( pOld, pNew, 0 ), aFmtCmp.Count());
1143cdf0e10cSrcweir 			}
1144cdf0e10cSrcweir 		}
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir 		SwHTMLTableLayout *pTableLayout = rTable.GetHTMLTableLayout();
1147cdf0e10cSrcweir 		if( pTableLayout )
1148cdf0e10cSrcweir 		{
1149cdf0e10cSrcweir 			SwCntntFrm* pFrm = rCursor.GetCntntNode()->getLayoutFrm( rCursor.GetCntntNode()->GetDoc()->GetCurrentLayout() );
1150cdf0e10cSrcweir 			SwTabFrm* pTabFrm = pFrm->ImplFindTabFrm();
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 			pTableLayout->Resize(
1153cdf0e10cSrcweir 				pTableLayout->GetBrowseWidthByTabFrm( *pTabFrm ), sal_True );
1154cdf0e10cSrcweir 		}
1155cdf0e10cSrcweir 		SwTblFmtCmp::Delete( aFmtCmp );
1156cdf0e10cSrcweir 		SetModified();
1157cdf0e10cSrcweir 	}
1158cdf0e10cSrcweir }
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir /***********************************************************************
1161cdf0e10cSrcweir #*	Class	   :  SwDoc
1162cdf0e10cSrcweir #*  Methoden   :  GetBoxAttr()
1163cdf0e10cSrcweir #*	Datum	   :  MA 01. Jun. 93
1164cdf0e10cSrcweir #*	Update	   :  JP 29.04.98
1165cdf0e10cSrcweir #***********************************************************************/
1166cdf0e10cSrcweir 
GetBoxAttr(const SwCursor & rCursor,SfxPoolItem & rToFill) const1167cdf0e10cSrcweir sal_Bool SwDoc::GetBoxAttr( const SwCursor& rCursor, SfxPoolItem& rToFill ) const
1168cdf0e10cSrcweir {
1169cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1170cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1171cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1172cdf0e10cSrcweir 	if( pTblNd && lcl_GetBoxSel( rCursor, aBoxes ))
1173cdf0e10cSrcweir 	{
1174cdf0e10cSrcweir 		bRet = sal_True;
1175cdf0e10cSrcweir 		sal_Bool bOneFound = sal_False;
1176cdf0e10cSrcweir         const sal_uInt16 nWhich = rToFill.Which();
1177cdf0e10cSrcweir 		for( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1178cdf0e10cSrcweir 		{
1179cdf0e10cSrcweir             switch ( nWhich )
1180cdf0e10cSrcweir             {
1181cdf0e10cSrcweir                 case RES_BACKGROUND:
1182cdf0e10cSrcweir                 {
1183cdf0e10cSrcweir                     const SvxBrushItem &rBack =
1184cdf0e10cSrcweir                                     aBoxes[i]->GetFrmFmt()->GetBackground();
1185cdf0e10cSrcweir                     if( !bOneFound )
1186cdf0e10cSrcweir                     {
1187cdf0e10cSrcweir                         (SvxBrushItem&)rToFill = rBack;
1188cdf0e10cSrcweir                         bOneFound = sal_True;
1189cdf0e10cSrcweir                     }
1190cdf0e10cSrcweir                     else if( rToFill != rBack )
1191cdf0e10cSrcweir                         bRet = sal_False;
1192cdf0e10cSrcweir                 }
1193cdf0e10cSrcweir                 break;
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir                 case RES_FRAMEDIR:
1196cdf0e10cSrcweir                 {
1197cdf0e10cSrcweir                     const SvxFrameDirectionItem& rDir =
1198cdf0e10cSrcweir                                     aBoxes[i]->GetFrmFmt()->GetFrmDir();
1199cdf0e10cSrcweir                     if( !bOneFound )
1200cdf0e10cSrcweir                     {
1201cdf0e10cSrcweir                         (SvxFrameDirectionItem&)rToFill = rDir;
1202cdf0e10cSrcweir                         bOneFound = sal_True;
1203cdf0e10cSrcweir                     }
1204cdf0e10cSrcweir                     else if( rToFill != rDir )
1205cdf0e10cSrcweir                         bRet = sal_False;
1206cdf0e10cSrcweir                 }
1207cdf0e10cSrcweir             }
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir             if ( sal_False == bRet )
1210cdf0e10cSrcweir                 break;
1211cdf0e10cSrcweir 		}
1212cdf0e10cSrcweir 	}
1213cdf0e10cSrcweir 	return bRet;
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir /***********************************************************************
1217cdf0e10cSrcweir #*	Class	   :  SwDoc
1218cdf0e10cSrcweir #*	Methoden   :  SetBoxAlign, SetBoxAlign
1219cdf0e10cSrcweir #*	Datum	   :  MA 18. Dec. 96
1220cdf0e10cSrcweir #*	Update	   :  JP 29.04.98
1221cdf0e10cSrcweir #***********************************************************************/
SetBoxAlign(const SwCursor & rCursor,sal_uInt16 nAlign)1222cdf0e10cSrcweir void SwDoc::SetBoxAlign( const SwCursor& rCursor, sal_uInt16 nAlign )
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir     ASSERT( nAlign == text::VertOrientation::NONE   ||
1225cdf0e10cSrcweir             nAlign == text::VertOrientation::CENTER ||
1226cdf0e10cSrcweir             nAlign == text::VertOrientation::BOTTOM, "wrong alignment" );
1227cdf0e10cSrcweir     SwFmtVertOrient aVertOri( 0, nAlign );
1228cdf0e10cSrcweir 	SetBoxAttr( rCursor, aVertOri );
1229cdf0e10cSrcweir }
1230cdf0e10cSrcweir 
GetBoxAlign(const SwCursor & rCursor) const1231cdf0e10cSrcweir sal_uInt16 SwDoc::GetBoxAlign( const SwCursor& rCursor ) const
1232cdf0e10cSrcweir {
1233cdf0e10cSrcweir 	sal_uInt16 nAlign = USHRT_MAX;
1234cdf0e10cSrcweir 	SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
1235cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1236cdf0e10cSrcweir 	if( pTblNd && ::lcl_GetBoxSel( rCursor, aBoxes ))
1237cdf0e10cSrcweir 		for( sal_uInt16 i = 0; i < aBoxes.Count(); ++i )
1238cdf0e10cSrcweir 		{
1239cdf0e10cSrcweir 			const SwFmtVertOrient &rOri =
1240cdf0e10cSrcweir 							aBoxes[i]->GetFrmFmt()->GetVertOrient();
1241cdf0e10cSrcweir 			if( USHRT_MAX == nAlign )
1242cdf0e10cSrcweir 				nAlign = static_cast<sal_uInt16>(rOri.GetVertOrient());
1243cdf0e10cSrcweir 			else if( rOri.GetVertOrient() != nAlign )
1244cdf0e10cSrcweir 			{
1245cdf0e10cSrcweir 				nAlign = USHRT_MAX;
1246cdf0e10cSrcweir 				break;
1247cdf0e10cSrcweir 			}
1248cdf0e10cSrcweir 		}
1249cdf0e10cSrcweir 	return nAlign;
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir /***********************************************************************
1254cdf0e10cSrcweir #*	Class	   :  SwDoc
1255cdf0e10cSrcweir #*	Methoden   :  AdjustCellWidth()
1256cdf0e10cSrcweir #*	Datum	   :  MA 20. Feb. 95
1257cdf0e10cSrcweir #*	Update	   :  JP 29.04.98
1258cdf0e10cSrcweir #***********************************************************************/
lcl_CalcCellFit(const SwLayoutFrm * pCell)1259cdf0e10cSrcweir sal_uInt16 lcl_CalcCellFit( const SwLayoutFrm *pCell )
1260cdf0e10cSrcweir {
1261cdf0e10cSrcweir 	SwTwips nRet = 0;
1262cdf0e10cSrcweir 	const SwFrm *pFrm = pCell->Lower();	//Die ganze Zelle.
1263cdf0e10cSrcweir 	SWRECTFN( pCell )
1264cdf0e10cSrcweir 	while ( pFrm )
1265cdf0e10cSrcweir 	{
1266cdf0e10cSrcweir 		const SwTwips nAdd = (pFrm->Frm().*fnRect->fnGetWidth)() -
1267cdf0e10cSrcweir 							 (pFrm->Prt().*fnRect->fnGetWidth)();
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir         // --> FME 2005-12-02 #127801# pFrm does not necessarily have to be a SwTxtFrm!
1270cdf0e10cSrcweir         const SwTwips nCalcFitToContent = pFrm->IsTxtFrm() ?
1271cdf0e10cSrcweir                                           ((SwTxtFrm*)pFrm)->CalcFitToContent() :
1272cdf0e10cSrcweir                                           (pFrm->Prt().*fnRect->fnGetWidth)();
1273cdf0e10cSrcweir         // <--
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir         nRet = Max( nRet, nCalcFitToContent + nAdd );
1276cdf0e10cSrcweir         pFrm = pFrm->GetNext();
1277cdf0e10cSrcweir 	}
1278cdf0e10cSrcweir 	//Umrandung und linker/rechter Rand wollen mit kalkuliert werden.
1279cdf0e10cSrcweir 	nRet += (pCell->Frm().*fnRect->fnGetWidth)() -
1280cdf0e10cSrcweir 			(pCell->Prt().*fnRect->fnGetWidth)();
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir 	//Um Rechenungenauikeiten, die spaeter bei SwTable::SetTabCols enstehen,
1283cdf0e10cSrcweir 	//auszugleichen, addieren wir noch ein bischen.
1284cdf0e10cSrcweir 	nRet += COLFUZZY;
1285cdf0e10cSrcweir 	return (sal_uInt16)Max( long(MINLAY), nRet );
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir /*Die Zelle ist in der Selektion, wird aber nicht von den TabCols beschrieben.
1289cdf0e10cSrcweir  *Das bedeutet, dass die Zelle aufgrund der zweidimensionalen Darstellung von
1290cdf0e10cSrcweir  *anderen Zellen "geteilt" wurde. Wir muessen also den Wunsch- bzw. Minimalwert
1291cdf0e10cSrcweir  *der Zelle auf die Spalten, durch die sie geteilt wurde verteilen.
1292cdf0e10cSrcweir  *
1293cdf0e10cSrcweir  *Dazu sammeln wir zuerst die Spalten - nicht die Spaltentrenner! - ein, die
1294cdf0e10cSrcweir  *sich mit der Zelle ueberschneiden. Den Wunschwert der Zelle verteilen wir
1295cdf0e10cSrcweir  *dann anhand des Betrages der Ueberschneidung auf die Zellen.
1296cdf0e10cSrcweir  *Wenn eine Zelle bereits einen groesseren Wunschwert angemeldet hat, so bleibt
1297cdf0e10cSrcweir  *dieser erhalten, kleinere Wuensche werden ueberschrieben.
1298cdf0e10cSrcweir  */
1299cdf0e10cSrcweir 
lcl_CalcSubColValues(SvUShorts & rToFill,const SwTabCols & rCols,const SwLayoutFrm * pCell,const SwLayoutFrm * pTab,sal_Bool bWishValues)1300cdf0e10cSrcweir void lcl_CalcSubColValues( SvUShorts &rToFill, const SwTabCols &rCols,
1301cdf0e10cSrcweir 							  const SwLayoutFrm *pCell, const SwLayoutFrm *pTab,
1302cdf0e10cSrcweir 							  sal_Bool bWishValues )
1303cdf0e10cSrcweir {
1304cdf0e10cSrcweir 	const sal_uInt16 nWish = bWishValues ?
1305cdf0e10cSrcweir 					::lcl_CalcCellFit( pCell ) :
1306cdf0e10cSrcweir 					MINLAY + sal_uInt16(pCell->Frm().Width() - pCell->Prt().Width());
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir     SWRECTFN( pTab )
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir 	for ( sal_uInt16 i = 0 ; i <= rCols.Count(); ++i )
1311cdf0e10cSrcweir 	{
1312cdf0e10cSrcweir 		long nColLeft  = i == 0 			? rCols.GetLeft()  : rCols[i-1];
1313cdf0e10cSrcweir 		long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
1314cdf0e10cSrcweir 		nColLeft  += rCols.GetLeftMin();
1315cdf0e10cSrcweir 		nColRight += rCols.GetLeftMin();
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir 		//Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
1318cdf0e10cSrcweir         if ( rCols.GetLeftMin() !=  sal_uInt16((pTab->Frm().*fnRect->fnGetLeft)()) )
1319cdf0e10cSrcweir 		{
1320cdf0e10cSrcweir             const long nDiff = (pTab->Frm().*fnRect->fnGetLeft)() - rCols.GetLeftMin();
1321cdf0e10cSrcweir 			nColLeft  += nDiff;
1322cdf0e10cSrcweir 			nColRight += nDiff;
1323cdf0e10cSrcweir 		}
1324cdf0e10cSrcweir         const long nCellLeft  = (pCell->Frm().*fnRect->fnGetLeft)();
1325cdf0e10cSrcweir         const long nCellRight = (pCell->Frm().*fnRect->fnGetRight)();
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir 		//Ueberschneidungsbetrag ermitteln.
1328cdf0e10cSrcweir 		long nWidth = 0;
1329cdf0e10cSrcweir 		if ( nColLeft <= nCellLeft && nColRight >= (nCellLeft+COLFUZZY) )
1330cdf0e10cSrcweir 			nWidth = nColRight - nCellLeft;
1331cdf0e10cSrcweir 		else if ( nColLeft <= (nCellRight-COLFUZZY) && nColRight >= nCellRight )
1332cdf0e10cSrcweir 			nWidth = nCellRight - nColLeft;
1333cdf0e10cSrcweir 		else if ( nColLeft >= nCellLeft && nColRight <= nCellRight )
1334cdf0e10cSrcweir 			nWidth = nColRight - nColLeft;
1335cdf0e10cSrcweir 		if ( nWidth && pCell->Frm().Width() )
1336cdf0e10cSrcweir 		{
1337cdf0e10cSrcweir 			long nTmp = nWidth * nWish / pCell->Frm().Width();
1338cdf0e10cSrcweir 			if ( sal_uInt16(nTmp) > rToFill[i] )
1339cdf0e10cSrcweir 				rToFill[i] = sal_uInt16(nTmp);
1340cdf0e10cSrcweir 		}
1341cdf0e10cSrcweir 	}
1342cdf0e10cSrcweir }
1343cdf0e10cSrcweir 
1344cdf0e10cSrcweir /*Besorgt neue Werte zu Einstellung der TabCols.
1345cdf0e10cSrcweir  *Es wird nicht ueber die Eintrage in den TabCols itereriert, sondern
1346cdf0e10cSrcweir  *quasi ueber die Zwischenraeume, die ja die Zellen beschreiben.
1347cdf0e10cSrcweir  *
1348cdf0e10cSrcweir  *bWishValues == sal_True:	Es werden zur aktuellen Selektion bzw. zur aktuellen
1349cdf0e10cSrcweir  *						Zelle die Wunschwerte aller betroffen Zellen ermittelt.
1350cdf0e10cSrcweir  * 						Sind mehrere Zellen in einer Spalte, so wird der
1351cdf0e10cSrcweir  *						groesste Wunschwert als Ergebnis geliefert.
1352cdf0e10cSrcweir  * 						Fuer die TabCol-Eintraege, zu denen keine Zellen
1353cdf0e10cSrcweir  * 						ermittelt wurden, werden 0-en eingetragen.
1354cdf0e10cSrcweir  *
1355cdf0e10cSrcweir  *bWishValues == sal_False: Die Selektion wird senkrecht ausgedehnt. Zu jeder
1356cdf0e10cSrcweir  * 						Spalte in den TabCols, die sich mit der Selektion
1357cdf0e10cSrcweir  *						schneidet wird der Minimalwert ermittelt.
1358cdf0e10cSrcweir  */
1359cdf0e10cSrcweir 
lcl_CalcColValues(SvUShorts & rToFill,const SwTabCols & rCols,const SwLayoutFrm * pStart,const SwLayoutFrm * pEnd,sal_Bool bWishValues)1360cdf0e10cSrcweir void lcl_CalcColValues( SvUShorts &rToFill, const SwTabCols &rCols,
1361cdf0e10cSrcweir 						   const SwLayoutFrm *pStart, const SwLayoutFrm *pEnd,
1362cdf0e10cSrcweir 						   sal_Bool bWishValues )
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir 	SwSelUnions aUnions;
1365cdf0e10cSrcweir 	::MakeSelUnions( aUnions, pStart, pEnd,
1366cdf0e10cSrcweir 					bWishValues ? nsSwTblSearchType::TBLSEARCH_NONE : nsSwTblSearchType::TBLSEARCH_COL );
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir 	for ( sal_uInt16 i2 = 0; i2 < aUnions.Count(); ++i2 )
1369cdf0e10cSrcweir 	{
1370cdf0e10cSrcweir 		SwSelUnion *pSelUnion = aUnions[i2];
1371cdf0e10cSrcweir 		const SwTabFrm *pTab = pSelUnion->GetTable();
1372cdf0e10cSrcweir 		const SwRect &rUnion = pSelUnion->GetUnion();
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir 		SWRECTFN( pTab )
1375cdf0e10cSrcweir         sal_Bool bRTL = pTab->IsRightToLeft();
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir 		const SwLayoutFrm *pCell = pTab->FirstCell();
1378cdf0e10cSrcweir 		do
1379cdf0e10cSrcweir 		{
1380cdf0e10cSrcweir             if ( pCell->IsCellFrm() && pCell->FindTabFrm() == pTab && ::IsFrmInTblSel( rUnion, pCell ) )
1381cdf0e10cSrcweir 			{
1382cdf0e10cSrcweir 				const long nCLeft  = (pCell->Frm().*fnRect->fnGetLeft)();
1383cdf0e10cSrcweir 				const long nCRight = (pCell->Frm().*fnRect->fnGetRight)();
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir 				sal_Bool bNotInCols = sal_True;
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir 				for ( sal_uInt16 i = 0; i <= rCols.Count(); ++i )
1388cdf0e10cSrcweir 				{
1389cdf0e10cSrcweir 					sal_uInt16 nFit = rToFill[i];
1390cdf0e10cSrcweir 					long nColLeft  = i == 0 			? rCols.GetLeft()  : rCols[i-1];
1391cdf0e10cSrcweir 					long nColRight = i == rCols.Count() ? rCols.GetRight() : rCols[i];
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir                     if ( bRTL )
1394cdf0e10cSrcweir                     {
1395cdf0e10cSrcweir 						long nTmpRight = nColRight;
1396cdf0e10cSrcweir                         nColRight = rCols.GetRight() - nColLeft;
1397cdf0e10cSrcweir                         nColLeft = rCols.GetRight() - nTmpRight;
1398cdf0e10cSrcweir                     }
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir                     nColLeft  += rCols.GetLeftMin();
1401cdf0e10cSrcweir                     nColRight += rCols.GetLeftMin();
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir 					//Werte auf die Verhaeltnisse der Tabelle (Follows) anpassen.
1404cdf0e10cSrcweir 					long nLeftA  = nColLeft;
1405cdf0e10cSrcweir 					long nRightA = nColRight;
1406cdf0e10cSrcweir 					if ( rCols.GetLeftMin() !=	sal_uInt16((pTab->Frm().*fnRect->fnGetLeft)()) )
1407cdf0e10cSrcweir 					{
1408cdf0e10cSrcweir 						const long nDiff = (pTab->Frm().*fnRect->fnGetLeft)() - rCols.GetLeftMin();
1409cdf0e10cSrcweir 						nLeftA	+= nDiff;
1410cdf0e10cSrcweir 						nRightA += nDiff;
1411cdf0e10cSrcweir 					}
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir 					//Wir wollen nicht allzu genau hinsehen.
1414cdf0e10cSrcweir 					if ( ::IsSame(nCLeft, nLeftA) && ::IsSame(nCRight, nRightA))
1415cdf0e10cSrcweir 					{
1416cdf0e10cSrcweir 						bNotInCols = sal_False;
1417cdf0e10cSrcweir 						if ( bWishValues )
1418cdf0e10cSrcweir 						{
1419cdf0e10cSrcweir 							const sal_uInt16 nWish = ::lcl_CalcCellFit( pCell );
1420cdf0e10cSrcweir 							if ( nWish > nFit )
1421cdf0e10cSrcweir 								nFit = nWish;
1422cdf0e10cSrcweir 						}
1423cdf0e10cSrcweir 						else
1424cdf0e10cSrcweir 						{	const sal_uInt16 nMin = MINLAY + sal_uInt16(pCell->Frm().Width() -
1425cdf0e10cSrcweir 																pCell->Prt().Width());
1426cdf0e10cSrcweir 							if ( !nFit || nMin < nFit )
1427cdf0e10cSrcweir 								nFit = nMin;
1428cdf0e10cSrcweir 						}
1429cdf0e10cSrcweir 						if ( rToFill[i] < nFit )
1430cdf0e10cSrcweir 							rToFill[i] = nFit;
1431cdf0e10cSrcweir 					}
1432cdf0e10cSrcweir 				}
1433cdf0e10cSrcweir 				if ( bNotInCols )
1434cdf0e10cSrcweir 					::lcl_CalcSubColValues( rToFill, rCols, pCell, pTab, bWishValues );
1435cdf0e10cSrcweir 			}
1436cdf0e10cSrcweir             do {
1437cdf0e10cSrcweir                 pCell = pCell->GetNextLayoutLeaf();
1438cdf0e10cSrcweir             }while( pCell && pCell->Frm().Width() == 0 );
1439cdf0e10cSrcweir         } while ( pCell && pTab->IsAnLower( pCell ) );
1440cdf0e10cSrcweir 	}
1441cdf0e10cSrcweir }
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir 
AdjustCellWidth(const SwCursor & rCursor,sal_Bool bBalance)1444cdf0e10cSrcweir void SwDoc::AdjustCellWidth( const SwCursor& rCursor, sal_Bool bBalance )
1445cdf0e10cSrcweir {
1446cdf0e10cSrcweir 	// pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
1447cdf0e10cSrcweir 	SwCntntNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetCntntNode();
1448cdf0e10cSrcweir 	SwTableNode* pTblNd = pCntNd ? pCntNd->FindTableNode() : 0;
1449cdf0e10cSrcweir 	if( !pTblNd )
1450cdf0e10cSrcweir 		return ;
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir 	SwLayoutFrm *pStart, *pEnd;
1453cdf0e10cSrcweir 	::lcl_GetStartEndCell( rCursor, pStart, pEnd );
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir 	//TabCols besorgen, den ueber diese stellen wir die Tabelle neu ein.
1456cdf0e10cSrcweir 	SwFrm* pBoxFrm = pStart;
1457cdf0e10cSrcweir     while( pBoxFrm && !pBoxFrm->IsCellFrm() )
1458cdf0e10cSrcweir 		pBoxFrm = pBoxFrm->GetUpper();
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir     if ( !pBoxFrm )
1461cdf0e10cSrcweir         return; // robust
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir 	SwTabCols aTabCols;
1464cdf0e10cSrcweir 	GetTabCols( aTabCols, 0, (SwCellFrm*)pBoxFrm );
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir     if ( ! aTabCols.Count() )
1467cdf0e10cSrcweir         return;
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir 	const sal_uInt8 nTmp = (sal_uInt8)Max( sal_uInt16(255), sal_uInt16(aTabCols.Count() + 1) );
1470cdf0e10cSrcweir 	SvUShorts aWish( nTmp, nTmp ),
1471cdf0e10cSrcweir 			  aMins( nTmp, nTmp );
1472cdf0e10cSrcweir 	sal_uInt16 i;
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir 	for ( i = 0; i <= aTabCols.Count(); ++i )
1475cdf0e10cSrcweir 	{
1476cdf0e10cSrcweir 		aWish.Insert( sal_uInt16(0), aWish.Count() );
1477cdf0e10cSrcweir 		aMins.Insert( sal_uInt16(0), aMins.Count() );
1478cdf0e10cSrcweir 	}
1479cdf0e10cSrcweir 	::lcl_CalcColValues( aWish, aTabCols, pStart, pEnd, sal_True  );
1480cdf0e10cSrcweir 
1481cdf0e10cSrcweir 	//Es ist Robuster wenn wir die Min-Werte fuer die ganze Tabelle berechnen.
1482cdf0e10cSrcweir 	const SwTabFrm *pTab = pStart->ImplFindTabFrm();
1483cdf0e10cSrcweir 	pStart = (SwLayoutFrm*)pTab->FirstCell();
1484cdf0e10cSrcweir 	pEnd   = (SwLayoutFrm*)pTab->FindLastCntnt()->GetUpper();
1485cdf0e10cSrcweir 	while( !pEnd->IsCellFrm() )
1486cdf0e10cSrcweir 		pEnd = pEnd->GetUpper();
1487cdf0e10cSrcweir 	::lcl_CalcColValues( aMins, aTabCols, pStart, pEnd, sal_False );
1488cdf0e10cSrcweir 
1489cdf0e10cSrcweir 	if( bBalance )
1490cdf0e10cSrcweir 	{
1491cdf0e10cSrcweir 		//Alle Spalten, die makiert sind haben jetzt einen Wunschwert
1492cdf0e10cSrcweir 		//eingtragen. Wir addieren die aktuellen Werte, teilen das Ergebnis
1493cdf0e10cSrcweir 		//durch die Anzahl und haben eine Wunschwert fuer den ausgleich.
1494cdf0e10cSrcweir 		sal_uInt16 nWish = 0, nCnt = 0;
1495cdf0e10cSrcweir 		for ( i = 0; i <= aTabCols.Count(); ++i )
1496cdf0e10cSrcweir 		{
1497cdf0e10cSrcweir 			int nDiff = aWish[i];
1498cdf0e10cSrcweir 			if ( nDiff )
1499cdf0e10cSrcweir 			{
1500cdf0e10cSrcweir 				if ( i == 0 )
1501cdf0e10cSrcweir 					nWish = static_cast<sal_uInt16>( nWish + aTabCols[i] - aTabCols.GetLeft() );
1502cdf0e10cSrcweir 				else if ( i == aTabCols.Count() )
1503cdf0e10cSrcweir 					nWish = static_cast<sal_uInt16>(nWish + aTabCols.GetRight() - aTabCols[i-1] );
1504cdf0e10cSrcweir 				else
1505cdf0e10cSrcweir 					nWish = static_cast<sal_uInt16>(nWish + aTabCols[i] - aTabCols[i-1] );
1506cdf0e10cSrcweir 				++nCnt;
1507cdf0e10cSrcweir 			}
1508cdf0e10cSrcweir 		}
1509cdf0e10cSrcweir 		nWish = nWish / nCnt;
1510cdf0e10cSrcweir 		for ( i = 0; i < aWish.Count(); ++i )
1511cdf0e10cSrcweir 			if ( aWish[i] )
1512cdf0e10cSrcweir 				aWish[i] = nWish;
1513cdf0e10cSrcweir 	}
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir 	const sal_uInt16 nOldRight = static_cast<sal_uInt16>(aTabCols.GetRight());
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir 	//Um die Impl. einfach zu gestalten, aber trotzdem in den meissten Faellen
1518cdf0e10cSrcweir 	//den Platz richtig auszunutzen laufen wir zweimal.
1519cdf0e10cSrcweir 	//Problem: Erste Spalte wird breiter, die anderen aber erst danach
1520cdf0e10cSrcweir 	//schmaler. Die Wunschbreite der ersten Spalte wuerde abgelehnt, weil
1521cdf0e10cSrcweir 	//mit ihr die max. Breite der Tabelle ueberschritten wuerde.
1522cdf0e10cSrcweir 	for ( sal_uInt16 k= 0; k < 2; ++k )
1523cdf0e10cSrcweir 	{
1524cdf0e10cSrcweir 		for ( i = 0; i <= aTabCols.Count(); ++i )
1525cdf0e10cSrcweir 		{
1526cdf0e10cSrcweir 			int nDiff = aWish[i];
1527cdf0e10cSrcweir 			if ( nDiff )
1528cdf0e10cSrcweir 			{
1529cdf0e10cSrcweir 				int nMin = aMins[i];
1530cdf0e10cSrcweir 				if ( nMin > nDiff )
1531cdf0e10cSrcweir 					nDiff = nMin;
1532cdf0e10cSrcweir 
1533cdf0e10cSrcweir 				if ( i == 0 )
1534cdf0e10cSrcweir 				{
1535cdf0e10cSrcweir 					if( aTabCols.Count() )
1536cdf0e10cSrcweir 						nDiff -= aTabCols[0] - aTabCols.GetLeft();
1537cdf0e10cSrcweir 					else
1538cdf0e10cSrcweir 						nDiff -= aTabCols.GetRight() - aTabCols.GetLeft();
1539cdf0e10cSrcweir 				}
1540cdf0e10cSrcweir 				else if ( i == aTabCols.Count() )
1541cdf0e10cSrcweir 					nDiff -= aTabCols.GetRight() - aTabCols[i-1];
1542cdf0e10cSrcweir 				else
1543cdf0e10cSrcweir 					nDiff -= aTabCols[i] - aTabCols[i-1];
1544cdf0e10cSrcweir 
1545cdf0e10cSrcweir                 long nTabRight = aTabCols.GetRight() + nDiff;
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir 				//Wenn die Tabelle zu breit wuerde begrenzen wir die Anpassung
1548cdf0e10cSrcweir 				//auf das erlaubte Maximum.
1549cdf0e10cSrcweir 				if ( !bBalance && nTabRight > aTabCols.GetRightMax() )
1550cdf0e10cSrcweir 				{
1551cdf0e10cSrcweir                     const long nTmpD = nTabRight - aTabCols.GetRightMax();
1552cdf0e10cSrcweir 					nDiff	  -= nTmpD;
1553cdf0e10cSrcweir 					nTabRight -= nTmpD;
1554cdf0e10cSrcweir 				}
1555cdf0e10cSrcweir 				for ( sal_uInt16 i2 = i; i2 < aTabCols.Count(); ++i2 )
1556cdf0e10cSrcweir 					aTabCols[i2] += nDiff;
1557cdf0e10cSrcweir 				aTabCols.SetRight( nTabRight );
1558cdf0e10cSrcweir 			}
1559cdf0e10cSrcweir 		}
1560cdf0e10cSrcweir 	}
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir 	const sal_uInt16 nNewRight = static_cast<sal_uInt16>(aTabCols.GetRight());
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir     SwFrmFmt *pFmt = pTblNd->GetTable().GetFrmFmt();
1565cdf0e10cSrcweir     const sal_Int16 nOriHori = pFmt->GetHoriOrient().GetHoriOrient();
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir 	//So, die richtige Arbeit koennen wir jetzt der SwTable ueberlassen.
1568cdf0e10cSrcweir 	SetTabCols( aTabCols, sal_False, 0, (SwCellFrm*)pBoxFrm );
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir     // i54248: lijian/fme
1571cdf0e10cSrcweir     // alignment might have been changed in SetTabCols, restore old value:
1572cdf0e10cSrcweir     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
1573cdf0e10cSrcweir     SwFmtHoriOrient aHori( rHori );
1574cdf0e10cSrcweir     if ( aHori.GetHoriOrient() != nOriHori )
1575cdf0e10cSrcweir     {
1576cdf0e10cSrcweir         aHori.SetHoriOrient( nOriHori );
1577cdf0e10cSrcweir         pFmt->SetFmtAttr( aHori );
1578cdf0e10cSrcweir     }
1579cdf0e10cSrcweir 
1580cdf0e10cSrcweir     //Bei Automatischer Breite wird auf Linksbuendig umgeschaltet.
1581cdf0e10cSrcweir 	//Bei Randattributen wird der Rechte Rand angepasst.
1582cdf0e10cSrcweir 	if( !bBalance && nNewRight < nOldRight )
1583cdf0e10cSrcweir 	{
1584cdf0e10cSrcweir         if( aHori.GetHoriOrient() == text::HoriOrientation::FULL )
1585cdf0e10cSrcweir 		{
1586cdf0e10cSrcweir             aHori.SetHoriOrient( text::HoriOrientation::LEFT );
1587cdf0e10cSrcweir             pFmt->SetFmtAttr( aHori );
1588cdf0e10cSrcweir 		}
1589cdf0e10cSrcweir 	}
1590cdf0e10cSrcweir 
1591cdf0e10cSrcweir 	SetModified();
1592cdf0e10cSrcweir }
1593cdf0e10cSrcweir 
1594