xref: /aoo41x/main/sw/source/core/layout/colfrm.cxx (revision d1af8f7d)
1efeef26fSAndrew Rist /**************************************************************
2efeef26fSAndrew Rist  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <hintids.hxx>
28cdf0e10cSrcweir #include "cntfrm.hxx"
29cdf0e10cSrcweir #include "doc.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "hintids.hxx"
32cdf0e10cSrcweir #include <editeng/ulspitem.hxx>
33cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
34cdf0e10cSrcweir #include <fmtclds.hxx>
35cdf0e10cSrcweir #include <fmtfordr.hxx>
36cdf0e10cSrcweir #include <frmfmt.hxx>
37cdf0e10cSrcweir #include <node.hxx>
38cdf0e10cSrcweir #include "frmtool.hxx"
39cdf0e10cSrcweir #include "colfrm.hxx"
40cdf0e10cSrcweir #include "pagefrm.hxx"
41cdf0e10cSrcweir #include "bodyfrm.hxx"	 // ColumnFrms jetzt mit BodyFrm
42cdf0e10cSrcweir #include "rootfrm.hxx"   // wg. RemoveFtns
43cdf0e10cSrcweir #include "sectfrm.hxx"	 // wg. FtnAtEnd-Flag
44cdf0e10cSrcweir #include "switerator.hxx"
45cdf0e10cSrcweir 
46cdf0e10cSrcweir // ftnfrm.cxx:
47cdf0e10cSrcweir void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir /*************************************************************************
51cdf0e10cSrcweir |*
52cdf0e10cSrcweir |*	SwColumnFrm::SwColumnFrm()
53cdf0e10cSrcweir |*
54cdf0e10cSrcweir |*	Ersterstellung		MA ??
55cdf0e10cSrcweir |*	Letzte Aenderung	AMA 30. Oct 98
56cdf0e10cSrcweir |*
57cdf0e10cSrcweir |*************************************************************************/
SwColumnFrm(SwFrmFmt * pFmt,SwFrm * pSib)58cdf0e10cSrcweir SwColumnFrm::SwColumnFrm( SwFrmFmt *pFmt, SwFrm* pSib ):
59cdf0e10cSrcweir 	SwFtnBossFrm( pFmt, pSib )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     nType = FRMC_COLUMN;
62cdf0e10cSrcweir 	SwBodyFrm* pColBody = new SwBodyFrm( pFmt->GetDoc()->GetDfltFrmFmt(), pSib );
63cdf0e10cSrcweir 	pColBody->InsertBehind( this, 0 ); // ColumnFrms jetzt mit BodyFrm
64cdf0e10cSrcweir 	SetMaxFtnHeight( LONG_MAX );
65cdf0e10cSrcweir }
66cdf0e10cSrcweir 
~SwColumnFrm()67cdf0e10cSrcweir SwColumnFrm::~SwColumnFrm()
68cdf0e10cSrcweir {
69cdf0e10cSrcweir 	SwFrmFmt *pFmt = GetFmt();
70cdf0e10cSrcweir 	SwDoc *pDoc;
71cdf0e10cSrcweir 	if ( !(pDoc = pFmt->GetDoc())->IsInDtor() && pFmt->IsLastDepend() )
72cdf0e10cSrcweir 	{
73cdf0e10cSrcweir 		//Ich bin der einzige, weg mit dem Format.
74cdf0e10cSrcweir 		//Vorher ummelden, damit die Basisklasse noch klarkommt.
75cdf0e10cSrcweir 		pDoc->GetDfltFrmFmt()->Add( this );
76cdf0e10cSrcweir 		pDoc->DelFrmFmt( pFmt );
77cdf0e10cSrcweir 	}
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir /*************************************************************************
81cdf0e10cSrcweir |*
82cdf0e10cSrcweir |*	SwLayoutFrm::ChgColumns()
83cdf0e10cSrcweir |*
84cdf0e10cSrcweir |*	Ersterstellung		MA 11. Feb. 93
85cdf0e10cSrcweir |*	Letzte Aenderung	MA 12. Oct. 98
86cdf0e10cSrcweir |*
87cdf0e10cSrcweir |*************************************************************************/
88cdf0e10cSrcweir 
lcl_RemoveColumns(SwLayoutFrm * pCont,sal_uInt16 nCnt)89cdf0e10cSrcweir void MA_FASTCALL lcl_RemoveColumns( SwLayoutFrm *pCont, sal_uInt16 nCnt )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	ASSERT( pCont && pCont->Lower() && pCont->Lower()->IsColumnFrm(),
92cdf0e10cSrcweir 			"Keine Spalten zu entfernen." );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	SwColumnFrm *pColumn = (SwColumnFrm*)pCont->Lower();
95cdf0e10cSrcweir 	::lcl_RemoveFtns( pColumn, sal_True, sal_True );
96cdf0e10cSrcweir 	while ( pColumn->GetNext() )
97cdf0e10cSrcweir 	{
98cdf0e10cSrcweir 		ASSERT( pColumn->GetNext()->IsColumnFrm(),
99cdf0e10cSrcweir 				"Nachbar von ColFrm kein ColFrm." );
100cdf0e10cSrcweir 		pColumn = (SwColumnFrm*)pColumn->GetNext();
101cdf0e10cSrcweir 	}
102cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < nCnt; ++i )
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir 		SwColumnFrm *pTmp = (SwColumnFrm*)pColumn->GetPrev();
105cdf0e10cSrcweir 		pColumn->Cut();
106cdf0e10cSrcweir 		delete pColumn;	//Format wird ggf. im DTor mit vernichtet.
107cdf0e10cSrcweir 		pColumn = pTmp;
108cdf0e10cSrcweir 	}
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
lcl_FindColumns(SwLayoutFrm * pLay,sal_uInt16 nCount)111cdf0e10cSrcweir SwLayoutFrm * MA_FASTCALL lcl_FindColumns( SwLayoutFrm *pLay, sal_uInt16 nCount )
112cdf0e10cSrcweir {
113cdf0e10cSrcweir 	SwFrm *pCol = pLay->Lower();
114cdf0e10cSrcweir 	if ( pLay->IsPageFrm() )
115cdf0e10cSrcweir 		pCol = ((SwPageFrm*)pLay)->FindBodyCont()->Lower();
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 	if ( pCol && pCol->IsColumnFrm() )
118cdf0e10cSrcweir 	{
119cdf0e10cSrcweir 		SwFrm *pTmp = pCol;
120cdf0e10cSrcweir 		sal_uInt16 i;
121cdf0e10cSrcweir 		for ( i = 0; pTmp; pTmp = pTmp->GetNext(), ++i )
122cdf0e10cSrcweir 			/* do nothing */;
123cdf0e10cSrcweir 		return i == nCount ? (SwLayoutFrm*)pCol : 0;
124cdf0e10cSrcweir 	}
125cdf0e10cSrcweir 	return 0;
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 
lcl_AddColumns(SwLayoutFrm * pCont,sal_uInt16 nCount)129cdf0e10cSrcweir static sal_Bool lcl_AddColumns( SwLayoutFrm *pCont, sal_uInt16 nCount )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	SwDoc *pDoc = pCont->GetFmt()->GetDoc();
132cdf0e10cSrcweir 	const sal_Bool bMod = pDoc->IsModified();
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	//Format sollen soweit moeglich geshared werden. Wenn es also schon einen
135cdf0e10cSrcweir 	//Nachbarn mit den selben Spalteneinstellungen gibt, so koennen die
136cdf0e10cSrcweir 	//Spalten an die selben Formate gehaengt werden.
137cdf0e10cSrcweir 	//Der Nachbar kann ueber das Format gesucht werden, wer der Owner des Attributes
138cdf0e10cSrcweir 	//ist, ist allerdings vom Frametyp abhaengig.
139cdf0e10cSrcweir 	SwLayoutFrm *pAttrOwner = pCont;
140cdf0e10cSrcweir 	if ( pCont->IsBodyFrm() )
141cdf0e10cSrcweir 		pAttrOwner = pCont->FindPageFrm();
142cdf0e10cSrcweir 	SwLayoutFrm *pNeighbourCol = 0;
143cdf0e10cSrcweir 	SwIterator<SwLayoutFrm,SwFmt> aIter( *pAttrOwner->GetFmt() );
144cdf0e10cSrcweir 	SwLayoutFrm *pNeighbour = aIter.First();
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 	sal_uInt16 nAdd = 0;
147cdf0e10cSrcweir 	SwFrm *pCol = pCont->Lower();
148cdf0e10cSrcweir 	if ( pCol && pCol->IsColumnFrm() )
149cdf0e10cSrcweir 		for ( nAdd = 1; pCol; pCol = pCol->GetNext(), ++nAdd )
150cdf0e10cSrcweir 			/* do nothing */;
151cdf0e10cSrcweir 	while ( pNeighbour )
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		if ( 0 != (pNeighbourCol = lcl_FindColumns( pNeighbour, nCount+nAdd )) &&
154cdf0e10cSrcweir 			 pNeighbourCol != pCont )
155cdf0e10cSrcweir 			break;
156cdf0e10cSrcweir 		pNeighbourCol = 0;
157cdf0e10cSrcweir 		pNeighbour = aIter.Next();
158cdf0e10cSrcweir 	}
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	sal_Bool bRet;
161cdf0e10cSrcweir 	SwTwips nMax = pCont->IsPageBodyFrm() ?
162cdf0e10cSrcweir 				   pCont->FindPageFrm()->GetMaxFtnHeight() : LONG_MAX;
163cdf0e10cSrcweir 	if ( pNeighbourCol )
164cdf0e10cSrcweir 	{
165cdf0e10cSrcweir 		bRet = sal_False;
166cdf0e10cSrcweir 		SwFrm *pTmp = pCont->Lower();
167cdf0e10cSrcweir 		while ( pTmp )
168cdf0e10cSrcweir 		{
169cdf0e10cSrcweir 			pTmp = pTmp->GetNext();
170cdf0e10cSrcweir 			pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext();
171cdf0e10cSrcweir 		}
172cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < nCount; ++i )
173cdf0e10cSrcweir 		{
174cdf0e10cSrcweir             SwColumnFrm *pTmpCol = new SwColumnFrm( pNeighbourCol->GetFmt(), pCont );
175cdf0e10cSrcweir             pTmpCol->SetMaxFtnHeight( nMax );
176cdf0e10cSrcweir             pTmpCol->InsertBefore( pCont, NULL );
177cdf0e10cSrcweir 			pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext();
178cdf0e10cSrcweir 		}
179cdf0e10cSrcweir 	}
180cdf0e10cSrcweir 	else
181cdf0e10cSrcweir 	{
182cdf0e10cSrcweir 		bRet = sal_True;
183cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < nCount; ++i )
184cdf0e10cSrcweir 		{
185cdf0e10cSrcweir 			SwFrmFmt *pFmt = pDoc->MakeFrmFmt( aEmptyStr, pDoc->GetDfltFrmFmt());
186cdf0e10cSrcweir 			SwColumnFrm *pTmp = new SwColumnFrm( pFmt, pCont );
187cdf0e10cSrcweir 			pTmp->SetMaxFtnHeight( nMax );
188cdf0e10cSrcweir 			pTmp->Paste( pCont );
189cdf0e10cSrcweir 		}
190cdf0e10cSrcweir 	}
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 	if ( !bMod )
193cdf0e10cSrcweir 		pDoc->ResetModified();
194cdf0e10cSrcweir 	return bRet;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir /*-----------------21.09.99 15:42-------------------
198cdf0e10cSrcweir  * ChgColumns() adds or removes columns from a layoutframe.
199cdf0e10cSrcweir  * Normally, a layoutframe with a column attribut of 1 or 0 columns contains
200cdf0e10cSrcweir  * no columnframe. However, a sectionframe with "footnotes at the end" needs
201cdf0e10cSrcweir  * a columnframe. If the bChgFtn-flag is set, the columnframe will be inserted
202cdf0e10cSrcweir  * or remove, if necessary.
203cdf0e10cSrcweir  * --------------------------------------------------*/
204cdf0e10cSrcweir 
ChgColumns(const SwFmtCol & rOld,const SwFmtCol & rNew,const sal_Bool bChgFtn)205cdf0e10cSrcweir void SwLayoutFrm::ChgColumns( const SwFmtCol &rOld, const SwFmtCol &rNew,
206cdf0e10cSrcweir 	const sal_Bool bChgFtn )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir 	if ( rOld.GetNumCols() <= 1 && rNew.GetNumCols() <= 1 && !bChgFtn )
209cdf0e10cSrcweir 		return;
210cdf0e10cSrcweir     // --> OD 2009-08-12 #i97379#
211cdf0e10cSrcweir     // If current lower is a no text frame, then columns are not allowed
212cdf0e10cSrcweir     if ( Lower() && Lower()->IsNoTxtFrm() &&
213cdf0e10cSrcweir          rNew.GetNumCols() > 1 )
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         return;
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir     // <--
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 	sal_uInt16 nNewNum,	nOldNum = 1;
220cdf0e10cSrcweir 	if( Lower() && Lower()->IsColumnFrm() )
221cdf0e10cSrcweir 	{
222cdf0e10cSrcweir 		SwFrm* pCol = Lower();
223cdf0e10cSrcweir 		while( 0 != (pCol=pCol->GetNext()) )
224cdf0e10cSrcweir 			++nOldNum;
225cdf0e10cSrcweir 	}
226cdf0e10cSrcweir 	nNewNum = rNew.GetNumCols();
227cdf0e10cSrcweir 	if( !nNewNum )
228cdf0e10cSrcweir 		++nNewNum;
229cdf0e10cSrcweir 	sal_Bool bAtEnd;
230cdf0e10cSrcweir 	if( IsSctFrm() )
231cdf0e10cSrcweir 		bAtEnd = ((SwSectionFrm*)this)->IsAnyNoteAtEnd();
232cdf0e10cSrcweir 	else
233cdf0e10cSrcweir 		bAtEnd = sal_False;
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 	//Einstellung der Spaltenbreiten ist nur bei neuen Formaten notwendig.
236cdf0e10cSrcweir 	sal_Bool bAdjustAttributes = nOldNum != rOld.GetNumCols();
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 	//Wenn die Spaltenanzahl unterschiedlich ist, wird der Inhalt
239cdf0e10cSrcweir 	//gesichert und restored.
240cdf0e10cSrcweir 	SwFrm *pSave = 0;
241cdf0e10cSrcweir 	if( nOldNum != nNewNum || bChgFtn )
242cdf0e10cSrcweir 	{
243cdf0e10cSrcweir 		SwDoc *pDoc = GetFmt()->GetDoc();
244cdf0e10cSrcweir 		ASSERT( pDoc, "FrmFmt gibt kein Dokument her." );
245cdf0e10cSrcweir 		// SaveCntnt wuerde auch den Inhalt der Fussnotencontainer aufsaugen
246cdf0e10cSrcweir 		// und im normalen Textfluss unterbringen.
247cdf0e10cSrcweir 		if( IsPageBodyFrm() )
248cdf0e10cSrcweir 			pDoc->GetCurrentLayout()->RemoveFtns( (SwPageFrm*)GetUpper(), sal_True, sal_False );	//swmod 080218
249cdf0e10cSrcweir 		pSave = ::SaveCntnt( this );
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 		//Wenn Spalten existieren, jetzt aber eine Spaltenanzahl von
252cdf0e10cSrcweir 		//0 oder eins gewuenscht ist, so werden die Spalten einfach vernichtet.
253cdf0e10cSrcweir 		if ( nNewNum == 1 && !bAtEnd )
254cdf0e10cSrcweir 		{
255cdf0e10cSrcweir 			::lcl_RemoveColumns( this, nOldNum );
256cdf0e10cSrcweir 			if ( IsBodyFrm() )
257cdf0e10cSrcweir 				SetFrmFmt( pDoc->GetDfltFrmFmt() );
258cdf0e10cSrcweir 			else
259cdf0e10cSrcweir                 GetFmt()->SetFmtAttr( SwFmtFillOrder() );
260cdf0e10cSrcweir 			if ( pSave )
261cdf0e10cSrcweir                 ::RestoreCntnt( pSave, this, 0, true );
262cdf0e10cSrcweir             return;
263cdf0e10cSrcweir 		}
264cdf0e10cSrcweir 		if ( nOldNum == 1 )
265cdf0e10cSrcweir 		{
266cdf0e10cSrcweir 			if ( IsBodyFrm() )
267cdf0e10cSrcweir 				SetFrmFmt( pDoc->GetColumnContFmt() );
268cdf0e10cSrcweir 			else
269cdf0e10cSrcweir                 GetFmt()->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) );
270cdf0e10cSrcweir 			if( !Lower() || !Lower()->IsColumnFrm() )
271cdf0e10cSrcweir 				--nOldNum;
272cdf0e10cSrcweir 		}
273cdf0e10cSrcweir 		if ( nOldNum > nNewNum )
274cdf0e10cSrcweir 		{
275cdf0e10cSrcweir 			::lcl_RemoveColumns( this, nOldNum - nNewNum );
276cdf0e10cSrcweir 			bAdjustAttributes = sal_True;
277cdf0e10cSrcweir 		}
278cdf0e10cSrcweir 		else if( nOldNum < nNewNum )
279cdf0e10cSrcweir 		{
280cdf0e10cSrcweir 			sal_uInt16 nAdd = nNewNum - nOldNum;
281cdf0e10cSrcweir 			bAdjustAttributes = lcl_AddColumns( this, nAdd );
282cdf0e10cSrcweir 		}
283cdf0e10cSrcweir 	}
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	if ( !bAdjustAttributes )
286cdf0e10cSrcweir 	{
287cdf0e10cSrcweir 		if ( rOld.GetLineWidth() 	!= rNew.GetLineWidth() ||
288cdf0e10cSrcweir 			 rOld.GetWishWidth()  	!= rNew.GetWishWidth() ||
289cdf0e10cSrcweir 			 rOld.IsOrtho()			!= rNew.IsOrtho() )
290cdf0e10cSrcweir 			bAdjustAttributes = sal_True;
291cdf0e10cSrcweir 		else
292cdf0e10cSrcweir 		{
293cdf0e10cSrcweir 			sal_uInt16 nCount = Min( rNew.GetColumns().Count(), rOld.GetColumns().Count() );
294cdf0e10cSrcweir 			for ( sal_uInt16 i = 0; i < nCount; ++i )
295cdf0e10cSrcweir 				if ( !(*rOld.GetColumns()[i] == *rNew.GetColumns()[i]) )
296cdf0e10cSrcweir 				{
297cdf0e10cSrcweir 					bAdjustAttributes = sal_True;
298cdf0e10cSrcweir 					break;
299cdf0e10cSrcweir 				}
300cdf0e10cSrcweir 		}
301cdf0e10cSrcweir 	}
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 	//Sodele, jetzt koennen die Spalten bequem eingestellt werden.
304cdf0e10cSrcweir 	AdjustColumns( &rNew, bAdjustAttributes );
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 	//Erst jetzt den Inhalt restaurieren. Ein frueheres Restaurieren wuerde
307cdf0e10cSrcweir 	//unnuetzte Aktionen beim Einstellen zur Folge haben.
308cdf0e10cSrcweir 	if ( pSave )
309cdf0e10cSrcweir 	{
310cdf0e10cSrcweir 		ASSERT( Lower() && Lower()->IsLayoutFrm() &&
311cdf0e10cSrcweir 				((SwLayoutFrm*)Lower())->Lower() &&
312cdf0e10cSrcweir 				((SwLayoutFrm*)Lower())->Lower()->IsLayoutFrm(),
313cdf0e10cSrcweir 				"Gesucht: Spaltenbody (Tod oder Lebend)." );   // ColumnFrms jetzt mit BodyFrm
314cdf0e10cSrcweir         ::RestoreCntnt( pSave, (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower(), 0, true );
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir /*************************************************************************
319cdf0e10cSrcweir |*
320cdf0e10cSrcweir |*	SwLayoutFrm::AdjustColumns()
321cdf0e10cSrcweir |*
322cdf0e10cSrcweir |*	Ersterstellung		MA 19. Jan. 99
323cdf0e10cSrcweir |*	Letzte Aenderung	MA 19. Jan. 99
324cdf0e10cSrcweir |*
325cdf0e10cSrcweir |*************************************************************************/
326cdf0e10cSrcweir 
AdjustColumns(const SwFmtCol * pAttr,sal_Bool bAdjustAttributes)327cdf0e10cSrcweir void SwLayoutFrm::AdjustColumns( const SwFmtCol *pAttr, sal_Bool bAdjustAttributes )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir 	if( !Lower()->GetNext() )
330cdf0e10cSrcweir 	{
331cdf0e10cSrcweir 		Lower()->ChgSize( Prt().SSize() );
332cdf0e10cSrcweir 		return;
333cdf0e10cSrcweir 	}
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     const sal_Bool bVert = IsVertical();
336cdf0e10cSrcweir     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
337cdf0e10cSrcweir 	SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 	//Ist ein Pointer da, oder sollen wir die Attribute einstellen,
340cdf0e10cSrcweir 	//so stellen wir auf jeden Fall die Spaltenbreiten ein. Andernfalls
341cdf0e10cSrcweir 	//checken wir, ob eine Einstellung notwendig ist.
342cdf0e10cSrcweir 	if ( !pAttr )
343cdf0e10cSrcweir 	{
344cdf0e10cSrcweir 		pAttr = &GetFmt()->GetCol();
345cdf0e10cSrcweir 		if ( !bAdjustAttributes )
346cdf0e10cSrcweir 		{
347cdf0e10cSrcweir             long nAvail = (Prt().*fnRect->fnGetWidth)();
348cdf0e10cSrcweir 			for ( SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
349cdf0e10cSrcweir 				  pCol;
350cdf0e10cSrcweir 				  pCol = (SwLayoutFrm*)pCol->GetNext() )
351cdf0e10cSrcweir                 nAvail -= (pCol->Frm().*fnRect->fnGetWidth)();
352cdf0e10cSrcweir 			if ( !nAvail )
353cdf0e10cSrcweir 				return;
354cdf0e10cSrcweir 		}
355cdf0e10cSrcweir 	}
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 	//Sodele, jetzt koennen die Spalten bequem eingestellt werden.
358cdf0e10cSrcweir 	//Die Breiten werden mitgezaehlt, damit wir dem letzten den Rest geben
359cdf0e10cSrcweir 	//koennen.
360cdf0e10cSrcweir     SwTwips nAvail = (Prt().*fnRect->fnGetWidth)();
361cdf0e10cSrcweir     const sal_Bool bLine = pAttr->GetLineAdj() != COLADJ_NONE;
362cdf0e10cSrcweir     const sal_uInt16 nMin = bLine ? sal_uInt16( 20 + ( pAttr->GetLineWidth() / 2) ) : 0;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir     const sal_Bool bR2L = IsRightToLeft();
365cdf0e10cSrcweir     SwFrm *pCol = bR2L ? GetLastLower() : Lower();
366cdf0e10cSrcweir 
367cdf0e10cSrcweir     // --> FME 2004-07-16 #i27399#
368cdf0e10cSrcweir     // bOrtho means we have to adjust the column frames manually. Otherwise
369cdf0e10cSrcweir     // we may use the values returned by CalcColWidth:
370cdf0e10cSrcweir     const sal_Bool bOrtho = pAttr->IsOrtho() && pAttr->GetNumCols() > 0;
371cdf0e10cSrcweir     long nGutter = 0;
372cdf0e10cSrcweir     // <--
373cdf0e10cSrcweir 
374*d1af8f7dSYong Lin Ma     for ( sal_uInt16 i = 0; i < pAttr->GetNumCols() && pCol; ++i ) //i118878, value returned by GetNumCols() can't be trusted
375cdf0e10cSrcweir 	{
376cdf0e10cSrcweir         if( !bOrtho )
377cdf0e10cSrcweir         {
378cdf0e10cSrcweir             const SwTwips nWidth = i == (pAttr->GetNumCols() - 1) ?
379cdf0e10cSrcweir                                    nAvail :
380cdf0e10cSrcweir                                    pAttr->CalcColWidth( i, sal_uInt16( (Prt().*fnRect->fnGetWidth)() ) );
381cdf0e10cSrcweir 
382cdf0e10cSrcweir             const Size aColSz = bVert ?
383cdf0e10cSrcweir                                 Size( Prt().Width(), nWidth ) :
384cdf0e10cSrcweir                                 Size( nWidth, Prt().Height() );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir             pCol->ChgSize( aColSz );
387cdf0e10cSrcweir 
388cdf0e10cSrcweir             // Hierdurch werden die ColumnBodyFrms von Seitenspalten angepasst und
389cdf0e10cSrcweir             // ihr bFixHeight-Flag wird gesetzt, damit sie nicht schrumpfen/wachsen.
390cdf0e10cSrcweir             // Bei Rahmenspalten hingegen soll das Flag _nicht_ gesetzt werden,
391cdf0e10cSrcweir             // da BodyFrms in Rahmenspalten durchaus wachsen/schrumpfen duerfen.
392cdf0e10cSrcweir             if( IsBodyFrm() )
393cdf0e10cSrcweir                 ((SwLayoutFrm*)pCol)->Lower()->ChgSize( aColSz );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir             nAvail -= nWidth;
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         if ( bOrtho || bAdjustAttributes )
399cdf0e10cSrcweir 		{
400cdf0e10cSrcweir             const SwColumn *pC = pAttr->GetColumns()[i];
401cdf0e10cSrcweir             const SwAttrSet* pSet = pCol->GetAttrSet();
402cdf0e10cSrcweir 			SvxLRSpaceItem aLR( pSet->GetLRSpace() );
403cdf0e10cSrcweir 
404cdf0e10cSrcweir             //Damit die Trennlinien Platz finden, muessen sie hier
405cdf0e10cSrcweir 			//Beruecksichtigung finden. Ueberall wo zwei Spalten aufeinanderstossen
406cdf0e10cSrcweir 			//wird jeweils rechts bzw. links ein Sicherheitsabstand von 20 plus
407cdf0e10cSrcweir 			//der halben Penbreite einkalkuliert.
408cdf0e10cSrcweir             const sal_uInt16 nLeft = pC->GetLeft();
409cdf0e10cSrcweir             const sal_uInt16 nRight = pC->GetRight();
410cdf0e10cSrcweir 
411cdf0e10cSrcweir             aLR.SetLeft ( nLeft );
412cdf0e10cSrcweir             aLR.SetRight( nRight );
413cdf0e10cSrcweir 
414cdf0e10cSrcweir             if ( bLine )
415cdf0e10cSrcweir             {
416cdf0e10cSrcweir                 if ( i == 0 )
417cdf0e10cSrcweir                 {
418cdf0e10cSrcweir                     aLR.SetRight( Max( nRight, nMin ) );
419cdf0e10cSrcweir                 }
420cdf0e10cSrcweir                 else if ( i == pAttr->GetNumCols() - 1 )
421cdf0e10cSrcweir                 {
422cdf0e10cSrcweir                     aLR.SetLeft ( Max( nLeft, nMin ) );
423cdf0e10cSrcweir                 }
424cdf0e10cSrcweir                 else
425cdf0e10cSrcweir                 {
426cdf0e10cSrcweir                     aLR.SetLeft ( Max( nLeft,  nMin ) );
427cdf0e10cSrcweir                     aLR.SetRight( Max( nRight, nMin ) );
428cdf0e10cSrcweir                 }
429cdf0e10cSrcweir             }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir             if ( bAdjustAttributes )
432cdf0e10cSrcweir             {
433cdf0e10cSrcweir     			SvxULSpaceItem aUL( pSet->GetULSpace() );
434cdf0e10cSrcweir                 aUL.SetUpper( pC->GetUpper());
435cdf0e10cSrcweir                 aUL.SetLower( pC->GetLower());
436cdf0e10cSrcweir 
437cdf0e10cSrcweir                 ((SwLayoutFrm*)pCol)->GetFmt()->SetFmtAttr( aLR );
438cdf0e10cSrcweir                 ((SwLayoutFrm*)pCol)->GetFmt()->SetFmtAttr( aUL );
439cdf0e10cSrcweir             }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir             nGutter += aLR.GetLeft() + aLR.GetRight();
442cdf0e10cSrcweir 		}
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         pCol = bR2L ? pCol->GetPrev() : pCol->GetNext();
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     if( bOrtho )
448cdf0e10cSrcweir     {
449cdf0e10cSrcweir         long nInnerWidth = ( nAvail - nGutter ) / pAttr->GetNumCols();
450cdf0e10cSrcweir         pCol = Lower();
451*d1af8f7dSYong Lin Ma         for( sal_uInt16 i = 0; i < pAttr->GetNumCols() && pCol; pCol = pCol->GetNext(), ++i ) //i118878, value returned by GetNumCols() can't be trusted
452cdf0e10cSrcweir         {
453cdf0e10cSrcweir             SwTwips nWidth;
454cdf0e10cSrcweir             if ( i == pAttr->GetNumCols() - 1 )
455cdf0e10cSrcweir                 nWidth = nAvail;
456cdf0e10cSrcweir             else
457cdf0e10cSrcweir             {
458cdf0e10cSrcweir                 SvxLRSpaceItem aLR( pCol->GetAttrSet()->GetLRSpace() );
459cdf0e10cSrcweir                 nWidth = nInnerWidth + aLR.GetLeft() + aLR.GetRight();
460cdf0e10cSrcweir             }
461cdf0e10cSrcweir             if( nWidth < 0 )
462cdf0e10cSrcweir                 nWidth = 0;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir             const Size aColSz = bVert ?
465cdf0e10cSrcweir                                 Size( Prt().Width(), nWidth ) :
466cdf0e10cSrcweir                                 Size( nWidth, Prt().Height() );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir             pCol->ChgSize( aColSz );
469cdf0e10cSrcweir 
470cdf0e10cSrcweir             if( IsBodyFrm() )
471cdf0e10cSrcweir                 ((SwLayoutFrm*)pCol)->Lower()->ChgSize( aColSz );
472cdf0e10cSrcweir 
473cdf0e10cSrcweir             nAvail -= nWidth;
474cdf0e10cSrcweir         }
475cdf0e10cSrcweir     }
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 
482