xref: /aoo41x/main/sw/source/core/docnode/ndtbl.cxx (revision efeef26f)
1*efeef26fSAndrew Rist /**************************************************************
2*efeef26fSAndrew Rist  *
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
10*efeef26fSAndrew Rist  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*efeef26fSAndrew Rist  *
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 
23*efeef26fSAndrew Rist 
24cdf0e10cSrcweir 
25cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
26cdf0e10cSrcweir #include "precompiled_sw.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <com/sun/star/chart2/XChartDocument.hpp>
29cdf0e10cSrcweir #include <hintids.hxx>
30cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
31cdf0e10cSrcweir #include <editeng/brkitem.hxx>
32cdf0e10cSrcweir #include <editeng/protitem.hxx>
33cdf0e10cSrcweir #include <editeng/boxitem.hxx>
34cdf0e10cSrcweir #include <editeng/shaditem.hxx>
35cdf0e10cSrcweir #include <fmtfsize.hxx>
36cdf0e10cSrcweir #include <fmtornt.hxx>
37cdf0e10cSrcweir #include <fmtfordr.hxx>
38cdf0e10cSrcweir #include <fmtpdsc.hxx>
39cdf0e10cSrcweir #include <fmtanchr.hxx>
40cdf0e10cSrcweir #include <fmtlsplt.hxx>
41cdf0e10cSrcweir #include <frmatr.hxx>
42cdf0e10cSrcweir #include <charatr.hxx>
43cdf0e10cSrcweir #include <cellfrm.hxx>
44cdf0e10cSrcweir #include <pagefrm.hxx>
45cdf0e10cSrcweir #include <tabcol.hxx>
46cdf0e10cSrcweir #include <doc.hxx>
47cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
48cdf0e10cSrcweir #include <UndoManager.hxx>
49cdf0e10cSrcweir #include <cntfrm.hxx>
50cdf0e10cSrcweir #include <pam.hxx>
51cdf0e10cSrcweir #include <swcrsr.hxx>
52cdf0e10cSrcweir #include <viscrs.hxx>
53cdf0e10cSrcweir #include <swtable.hxx>
54cdf0e10cSrcweir #include <ndtxt.hxx>
55cdf0e10cSrcweir #include <swundo.hxx>
56cdf0e10cSrcweir #include <tblsel.hxx>
57cdf0e10cSrcweir #include <fldbas.hxx>
58cdf0e10cSrcweir #include <poolfmt.hxx>
59cdf0e10cSrcweir #include <tabfrm.hxx>
60cdf0e10cSrcweir #include <UndoCore.hxx>
61cdf0e10cSrcweir #include <UndoRedline.hxx>
62cdf0e10cSrcweir #include <UndoDelete.hxx>
63cdf0e10cSrcweir #include <UndoTable.hxx>
64cdf0e10cSrcweir #include <hints.hxx>
65cdf0e10cSrcweir #include <tblafmt.hxx>
66cdf0e10cSrcweir #include <swcache.hxx>
67cdf0e10cSrcweir #include <ddefld.hxx>
68cdf0e10cSrcweir #include <frminf.hxx>
69cdf0e10cSrcweir #include <cellatr.hxx>
70cdf0e10cSrcweir #include <swtblfmt.hxx>
71cdf0e10cSrcweir #include <swddetbl.hxx>
72cdf0e10cSrcweir #include <mvsave.hxx>
73cdf0e10cSrcweir #include <docary.hxx>
74cdf0e10cSrcweir #include <redline.hxx>
75cdf0e10cSrcweir #include <rolbck.hxx>
76cdf0e10cSrcweir #include <tblrwcl.hxx>
77cdf0e10cSrcweir #include <editsh.hxx>
78cdf0e10cSrcweir #include <txtfrm.hxx>
79cdf0e10cSrcweir #include <ftnfrm.hxx>
80cdf0e10cSrcweir #include <section.hxx>
81cdf0e10cSrcweir #include <frmtool.hxx>
82cdf0e10cSrcweir #include <node2lay.hxx>
83cdf0e10cSrcweir #include <comcore.hrc>
84cdf0e10cSrcweir #include "docsh.hxx"
85cdf0e10cSrcweir #include <tabcol.hxx>
86cdf0e10cSrcweir #include <unochart.hxx>
87cdf0e10cSrcweir #include <node.hxx>
88cdf0e10cSrcweir #include <ndtxt.hxx>
89cdf0e10cSrcweir #include <map>
90cdf0e10cSrcweir #include <algorithm>
91cdf0e10cSrcweir #include <rootfrm.hxx>
92cdf0e10cSrcweir #include <fldupde.hxx>
93cdf0e10cSrcweir #include <switerator.hxx>
94cdf0e10cSrcweir 
95cdf0e10cSrcweir #ifndef DBG_UTIL
96cdf0e10cSrcweir #define CHECK_TABLE(t)
97cdf0e10cSrcweir #else
98cdf0e10cSrcweir #ifdef DEBUG
99cdf0e10cSrcweir #define CHECK_TABLE(t) (t).CheckConsistency();
100cdf0e10cSrcweir #else
101cdf0e10cSrcweir #define CHECK_TABLE(t)
102cdf0e10cSrcweir #endif
103cdf0e10cSrcweir #endif
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 
106cdf0e10cSrcweir using namespace ::com::sun::star;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir // #i17764# delete table redlines when modifying the table structure?
109cdf0e10cSrcweir // #define DEL_TABLE_REDLINES 1
110cdf0e10cSrcweir 
111cdf0e10cSrcweir const sal_Unicode T2T_PARA = 0x0a;
112cdf0e10cSrcweir 
113cdf0e10cSrcweir extern void ClearFEShellTabCols();
114cdf0e10cSrcweir 
115cdf0e10cSrcweir // steht im gctable.cxx
116cdf0e10cSrcweir extern sal_Bool lcl_GC_Line_Border( const SwTableLine*& , void* pPara );
117cdf0e10cSrcweir 
118cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
119cdf0e10cSrcweir class lcl_DelRedlines
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	SwDoc* pDoc;
122cdf0e10cSrcweir public:
123cdf0e10cSrcweir 	lcl_DelRedlines( const SwTableNode& rNd, sal_Bool bCheckForOwnRedline );
124cdf0e10cSrcweir 	lcl_DelRedlines( SwPaM& rPam );
125cdf0e10cSrcweir 
~lcl_DelRedlines()126cdf0e10cSrcweir     ~lcl_DelRedlines() { pDoc->EndUndo(UNDO_EMPTY, NULL); }
127cdf0e10cSrcweir };
128cdf0e10cSrcweir 
lcl_DelRedlines(SwPaM & rPam)129cdf0e10cSrcweir lcl_DelRedlines::lcl_DelRedlines( SwPaM & rPam) : pDoc( rPam.GetDoc() )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir     pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
132cdf0e10cSrcweir 	if( !pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() )
133cdf0e10cSrcweir 		pDoc->AcceptRedline( rPam, true );
134cdf0e10cSrcweir }
135cdf0e10cSrcweir #endif
136cdf0e10cSrcweir 
lcl_SetDfltBoxAttr(SwFrmFmt & rFmt,sal_uInt8 nId)137cdf0e10cSrcweir void lcl_SetDfltBoxAttr( SwFrmFmt& rFmt, sal_uInt8 nId )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	sal_Bool bTop = sal_False, bBottom = sal_False, bLeft = sal_False, bRight = sal_False;
140cdf0e10cSrcweir 	switch ( nId )
141cdf0e10cSrcweir 	{
142cdf0e10cSrcweir 	case 0:	bTop = bBottom = bLeft = sal_True; 			break;
143cdf0e10cSrcweir 	case 1:	bTop = bBottom = bLeft = bRight = sal_True;	break;
144cdf0e10cSrcweir 	case 2:	bBottom = bLeft = sal_True; 				break;
145cdf0e10cSrcweir 	case 3: bBottom = bLeft = bRight = sal_True; 		break;
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     const sal_Bool bHTML = rFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE);
149cdf0e10cSrcweir 	Color aCol( bHTML ? COL_GRAY : COL_BLACK );
150cdf0e10cSrcweir 	SvxBorderLine aLine( &aCol, DEF_LINE_WIDTH_0 );
151cdf0e10cSrcweir 	if ( bHTML )
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		aLine.SetOutWidth( DEF_DOUBLE_LINE7_OUT );
154cdf0e10cSrcweir 		aLine.SetInWidth ( DEF_DOUBLE_LINE7_IN  );
155cdf0e10cSrcweir 		aLine.SetDistance( DEF_DOUBLE_LINE7_DIST);
156cdf0e10cSrcweir 	}
157cdf0e10cSrcweir     SvxBoxItem aBox(RES_BOX); aBox.SetDistance( 55 );
158cdf0e10cSrcweir 	if ( bTop )
159cdf0e10cSrcweir 		aBox.SetLine( &aLine, BOX_LINE_TOP );
160cdf0e10cSrcweir 	if ( bBottom )
161cdf0e10cSrcweir 		aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
162cdf0e10cSrcweir 	if ( bLeft )
163cdf0e10cSrcweir 		aBox.SetLine( &aLine, BOX_LINE_LEFT );
164cdf0e10cSrcweir 	if ( bRight )
165cdf0e10cSrcweir 		aBox.SetLine( &aLine, BOX_LINE_RIGHT );
166cdf0e10cSrcweir     rFmt.SetFmtAttr( aBox );
167cdf0e10cSrcweir }
168cdf0e10cSrcweir 
lcl_SetDfltBoxAttr(SwTableBox & rBox,SvPtrarr & rBoxFmtArr,sal_uInt8 nId,const SwTableAutoFmt * pAutoFmt=0)169cdf0e10cSrcweir void lcl_SetDfltBoxAttr( SwTableBox& rBox, SvPtrarr &rBoxFmtArr, sal_uInt8 nId,
170cdf0e10cSrcweir 							const SwTableAutoFmt* pAutoFmt = 0 )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir 	SvPtrarr* pArr = (SvPtrarr*)rBoxFmtArr[ nId ];
173cdf0e10cSrcweir 	if( !pArr )
174cdf0e10cSrcweir 	{
175cdf0e10cSrcweir 		pArr = new SvPtrarr;
176cdf0e10cSrcweir 		rBoxFmtArr.Replace( pArr, nId );
177cdf0e10cSrcweir 	}
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 	SwTableBoxFmt* pNewBoxFmt = 0;
180cdf0e10cSrcweir 	SwFrmFmt* pBoxFmt = rBox.GetFrmFmt();
181cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < pArr->Count(); n += 2 )
182cdf0e10cSrcweir 		if( pArr->GetObject( n ) == pBoxFmt )
183cdf0e10cSrcweir 		{
184cdf0e10cSrcweir 			pNewBoxFmt = (SwTableBoxFmt*)pArr->GetObject( n + 1 );
185cdf0e10cSrcweir 			break;
186cdf0e10cSrcweir 		}
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 	if( !pNewBoxFmt )
189cdf0e10cSrcweir 	{
190cdf0e10cSrcweir 		SwDoc* pDoc = pBoxFmt->GetDoc();
191cdf0e10cSrcweir 		// das Format ist also nicht vorhanden, also neu erzeugen
192cdf0e10cSrcweir 		pNewBoxFmt = pDoc->MakeTableBoxFmt();
193cdf0e10cSrcweir         pNewBoxFmt->SetFmtAttr( pBoxFmt->GetAttrSet().Get( RES_FRM_SIZE ) );
194cdf0e10cSrcweir 
195cdf0e10cSrcweir 		if( pAutoFmt )
196cdf0e10cSrcweir 			pAutoFmt->UpdateToSet( nId, (SfxItemSet&)pNewBoxFmt->GetAttrSet(),
197cdf0e10cSrcweir 									SwTableAutoFmt::UPDATE_BOX,
198cdf0e10cSrcweir 									pDoc->GetNumberFormatter( sal_True ) );
199cdf0e10cSrcweir 		else
200cdf0e10cSrcweir 			::lcl_SetDfltBoxAttr( *pNewBoxFmt, nId );
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 		void* p = pBoxFmt;
203cdf0e10cSrcweir 		pArr->Insert( p, pArr->Count() );
204cdf0e10cSrcweir 		p = pNewBoxFmt;
205cdf0e10cSrcweir 		pArr->Insert( p, pArr->Count() );
206cdf0e10cSrcweir 	}
207cdf0e10cSrcweir 	rBox.ChgFrmFmt( pNewBoxFmt );
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
lcl_CreateDfltBoxFmt(SwDoc & rDoc,SvPtrarr & rBoxFmtArr,sal_uInt16 nCols,sal_uInt8 nId)210cdf0e10cSrcweir SwTableBoxFmt *lcl_CreateDfltBoxFmt( SwDoc &rDoc, SvPtrarr &rBoxFmtArr,
211cdf0e10cSrcweir 									sal_uInt16 nCols, sal_uInt8 nId )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	if ( !rBoxFmtArr[nId] )
214cdf0e10cSrcweir 	{
215cdf0e10cSrcweir 		SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
216cdf0e10cSrcweir 		if( USHRT_MAX != nCols )
217cdf0e10cSrcweir             pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
218cdf0e10cSrcweir 											USHRT_MAX / nCols, 0 ));
219cdf0e10cSrcweir 		::lcl_SetDfltBoxAttr( *pBoxFmt, nId );
220cdf0e10cSrcweir 		rBoxFmtArr.Replace( pBoxFmt, nId );
221cdf0e10cSrcweir 	}
222cdf0e10cSrcweir 	return (SwTableBoxFmt*)rBoxFmtArr[nId];
223cdf0e10cSrcweir }
224cdf0e10cSrcweir 
lcl_CreateAFmtBoxFmt(SwDoc & rDoc,SvPtrarr & rBoxFmtArr,const SwTableAutoFmt & rAutoFmt,sal_uInt16 nCols,sal_uInt8 nId)225cdf0e10cSrcweir SwTableBoxFmt *lcl_CreateAFmtBoxFmt( SwDoc &rDoc, SvPtrarr &rBoxFmtArr,
226cdf0e10cSrcweir 									const SwTableAutoFmt& rAutoFmt,
227cdf0e10cSrcweir 									sal_uInt16 nCols, sal_uInt8 nId )
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	if( !rBoxFmtArr[nId] )
230cdf0e10cSrcweir 	{
231cdf0e10cSrcweir 		SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
232cdf0e10cSrcweir 		rAutoFmt.UpdateToSet( nId, (SfxItemSet&)pBoxFmt->GetAttrSet(),
233cdf0e10cSrcweir 								SwTableAutoFmt::UPDATE_BOX,
234cdf0e10cSrcweir 								rDoc.GetNumberFormatter( sal_True ) );
235cdf0e10cSrcweir 		if( USHRT_MAX != nCols )
236cdf0e10cSrcweir             pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
237cdf0e10cSrcweir 											USHRT_MAX / nCols, 0 ));
238cdf0e10cSrcweir 		rBoxFmtArr.Replace( pBoxFmt, nId );
239cdf0e10cSrcweir 	}
240cdf0e10cSrcweir 	return (SwTableBoxFmt*)rBoxFmtArr[nId];
241cdf0e10cSrcweir }
242cdf0e10cSrcweir 
IsIdxInTbl(const SwNodeIndex & rIdx)243cdf0e10cSrcweir SwTableNode* SwDoc::IsIdxInTbl(const SwNodeIndex& rIdx)
244cdf0e10cSrcweir {
245cdf0e10cSrcweir 	SwTableNode* pTableNd = 0;
246cdf0e10cSrcweir 	sal_uLong nIndex = rIdx.GetIndex();
247cdf0e10cSrcweir 	do {
248cdf0e10cSrcweir 		SwNode* pNd = (SwNode*)GetNodes()[ nIndex ]->StartOfSectionNode();
249cdf0e10cSrcweir 		if( 0 != ( pTableNd = pNd->GetTableNode() ) )
250cdf0e10cSrcweir 			break;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 		nIndex = pNd->GetIndex();
253cdf0e10cSrcweir 	} while ( nIndex );
254cdf0e10cSrcweir 	return pTableNd;
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 
258cdf0e10cSrcweir // --------------- einfuegen einer neuen Box --------------
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 	// fuege in der Line, vor der InsPos eine neue Box ein.
261cdf0e10cSrcweir 
InsBoxen(SwTableNode * pTblNd,SwTableLine * pLine,SwTableBoxFmt * pBoxFmt,SwTxtFmtColl * pTxtColl,const SfxItemSet * pAutoAttr,sal_uInt16 nInsPos,sal_uInt16 nCnt)262cdf0e10cSrcweir sal_Bool SwNodes::InsBoxen( SwTableNode* pTblNd,
263cdf0e10cSrcweir 						SwTableLine* pLine,
264cdf0e10cSrcweir 						SwTableBoxFmt* pBoxFmt,
265cdf0e10cSrcweir 						SwTxtFmtColl* pTxtColl,
266cdf0e10cSrcweir                         const SfxItemSet* pAutoAttr,
267cdf0e10cSrcweir 						sal_uInt16 nInsPos,
268cdf0e10cSrcweir 						sal_uInt16 nCnt )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     if( !nCnt )
271cdf0e10cSrcweir 		return sal_False;
272cdf0e10cSrcweir 	ASSERT( pLine, "keine gueltige Zeile" );
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	// Index hinter die letzte Box der Line
275cdf0e10cSrcweir 	sal_uLong nIdxPos = 0;
276cdf0e10cSrcweir 	SwTableBox *pPrvBox = 0, *pNxtBox = 0;
277cdf0e10cSrcweir 	if( pLine->GetTabBoxes().Count() )
278cdf0e10cSrcweir 	{
279cdf0e10cSrcweir 		if( nInsPos < pLine->GetTabBoxes().Count() )
280cdf0e10cSrcweir 		{
281cdf0e10cSrcweir 			if( 0 == (pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable(),
282cdf0e10cSrcweir 							pLine->GetTabBoxes()[ nInsPos ] )))
283cdf0e10cSrcweir 				pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
284cdf0e10cSrcweir 		}
285cdf0e10cSrcweir 		else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable(),
286cdf0e10cSrcweir 							pLine->GetTabBoxes()[ nInsPos-1 ] )))
287cdf0e10cSrcweir 				pNxtBox = pLine->FindNextBox( pTblNd->GetTable() );
288cdf0e10cSrcweir 	}
289cdf0e10cSrcweir 	else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable() )))
290cdf0e10cSrcweir 		pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 	if( !pPrvBox && !pNxtBox )
293cdf0e10cSrcweir 	{
294cdf0e10cSrcweir 		sal_Bool bSetIdxPos = sal_True;
295cdf0e10cSrcweir 		if( pTblNd->GetTable().GetTabLines().Count() && !nInsPos )
296cdf0e10cSrcweir 		{
297cdf0e10cSrcweir 			const SwTableLine* pTblLn = pLine;
298cdf0e10cSrcweir 			while( pTblLn->GetUpper() )
299cdf0e10cSrcweir 				pTblLn = pTblLn->GetUpper()->GetUpper();
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 			if( pTblNd->GetTable().GetTabLines()[ 0 ] == pTblLn )
302cdf0e10cSrcweir 			{
303cdf0e10cSrcweir 				// also vor die erste Box der Tabelle
304cdf0e10cSrcweir 				while( ( pNxtBox = pLine->GetTabBoxes()[0])->GetTabLines().Count() )
305cdf0e10cSrcweir 					pLine = pNxtBox->GetTabLines()[0];
306cdf0e10cSrcweir 				nIdxPos = pNxtBox->GetSttIdx();
307cdf0e10cSrcweir 				bSetIdxPos = sal_False;
308cdf0e10cSrcweir 			}
309cdf0e10cSrcweir 		}
310cdf0e10cSrcweir 		if( bSetIdxPos )
311cdf0e10cSrcweir 			// Tabelle ohne irgendeinen Inhalt oder am Ende, also vors Ende
312cdf0e10cSrcweir 			nIdxPos = pTblNd->EndOfSectionIndex();
313cdf0e10cSrcweir 	}
314cdf0e10cSrcweir 	else if( pNxtBox )			// es gibt einen Nachfolger
315cdf0e10cSrcweir 		nIdxPos = pNxtBox->GetSttIdx();
316cdf0e10cSrcweir 	else						// es gibt einen Vorgaenger
317cdf0e10cSrcweir 		nIdxPos = pPrvBox->GetSttNd()->EndOfSectionIndex() + 1;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 	SwNodeIndex aEndIdx( *this, nIdxPos );
320cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < nCnt; ++n )
321cdf0e10cSrcweir 	{
322cdf0e10cSrcweir 		SwStartNode* pSttNd = new SwStartNode( aEndIdx, ND_STARTNODE,
323cdf0e10cSrcweir 												SwTableBoxStartNode );
324cdf0e10cSrcweir 		pSttNd->pStartOfSection = pTblNd;
325cdf0e10cSrcweir 		new SwEndNode( aEndIdx, *pSttNd );
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 		pPrvBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
328cdf0e10cSrcweir 
329cdf0e10cSrcweir         SwTableBoxes & rTabBoxes = pLine->GetTabBoxes();
330cdf0e10cSrcweir         sal_uInt16 nRealInsPos = nInsPos + n;
331cdf0e10cSrcweir         if (nRealInsPos > rTabBoxes.Count())
332cdf0e10cSrcweir             nRealInsPos = rTabBoxes.Count();
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         rTabBoxes.C40_INSERT( SwTableBox, pPrvBox, nRealInsPos );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 		//if( NO_NUMBERING == pTxtColl->GetOutlineLevel()//#outline level,zhaojianwei
337cdf0e10cSrcweir 		if( ! pTxtColl->IsAssignedToListLevelOfOutlineStyle()//<-end,zhaojianwei
338cdf0e10cSrcweir //FEATURE::CONDCOLL
339cdf0e10cSrcweir 			&& RES_CONDTXTFMTCOLL != pTxtColl->Which()
340cdf0e10cSrcweir //FEATURE::CONDCOLL
341cdf0e10cSrcweir 		)
342cdf0e10cSrcweir 			new SwTxtNode( SwNodeIndex( *pSttNd->EndOfSectionNode() ),
343cdf0e10cSrcweir 								pTxtColl, pAutoAttr );
344cdf0e10cSrcweir 		else
345cdf0e10cSrcweir 		{
346cdf0e10cSrcweir 			// Outline-Numerierung richtig behandeln !!!
347cdf0e10cSrcweir 			SwTxtNode* pTNd = new SwTxtNode(
348cdf0e10cSrcweir 							SwNodeIndex( *pSttNd->EndOfSectionNode() ),
349cdf0e10cSrcweir 							(SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl(),
350cdf0e10cSrcweir 							pAutoAttr );
351cdf0e10cSrcweir 			pTNd->ChgFmtColl( pTxtColl );
352cdf0e10cSrcweir 		}
353cdf0e10cSrcweir 	}
354cdf0e10cSrcweir 	return sal_True;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir // --------------- einfuegen einer neuen Tabelle --------------
358cdf0e10cSrcweir 
InsertTable(const SwInsertTableOptions & rInsTblOpts,const SwPosition & rPos,sal_uInt16 nRows,sal_uInt16 nCols,sal_Int16 eAdjust,const SwTableAutoFmt * pTAFmt,const SvUShorts * pColArr,sal_Bool bCalledFromShell,sal_Bool bNewModel)359cdf0e10cSrcweir const SwTable* SwDoc::InsertTable( const SwInsertTableOptions& rInsTblOpts,
360cdf0e10cSrcweir                                    const SwPosition& rPos, sal_uInt16 nRows,
361cdf0e10cSrcweir                                    sal_uInt16 nCols, sal_Int16 eAdjust,
362cdf0e10cSrcweir                                    const SwTableAutoFmt* pTAFmt,
363cdf0e10cSrcweir                                    const SvUShorts* pColArr,
364cdf0e10cSrcweir                                    sal_Bool bCalledFromShell,
365cdf0e10cSrcweir                                    sal_Bool bNewModel )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir     ASSERT( nRows, "Tabelle ohne Zeile?" );
368cdf0e10cSrcweir     ASSERT( nCols, "Tabelle ohne Spalten?" );
369cdf0e10cSrcweir 
370cdf0e10cSrcweir     {
371cdf0e10cSrcweir         // nicht in Fussnoten kopieren !!
372cdf0e10cSrcweir         if( rPos.nNode < GetNodes().GetEndOfInserts().GetIndex() &&
373cdf0e10cSrcweir             rPos.nNode >= GetNodes().GetEndOfInserts().StartOfSectionIndex() )
374cdf0e10cSrcweir             return 0;
375cdf0e10cSrcweir 
376cdf0e10cSrcweir         // sollte das ColumnArray die falsche Anzahl haben wird es ignoriert!
377cdf0e10cSrcweir         if( pColArr &&
378cdf0e10cSrcweir             (nCols + ( text::HoriOrientation::NONE == eAdjust ? 2 : 1 )) != pColArr->Count() )
379cdf0e10cSrcweir             pColArr = 0;
380cdf0e10cSrcweir     }
381cdf0e10cSrcweir 
382cdf0e10cSrcweir     String aTblName = GetUniqueTblName();
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     if( GetIDocumentUndoRedo().DoesUndo() )
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(
387cdf0e10cSrcweir             new SwUndoInsTbl( rPos, nCols, nRows, static_cast<sal_uInt16>(eAdjust),
388cdf0e10cSrcweir                                       rInsTblOpts, pTAFmt, pColArr,
389cdf0e10cSrcweir                                       aTblName));
390cdf0e10cSrcweir     }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir     // fuege erstmal die Nodes ein
393cdf0e10cSrcweir     // hole das Auto-Format fuer die Tabelle
394cdf0e10cSrcweir     SwTxtFmtColl *pBodyColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE ),
395cdf0e10cSrcweir                  *pHeadColl = pBodyColl;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     sal_Bool bDfltBorders = 0 != ( rInsTblOpts.mnInsMode & tabopts::DEFAULT_BORDER );
398cdf0e10cSrcweir 
399cdf0e10cSrcweir     if( (rInsTblOpts.mnInsMode & tabopts::HEADLINE) && (1 != nRows || !bDfltBorders) )
400cdf0e10cSrcweir         pHeadColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     const sal_uInt16 nRowsToRepeat =
403cdf0e10cSrcweir             tabopts::HEADLINE == (rInsTblOpts.mnInsMode & tabopts::HEADLINE) ?
404cdf0e10cSrcweir             rInsTblOpts.mnRowsToRepeat :
405cdf0e10cSrcweir             0;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir     /* #106283# Save content node to extract FRAMEDIR from. */
408cdf0e10cSrcweir     const SwCntntNode * pCntntNd = rPos.nNode.GetNode().GetCntntNode();
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     /* #109161# If we are called from a shell pass the attrset from
411cdf0e10cSrcweir         pCntntNd (aka the node the table is inserted at) thus causing
412cdf0e10cSrcweir         SwNodes::InsertTable to propagate an adjust item if
413cdf0e10cSrcweir         necessary. */
414cdf0e10cSrcweir     SwTableNode *pTblNd = GetNodes().InsertTable(
415cdf0e10cSrcweir         rPos.nNode,
416cdf0e10cSrcweir         nCols,
417cdf0e10cSrcweir         pBodyColl,
418cdf0e10cSrcweir         nRows,
419cdf0e10cSrcweir         nRowsToRepeat,
420cdf0e10cSrcweir         pHeadColl,
421cdf0e10cSrcweir         bCalledFromShell ? &pCntntNd->GetSwAttrSet() : 0 );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     // dann erstelle die Box/Line/Table-Struktur
424cdf0e10cSrcweir     SwTableLineFmt* pLineFmt = MakeTableLineFmt();
425cdf0e10cSrcweir     SwTableFmt* pTableFmt = MakeTblFrmFmt( aTblName, GetDfltFrmFmt() );
426cdf0e10cSrcweir 
427cdf0e10cSrcweir     /* #106283# If the node to insert the table at is a context node and has a
428cdf0e10cSrcweir        non-default FRAMEDIR propagate it to the table. */
429cdf0e10cSrcweir     if (pCntntNd)
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir         const SwAttrSet & aNdSet = pCntntNd->GetSwAttrSet();
432cdf0e10cSrcweir         const SfxPoolItem *pItem = NULL;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir         if (SFX_ITEM_SET == aNdSet.GetItemState( RES_FRAMEDIR, sal_True, &pItem )
435cdf0e10cSrcweir             && pItem != NULL)
436cdf0e10cSrcweir         {
437cdf0e10cSrcweir             pTableFmt->SetFmtAttr( *pItem );
438cdf0e10cSrcweir         }
439cdf0e10cSrcweir     }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     //Orientation am Fmt der Table setzen
442cdf0e10cSrcweir     pTableFmt->SetFmtAttr( SwFmtHoriOrient( 0, eAdjust ) );
443cdf0e10cSrcweir     // alle Zeilen haben die Fill-Order von links nach rechts !
444cdf0e10cSrcweir     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     // die Tabelle bekommt USHRT_MAX als default SSize
447cdf0e10cSrcweir     SwTwips nWidth = USHRT_MAX;
448cdf0e10cSrcweir     if( pColArr )
449cdf0e10cSrcweir     {
450cdf0e10cSrcweir         sal_uInt16 nSttPos = (*pColArr)[ 0 ];
451cdf0e10cSrcweir         sal_uInt16 nLastPos = (*pColArr)[ sal_uInt16(pColArr->Count()-1)];
452cdf0e10cSrcweir         if( text::HoriOrientation::NONE == eAdjust )
453cdf0e10cSrcweir         {
454cdf0e10cSrcweir             sal_uInt16 nFrmWidth = nLastPos;
455cdf0e10cSrcweir             nLastPos = (*pColArr)[ sal_uInt16(pColArr->Count()-2)];
456cdf0e10cSrcweir             pTableFmt->SetFmtAttr( SvxLRSpaceItem( nSttPos, nFrmWidth - nLastPos, 0, 0, RES_LR_SPACE ) );
457cdf0e10cSrcweir         }
458cdf0e10cSrcweir         nWidth = nLastPos - nSttPos;
459cdf0e10cSrcweir     }
460cdf0e10cSrcweir     else if( nCols )
461cdf0e10cSrcweir     {
462cdf0e10cSrcweir         nWidth /= nCols;
463cdf0e10cSrcweir         nWidth *= nCols; // to avoid rounding problems
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
466cdf0e10cSrcweir     if( !(rInsTblOpts.mnInsMode & tabopts::SPLIT_LAYOUT) )
467cdf0e10cSrcweir         pTableFmt->SetFmtAttr( SwFmtLayoutSplit( sal_False ));
468cdf0e10cSrcweir 
469cdf0e10cSrcweir     // verschiebe ggfs. die harten PageDesc/PageBreak Attribute:
470cdf0e10cSrcweir     SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]
471cdf0e10cSrcweir                             ->GetCntntNode();
472cdf0e10cSrcweir     if( pNextNd && pNextNd->HasSwAttrSet() )
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         const SfxItemSet* pNdSet = pNextNd->GetpSwAttrSet();
475cdf0e10cSrcweir         const SfxPoolItem *pItem;
476cdf0e10cSrcweir         if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, sal_False,
477cdf0e10cSrcweir             &pItem ) )
478cdf0e10cSrcweir         {
479cdf0e10cSrcweir             pTableFmt->SetFmtAttr( *pItem );
480cdf0e10cSrcweir             pNextNd->ResetAttr( RES_PAGEDESC );
481cdf0e10cSrcweir             pNdSet = pNextNd->GetpSwAttrSet();
482cdf0e10cSrcweir         }
483cdf0e10cSrcweir         if( pNdSet && SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, sal_False,
484cdf0e10cSrcweir              &pItem ) )
485cdf0e10cSrcweir         {
486cdf0e10cSrcweir             pTableFmt->SetFmtAttr( *pItem );
487cdf0e10cSrcweir             pNextNd->ResetAttr( RES_BREAK );
488cdf0e10cSrcweir         }
489cdf0e10cSrcweir     }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     SwTable * pNdTbl = &pTblNd->GetTable();
492cdf0e10cSrcweir     pNdTbl->RegisterToFormat( *pTableFmt );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir     pNdTbl->SetRowsToRepeat( nRowsToRepeat );
495cdf0e10cSrcweir     pNdTbl->SetTableModel( bNewModel );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir     SvPtrarr aBoxFmtArr( 0, 16 );
498cdf0e10cSrcweir     SwTableBoxFmt* pBoxFmt = 0;
499cdf0e10cSrcweir     if( !bDfltBorders && !pTAFmt )
500cdf0e10cSrcweir     {
501cdf0e10cSrcweir         pBoxFmt = MakeTableBoxFmt();
502cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nCols, 0 ));
503cdf0e10cSrcweir     }
504cdf0e10cSrcweir     else
505cdf0e10cSrcweir     {
506cdf0e10cSrcweir         const sal_uInt16 nBoxArrLen = pTAFmt ? 16 : 4;
507cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < nBoxArrLen; ++i )
508cdf0e10cSrcweir             aBoxFmtArr.Insert( (void*)0, i );
509cdf0e10cSrcweir     }
510cdf0e10cSrcweir     // --> OD 2008-02-25 #refactorlists#
511cdf0e10cSrcweir //    SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
512cdf0e10cSrcweir     SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
513cdf0e10cSrcweir     // <--
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     SwNodeIndex aNdIdx( *pTblNd, 1 );   // auf den ersten Box-StartNode
516cdf0e10cSrcweir     SwTableLines& rLines = pNdTbl->GetTabLines();
517cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < nRows; ++n )
518cdf0e10cSrcweir     {
519cdf0e10cSrcweir         SwTableLine* pLine = new SwTableLine( pLineFmt, nCols, 0 );
520cdf0e10cSrcweir         rLines.C40_INSERT( SwTableLine, pLine, n );
521cdf0e10cSrcweir         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
522cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < nCols; ++i )
523cdf0e10cSrcweir         {
524cdf0e10cSrcweir             SwTableBoxFmt *pBoxF;
525cdf0e10cSrcweir             if( pTAFmt )
526cdf0e10cSrcweir             {
527cdf0e10cSrcweir                 sal_uInt8 nId = static_cast<sal_uInt8>(!n ? 0 : (( n+1 == nRows )
528cdf0e10cSrcweir                                         ? 12 : (4 * (1 + ((n-1) & 1 )))));
529cdf0e10cSrcweir                 nId = nId + static_cast<sal_uInt8>( !i ? 0 :
530cdf0e10cSrcweir                             ( i+1 == nCols ? 3 : (1 + ((i-1) & 1))));
531cdf0e10cSrcweir                 pBoxF = ::lcl_CreateAFmtBoxFmt( *this, aBoxFmtArr, *pTAFmt,
532cdf0e10cSrcweir                                                 nCols, nId );
533cdf0e10cSrcweir 
534cdf0e10cSrcweir                 // ggfs. noch die Absatz/ZeichenAttribute setzen
535cdf0e10cSrcweir                 if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
536cdf0e10cSrcweir                 {
537cdf0e10cSrcweir                     aCharSet.ClearItem();
538cdf0e10cSrcweir                     pTAFmt->UpdateToSet( nId, aCharSet,
539cdf0e10cSrcweir                                         SwTableAutoFmt::UPDATE_CHAR, 0 );
540cdf0e10cSrcweir                     if( aCharSet.Count() )
541cdf0e10cSrcweir                         GetNodes()[ aNdIdx.GetIndex()+1 ]->GetCntntNode()->
542cdf0e10cSrcweir                             SetAttr( aCharSet );
543cdf0e10cSrcweir                 }
544cdf0e10cSrcweir             }
545cdf0e10cSrcweir             else if( bDfltBorders )
546cdf0e10cSrcweir             {
547cdf0e10cSrcweir                 sal_uInt8 nBoxId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
548cdf0e10cSrcweir                 pBoxF = ::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr, nCols, nBoxId);
549cdf0e10cSrcweir             }
550cdf0e10cSrcweir             else
551cdf0e10cSrcweir                 pBoxF = pBoxFmt;
552cdf0e10cSrcweir 
553cdf0e10cSrcweir             // fuer AutoFormat bei der Eingabe: beim Einfuegen der Tabelle
554cdf0e10cSrcweir             // werden gleich die Spalten gesetzt. Im Array stehen die
555cdf0e10cSrcweir             // Positionen der Spalten!! (nicht deren Breite!)
556cdf0e10cSrcweir             if( pColArr )
557cdf0e10cSrcweir             {
558cdf0e10cSrcweir                 nWidth = (*pColArr)[ sal_uInt16(i + 1) ] - (*pColArr)[ i ];
559cdf0e10cSrcweir                 if( pBoxF->GetFrmSize().GetWidth() != nWidth )
560cdf0e10cSrcweir                 {
561cdf0e10cSrcweir                     if( pBoxF->GetDepends() )       // neues Format erzeugen!
562cdf0e10cSrcweir                     {
563cdf0e10cSrcweir                         SwTableBoxFmt *pNewFmt = MakeTableBoxFmt();
564cdf0e10cSrcweir                         *pNewFmt = *pBoxF;
565cdf0e10cSrcweir                         pBoxF = pNewFmt;
566cdf0e10cSrcweir                     }
567cdf0e10cSrcweir                     pBoxF->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
568cdf0e10cSrcweir                 }
569cdf0e10cSrcweir             }
570cdf0e10cSrcweir 
571cdf0e10cSrcweir             SwTableBox *pBox = new SwTableBox( pBoxF, aNdIdx, pLine);
572cdf0e10cSrcweir             rBoxes.C40_INSERT( SwTableBox, pBox, i );
573cdf0e10cSrcweir             aNdIdx += 3;        // StartNode, TextNode, EndNode  == 3 Nodes
574cdf0e10cSrcweir         }
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir     // und Frms einfuegen.
577cdf0e10cSrcweir     GetNodes().GoNext( &aNdIdx );      // zum naechsten ContentNode
578cdf0e10cSrcweir     pTblNd->MakeFrms( &aNdIdx );
579cdf0e10cSrcweir 
580cdf0e10cSrcweir     if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
581cdf0e10cSrcweir     {
582cdf0e10cSrcweir         SwPaM aPam( *pTblNd->EndOfSectionNode(), *pTblNd, 1 );
583cdf0e10cSrcweir         if( IsRedlineOn() )
584cdf0e10cSrcweir             AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
585cdf0e10cSrcweir         else
586cdf0e10cSrcweir             SplitRedline( aPam );
587cdf0e10cSrcweir     }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     SetModified();
590cdf0e10cSrcweir     CHECK_TABLE( *pNdTbl );
591cdf0e10cSrcweir     return pNdTbl;
592cdf0e10cSrcweir }
593cdf0e10cSrcweir 
InsertTable(const SwNodeIndex & rNdIdx,sal_uInt16 nBoxes,SwTxtFmtColl * pCntntTxtColl,sal_uInt16 nLines,sal_uInt16 nRepeat,SwTxtFmtColl * pHeadlineTxtColl,const SwAttrSet * pAttrSet)594cdf0e10cSrcweir SwTableNode* SwNodes::InsertTable( const SwNodeIndex& rNdIdx,
595cdf0e10cSrcweir                                    sal_uInt16 nBoxes,
596cdf0e10cSrcweir                                    SwTxtFmtColl* pCntntTxtColl,
597cdf0e10cSrcweir                                    sal_uInt16 nLines,
598cdf0e10cSrcweir                                    sal_uInt16 nRepeat,
599cdf0e10cSrcweir 								   SwTxtFmtColl* pHeadlineTxtColl,
600cdf0e10cSrcweir                                    const SwAttrSet * pAttrSet)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir 	if( !nBoxes )
603cdf0e10cSrcweir 		return 0;
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 	// wenn Lines angegeben, erzeuge die Matrix aus Lines & Boxen
606cdf0e10cSrcweir 	if( !pHeadlineTxtColl || !nLines )
607cdf0e10cSrcweir 		pHeadlineTxtColl = pCntntTxtColl;
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 	SwTableNode * pTblNd = new SwTableNode( rNdIdx );
610cdf0e10cSrcweir 	SwEndNode* pEndNd = new SwEndNode( rNdIdx, *pTblNd );
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 	if( !nLines )		// fuer die FOR-Schleife
613cdf0e10cSrcweir 		++nLines;
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 	SwNodeIndex aIdx( *pEndNd );
616cdf0e10cSrcweir 	SwTxtFmtColl* pTxtColl = pHeadlineTxtColl;
617cdf0e10cSrcweir 	for( sal_uInt16 nL = 0; nL < nLines; ++nL )
618cdf0e10cSrcweir 	{
619cdf0e10cSrcweir 		for( sal_uInt16 nB = 0; nB < nBoxes; ++nB )
620cdf0e10cSrcweir 		{
621cdf0e10cSrcweir 			SwStartNode* pSttNd = new SwStartNode( aIdx, ND_STARTNODE,
622cdf0e10cSrcweir 													SwTableBoxStartNode );
623cdf0e10cSrcweir 			pSttNd->pStartOfSection = pTblNd;
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 			SwTxtNode * pTmpNd = new SwTxtNode( aIdx, pTxtColl );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir             // --> FME 2006-04-13 #i60422# Propagate some more attributes.
628cdf0e10cSrcweir             // Adjustment was done for #109161#
629cdf0e10cSrcweir             const SfxPoolItem* pItem = NULL;
630cdf0e10cSrcweir             if ( NULL != pAttrSet )
631cdf0e10cSrcweir             {
632cdf0e10cSrcweir                 static const sal_uInt16 aPropagateItems[] = {
633cdf0e10cSrcweir                     RES_PARATR_ADJUST,
634cdf0e10cSrcweir                     RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
635cdf0e10cSrcweir                     RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
636cdf0e10cSrcweir                     RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE, 0 };
637cdf0e10cSrcweir 
638cdf0e10cSrcweir                 const sal_uInt16* pIdx = aPropagateItems;
639cdf0e10cSrcweir                 while ( *pIdx != 0 )
640cdf0e10cSrcweir                 {
641cdf0e10cSrcweir                     if ( SFX_ITEM_SET != pTmpNd->GetSwAttrSet().GetItemState( *pIdx ) &&
642cdf0e10cSrcweir                          SFX_ITEM_SET == pAttrSet->GetItemState( *pIdx, sal_True, &pItem ) )
643cdf0e10cSrcweir                         static_cast<SwCntntNode *>(pTmpNd)->SetAttr(*pItem);
644cdf0e10cSrcweir                     ++pIdx;
645cdf0e10cSrcweir                 }
646cdf0e10cSrcweir             }
647cdf0e10cSrcweir             // <--
648cdf0e10cSrcweir 
649cdf0e10cSrcweir 			new SwEndNode( aIdx, *pSttNd );
650cdf0e10cSrcweir 		}
651cdf0e10cSrcweir 		if ( nL + 1 >= nRepeat )
652cdf0e10cSrcweir             pTxtColl = pCntntTxtColl;
653cdf0e10cSrcweir 	}
654cdf0e10cSrcweir 	return pTblNd;
655cdf0e10cSrcweir }
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 
658cdf0e10cSrcweir //---------------- Text -> Tabelle -----------------------
659cdf0e10cSrcweir 
TextToTable(const SwInsertTableOptions & rInsTblOpts,const SwPaM & rRange,sal_Unicode cCh,sal_Int16 eAdjust,const SwTableAutoFmt * pTAFmt)660cdf0e10cSrcweir const SwTable* SwDoc::TextToTable( const SwInsertTableOptions& rInsTblOpts,
661cdf0e10cSrcweir                                    const SwPaM& rRange, sal_Unicode cCh,
662cdf0e10cSrcweir                                    sal_Int16 eAdjust,
663cdf0e10cSrcweir                                    const SwTableAutoFmt* pTAFmt )
664cdf0e10cSrcweir {
665cdf0e10cSrcweir 	// pruefe ob in der Selection eine Tabelle liegt
666cdf0e10cSrcweir 	const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
667cdf0e10cSrcweir 	{
668cdf0e10cSrcweir 		sal_uLong nCnt = pStt->nNode.GetIndex();
669cdf0e10cSrcweir 		for( ; nCnt <= pEnd->nNode.GetIndex(); ++nCnt )
670cdf0e10cSrcweir 			if( !GetNodes()[ nCnt ]->IsTxtNode() )
671cdf0e10cSrcweir 				return 0;
672cdf0e10cSrcweir 	}
673cdf0e10cSrcweir 
674cdf0e10cSrcweir 	/* #106283# Save first node in the selection if it is a context node. */
675cdf0e10cSrcweir 	SwCntntNode * pSttCntntNd = pStt->nNode.GetNode().GetCntntNode();
676cdf0e10cSrcweir 
677cdf0e10cSrcweir 	SwPaM aOriginal( *pStt, *pEnd );
678cdf0e10cSrcweir 	pStt = aOriginal.GetMark();
679cdf0e10cSrcweir 	pEnd = aOriginal.GetPoint();
680cdf0e10cSrcweir 
681cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
682cdf0e10cSrcweir 	lcl_DelRedlines aDelRedl( aOriginal );
683cdf0e10cSrcweir #endif
684cdf0e10cSrcweir 
685cdf0e10cSrcweir 	SwUndoTxtToTbl* pUndo = 0;
686cdf0e10cSrcweir     if( GetIDocumentUndoRedo().DoesUndo() )
687cdf0e10cSrcweir     {
688cdf0e10cSrcweir         GetIDocumentUndoRedo().StartUndo( UNDO_TEXTTOTABLE, NULL );
689cdf0e10cSrcweir         pUndo = new SwUndoTxtToTbl( aOriginal, rInsTblOpts, cCh,
690cdf0e10cSrcweir                     static_cast<sal_uInt16>(eAdjust), pTAFmt );
691cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo( pUndo );
692cdf0e10cSrcweir 
693cdf0e10cSrcweir 		// das Splitten vom TextNode nicht in die Undohistory aufnehmen
694cdf0e10cSrcweir         GetIDocumentUndoRedo().DoUndo( false );
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 	::PaMCorrAbs( aOriginal, *pEnd );
698cdf0e10cSrcweir 
699cdf0e10cSrcweir 	// sorge dafuer, das der Bereich auf Node-Grenzen liegt
700cdf0e10cSrcweir 	SwNodeRange aRg( pStt->nNode, pEnd->nNode );
701cdf0e10cSrcweir 	if( pStt->nContent.GetIndex() )
702cdf0e10cSrcweir 		SplitNode( *pStt, false );
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 	sal_Bool bEndCntnt = 0 != pEnd->nContent.GetIndex();
705cdf0e10cSrcweir 	// nicht splitten am Ende der Zeile (aber am Ende vom Doc!!)
706cdf0e10cSrcweir 	if( bEndCntnt )
707cdf0e10cSrcweir 	{
708cdf0e10cSrcweir 		if( pEnd->nNode.GetNode().GetCntntNode()->Len() != pEnd->nContent.GetIndex()
709cdf0e10cSrcweir 			|| pEnd->nNode.GetIndex() >= GetNodes().GetEndOfContent().GetIndex()-1 )
710cdf0e10cSrcweir 		{
711cdf0e10cSrcweir 			SplitNode( *pEnd, false );
712cdf0e10cSrcweir 			((SwNodeIndex&)pEnd->nNode)--;
713cdf0e10cSrcweir 			((SwIndex&)pEnd->nContent).Assign(
714cdf0e10cSrcweir 								pEnd->nNode.GetNode().GetCntntNode(), 0 );
715cdf0e10cSrcweir 			// ein Node und am Ende ??
716cdf0e10cSrcweir 			if( pStt->nNode.GetIndex() >= pEnd->nNode.GetIndex() )
717cdf0e10cSrcweir 				aRg.aStart--;
718cdf0e10cSrcweir 		}
719cdf0e10cSrcweir 		else
720cdf0e10cSrcweir 			aRg.aEnd++;
721cdf0e10cSrcweir 	}
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 
724cdf0e10cSrcweir 	if( aRg.aEnd.GetIndex() == aRg.aStart.GetIndex() )
725cdf0e10cSrcweir 	{
726cdf0e10cSrcweir 		ASSERT( sal_False, "Kein Bereich" );
727cdf0e10cSrcweir 		aRg.aEnd++;
728cdf0e10cSrcweir 	}
729cdf0e10cSrcweir 
730cdf0e10cSrcweir 	// Wir gehen jetzt immer ueber die Upper, um die Tabelle einzufuegen:
731cdf0e10cSrcweir 	SwNode2Layout aNode2Layout( aRg.aStart.GetNode() );
732cdf0e10cSrcweir 
733cdf0e10cSrcweir     GetIDocumentUndoRedo().DoUndo( 0 != pUndo );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 	// dann erstelle die Box/Line/Table-Struktur
736cdf0e10cSrcweir 	SwTableBoxFmt* pBoxFmt = MakeTableBoxFmt();
737cdf0e10cSrcweir 	SwTableLineFmt* pLineFmt = MakeTableLineFmt();
738cdf0e10cSrcweir 	SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
739cdf0e10cSrcweir 
740cdf0e10cSrcweir 	// alle Zeilen haben die Fill-Order von links nach rechts !
741cdf0e10cSrcweir     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
742cdf0e10cSrcweir 	// die Tabelle bekommt USHRT_MAX als default SSize
743cdf0e10cSrcweir     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX ));
744cdf0e10cSrcweir     if( !(rInsTblOpts.mnInsMode & tabopts::SPLIT_LAYOUT) )
745cdf0e10cSrcweir         pTableFmt->SetFmtAttr( SwFmtLayoutSplit( sal_False ));
746cdf0e10cSrcweir 
747cdf0e10cSrcweir 	/* #106283# If the first node in the selection is a context node and if it
748cdf0e10cSrcweir        has an item FRAMEDIR set (no default) propagate the item to the
749cdf0e10cSrcweir        replacing table. */
750cdf0e10cSrcweir 	if (pSttCntntNd)
751cdf0e10cSrcweir 	{
752cdf0e10cSrcweir 		const SwAttrSet & aNdSet = pSttCntntNd->GetSwAttrSet();
753cdf0e10cSrcweir 		const SfxPoolItem *pItem = NULL;
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 		if (SFX_ITEM_SET == aNdSet.GetItemState( RES_FRAMEDIR, sal_True, &pItem )
756cdf0e10cSrcweir 			&& pItem != NULL)
757cdf0e10cSrcweir 		{
758cdf0e10cSrcweir             pTableFmt->SetFmtAttr( *pItem );
759cdf0e10cSrcweir 		}
760cdf0e10cSrcweir 	}
761cdf0e10cSrcweir 
762cdf0e10cSrcweir     SwTableNode* pTblNd = GetNodes().TextToTable(
763cdf0e10cSrcweir             aRg, cCh, pTableFmt, pLineFmt, pBoxFmt,
764cdf0e10cSrcweir             GetTxtCollFromPool( RES_POOLCOLL_STANDARD ), pUndo );
765cdf0e10cSrcweir 
766cdf0e10cSrcweir 	SwTable * pNdTbl = &pTblNd->GetTable();
767cdf0e10cSrcweir 	ASSERT( pNdTbl, "kein Tabellen-Node angelegt."  )
768cdf0e10cSrcweir 
769cdf0e10cSrcweir     const sal_uInt16 nRowsToRepeat =
770cdf0e10cSrcweir             tabopts::HEADLINE == (rInsTblOpts.mnInsMode & tabopts::HEADLINE) ?
771cdf0e10cSrcweir             rInsTblOpts.mnRowsToRepeat :
772cdf0e10cSrcweir             0;
773cdf0e10cSrcweir     pNdTbl->SetRowsToRepeat( nRowsToRepeat );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 	sal_Bool bUseBoxFmt = sal_False;
776cdf0e10cSrcweir 	if( !pBoxFmt->GetDepends() )
777cdf0e10cSrcweir 	{
778cdf0e10cSrcweir 		// die Formate an den Boxen haben schon die richtige Size, es darf
779cdf0e10cSrcweir 		// also nur noch die richtige Umrandung/AutoFmt gesetzt werden.
780cdf0e10cSrcweir 		bUseBoxFmt = sal_True;
781cdf0e10cSrcweir         pTableFmt->SetFmtAttr( pBoxFmt->GetFrmSize() );
782cdf0e10cSrcweir 		delete pBoxFmt;
783cdf0e10cSrcweir         eAdjust = text::HoriOrientation::NONE;
784cdf0e10cSrcweir 	}
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 	//Orientation am Fmt der Table setzen
787cdf0e10cSrcweir     pTableFmt->SetFmtAttr( SwFmtHoriOrient( 0, eAdjust ) );
788cdf0e10cSrcweir     pNdTbl->RegisterToFormat( *pTableFmt );
789cdf0e10cSrcweir 
790cdf0e10cSrcweir     if( pTAFmt || ( rInsTblOpts.mnInsMode & tabopts::DEFAULT_BORDER) )
791cdf0e10cSrcweir 	{
792cdf0e10cSrcweir 		sal_uInt8 nBoxArrLen = pTAFmt ? 16 : 4;
793cdf0e10cSrcweir 		SvPtrarr aBoxFmtArr( nBoxArrLen, 0 );
794cdf0e10cSrcweir 		{
795cdf0e10cSrcweir 			for( sal_uInt8 i = 0; i < nBoxArrLen; ++i )
796cdf0e10cSrcweir 				aBoxFmtArr.Insert( (void*)0, i );
797cdf0e10cSrcweir 		}
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         // --> OD 2008-02-25 #refactorlists#
800cdf0e10cSrcweir //        SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
801cdf0e10cSrcweir         SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
802cdf0e10cSrcweir         // <--
803cdf0e10cSrcweir 		SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
804cdf0e10cSrcweir 
805cdf0e10cSrcweir         SwTableBoxFmt *pBoxF = 0;
806cdf0e10cSrcweir 		SwTableLines& rLines = pNdTbl->GetTabLines();
807cdf0e10cSrcweir 		sal_uInt16 nRows = rLines.Count();
808cdf0e10cSrcweir 		for( sal_uInt16 n = 0; n < nRows; ++n )
809cdf0e10cSrcweir 		{
810cdf0e10cSrcweir 			SwTableBoxes& rBoxes = rLines[ n ]->GetTabBoxes();
811cdf0e10cSrcweir 			sal_uInt16 nCols = rBoxes.Count();
812cdf0e10cSrcweir 			for( sal_uInt16 i = 0; i < nCols; ++i )
813cdf0e10cSrcweir 			{
814cdf0e10cSrcweir 				SwTableBox* pBox = rBoxes[ i ];
815cdf0e10cSrcweir 				sal_Bool bChgSz = sal_False;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir 				if( pTAFmt )
818cdf0e10cSrcweir 				{
819cdf0e10cSrcweir 					sal_uInt8 nId = static_cast<sal_uInt8>(!n ? 0 : (( n+1 == nRows )
820cdf0e10cSrcweir 											? 12 : (4 * (1 + ((n-1) & 1 )))));
821cdf0e10cSrcweir 					nId = nId + static_cast<sal_uInt8>(!i ? 0 :
822cdf0e10cSrcweir                                 ( i+1 == nCols ? 3 : (1 + ((i-1) & 1))));
823cdf0e10cSrcweir 					if( bUseBoxFmt )
824cdf0e10cSrcweir 						::lcl_SetDfltBoxAttr( *pBox, aBoxFmtArr, nId, pTAFmt );
825cdf0e10cSrcweir 					else
826cdf0e10cSrcweir 					{
827cdf0e10cSrcweir 						bChgSz = 0 == aBoxFmtArr[ nId ];
828cdf0e10cSrcweir 						pBoxF = ::lcl_CreateAFmtBoxFmt( *this, aBoxFmtArr,
829cdf0e10cSrcweir 												*pTAFmt, USHRT_MAX, nId );
830cdf0e10cSrcweir 					}
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 					// ggfs. noch die Absatz/ZeichenAttribute setzen
833cdf0e10cSrcweir 					if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
834cdf0e10cSrcweir 					{
835cdf0e10cSrcweir 						aCharSet.ClearItem();
836cdf0e10cSrcweir 						pTAFmt->UpdateToSet( nId, aCharSet,
837cdf0e10cSrcweir 											SwTableAutoFmt::UPDATE_CHAR, 0 );
838cdf0e10cSrcweir 						if( aCharSet.Count() )
839cdf0e10cSrcweir 						{
840cdf0e10cSrcweir 							sal_uLong nSttNd = pBox->GetSttIdx()+1;
841cdf0e10cSrcweir 							sal_uLong nEndNd = pBox->GetSttNd()->EndOfSectionIndex();
842cdf0e10cSrcweir 							for( ; nSttNd < nEndNd; ++nSttNd )
843cdf0e10cSrcweir 							{
844cdf0e10cSrcweir 								SwCntntNode* pNd = GetNodes()[ nSttNd ]->GetCntntNode();
845cdf0e10cSrcweir 								if( pNd )
846cdf0e10cSrcweir 								{
847cdf0e10cSrcweir 									if( pHistory )
848cdf0e10cSrcweir 									{
849cdf0e10cSrcweir 										SwRegHistory aReg( pNd, *pNd, pHistory );
850cdf0e10cSrcweir 										pNd->SetAttr( aCharSet );
851cdf0e10cSrcweir 									}
852cdf0e10cSrcweir 									else
853cdf0e10cSrcweir 										pNd->SetAttr( aCharSet );
854cdf0e10cSrcweir 								}
855cdf0e10cSrcweir 							}
856cdf0e10cSrcweir 						}
857cdf0e10cSrcweir 					}
858cdf0e10cSrcweir 				}
859cdf0e10cSrcweir 				else
860cdf0e10cSrcweir 				{
861cdf0e10cSrcweir 					sal_uInt8 nId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
862cdf0e10cSrcweir 					if( bUseBoxFmt )
863cdf0e10cSrcweir 						::lcl_SetDfltBoxAttr( *pBox, aBoxFmtArr, nId );
864cdf0e10cSrcweir 					else
865cdf0e10cSrcweir 					{
866cdf0e10cSrcweir 						bChgSz = 0 == aBoxFmtArr[ nId ];
867cdf0e10cSrcweir 						pBoxF = ::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr,
868cdf0e10cSrcweir 														USHRT_MAX, nId );
869cdf0e10cSrcweir 					}
870cdf0e10cSrcweir 				}
871cdf0e10cSrcweir 
872cdf0e10cSrcweir 				if( !bUseBoxFmt )
873cdf0e10cSrcweir 				{
874cdf0e10cSrcweir 					if( bChgSz )
875cdf0e10cSrcweir                         pBoxF->SetFmtAttr( pBox->GetFrmFmt()->GetFrmSize() );
876cdf0e10cSrcweir 					pBox->ChgFrmFmt( pBoxF );
877cdf0e10cSrcweir 				}
878cdf0e10cSrcweir 			}
879cdf0e10cSrcweir 		}
880cdf0e10cSrcweir 
881cdf0e10cSrcweir 		if( bUseBoxFmt )
882cdf0e10cSrcweir 		{
883cdf0e10cSrcweir 			for( sal_uInt8 i = 0; i < nBoxArrLen; ++i )
884cdf0e10cSrcweir 			{
885cdf0e10cSrcweir 				SvPtrarr* pArr = (SvPtrarr*)aBoxFmtArr[ i ];
886cdf0e10cSrcweir 				delete pArr;
887cdf0e10cSrcweir 			}
888cdf0e10cSrcweir 		}
889cdf0e10cSrcweir 	}
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 	// JP 03.04.97: Inhalt der Boxen auf Zahlen abpruefen
892cdf0e10cSrcweir 	if( IsInsTblFormatNum() )
893cdf0e10cSrcweir 	{
894cdf0e10cSrcweir 		for( sal_uInt16 nBoxes = pNdTbl->GetTabSortBoxes().Count(); nBoxes; )
895cdf0e10cSrcweir 			ChkBoxNumFmt( *pNdTbl->GetTabSortBoxes()[ --nBoxes ], sal_False );
896cdf0e10cSrcweir 	}
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 	sal_uLong nIdx = pTblNd->GetIndex();
899cdf0e10cSrcweir 	aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
900cdf0e10cSrcweir 
901cdf0e10cSrcweir 	{
902cdf0e10cSrcweir 		SwPaM& rTmp = (SwPaM&)rRange;	// Point immer an den Anfang
903cdf0e10cSrcweir 		rTmp.DeleteMark();
904cdf0e10cSrcweir 		rTmp.GetPoint()->nNode = *pTblNd;
905cdf0e10cSrcweir 		SwCntntNode* pCNd = GetNodes().GoNext( &rTmp.GetPoint()->nNode );
906cdf0e10cSrcweir 		rTmp.GetPoint()->nContent.Assign( pCNd, 0 );
907cdf0e10cSrcweir 	}
908cdf0e10cSrcweir 
909cdf0e10cSrcweir 	if( pUndo )
910cdf0e10cSrcweir     {
911cdf0e10cSrcweir         GetIDocumentUndoRedo().EndUndo( UNDO_TEXTTOTABLE, NULL );
912cdf0e10cSrcweir     }
913cdf0e10cSrcweir 
914cdf0e10cSrcweir 	SetModified();
915cdf0e10cSrcweir 	SetFieldsDirty(true, NULL, 0);
916cdf0e10cSrcweir 	return pNdTbl;
917cdf0e10cSrcweir }
918cdf0e10cSrcweir 
TextToTable(const SwNodeRange & rRange,sal_Unicode cCh,SwTableFmt * pTblFmt,SwTableLineFmt * pLineFmt,SwTableBoxFmt * pBoxFmt,SwTxtFmtColl * pTxtColl,SwUndoTxtToTbl * pUndo)919cdf0e10cSrcweir SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
920cdf0e10cSrcweir 									SwTableFmt* pTblFmt,
921cdf0e10cSrcweir 									SwTableLineFmt* pLineFmt,
922cdf0e10cSrcweir 									SwTableBoxFmt* pBoxFmt,
923cdf0e10cSrcweir 									SwTxtFmtColl* pTxtColl,
924cdf0e10cSrcweir 									SwUndoTxtToTbl* pUndo )
925cdf0e10cSrcweir {
926cdf0e10cSrcweir 	if( rRange.aStart >= rRange.aEnd )
927cdf0e10cSrcweir 		return 0;
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 	SwTableNode * pTblNd = new SwTableNode( rRange.aStart );
930cdf0e10cSrcweir 	new SwEndNode( rRange.aEnd, *pTblNd );
931cdf0e10cSrcweir 
932cdf0e10cSrcweir 	SwDoc* pDoc = GetDoc();
933cdf0e10cSrcweir 	SvUShorts aPosArr( 0, 16 );
934cdf0e10cSrcweir 	SwTable * pTable = &pTblNd->GetTable();
935cdf0e10cSrcweir 	SwTableLine* pLine;
936cdf0e10cSrcweir 	SwTableBox* pBox;
937cdf0e10cSrcweir 	sal_uInt16 nBoxes, nLines, nMaxBoxes = 0;
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 	SwNodeIndex aSttIdx( *pTblNd, 1 );
940cdf0e10cSrcweir 	SwNodeIndex aEndIdx( rRange.aEnd, -1 );
941cdf0e10cSrcweir 	for( nLines = 0, nBoxes = 0;
942cdf0e10cSrcweir 		aSttIdx.GetIndex() < aEndIdx.GetIndex();
943cdf0e10cSrcweir 		aSttIdx += 2, nLines++, nBoxes = 0 )
944cdf0e10cSrcweir 	{
945cdf0e10cSrcweir 		SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
946cdf0e10cSrcweir 		ASSERT( pTxtNd, "nur TextNodes in der Tabelle aufnehmen" );
947cdf0e10cSrcweir 
948cdf0e10cSrcweir 		if( !nLines && 0x0b == cCh )
949cdf0e10cSrcweir 		{
950cdf0e10cSrcweir 			cCh = 0x09;
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 			// JP 28.10.96: vom 1. Node die Positionen des Trenners besorgen,
953cdf0e10cSrcweir 			//				damit die Boxen entsprechend eingestellt werden
954cdf0e10cSrcweir 			SwTxtFrmInfo aFInfo( (SwTxtFrm*)pTxtNd->getLayoutFrm( pTxtNd->GetDoc()->GetCurrentLayout() ) );
955cdf0e10cSrcweir 			if( aFInfo.IsOneLine() )		// nur dann sinnvoll!
956cdf0e10cSrcweir 			{
957cdf0e10cSrcweir 				const sal_Unicode* pTxt = pTxtNd->GetTxt().GetBuffer();
958cdf0e10cSrcweir 				for( xub_StrLen nChPos = 0; *pTxt; ++nChPos, ++pTxt )
959cdf0e10cSrcweir                 {
960cdf0e10cSrcweir 					if( *pTxt == cCh )
961cdf0e10cSrcweir 					{
962cdf0e10cSrcweir 						aPosArr.Insert( static_cast<sal_uInt16>(
963cdf0e10cSrcweir                                         aFInfo.GetCharPos( nChPos+1, sal_False )),
964cdf0e10cSrcweir 										aPosArr.Count() );
965cdf0e10cSrcweir 					}
966cdf0e10cSrcweir                 }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir 				aPosArr.Insert( /*aFInfo.GetFrm()->Frm().Left() +*/
969cdf0e10cSrcweir                                 static_cast<sal_uInt16>(aFInfo.GetFrm()->IsVertical() ?
970cdf0e10cSrcweir                                 aFInfo.GetFrm()->Prt().Bottom() :
971cdf0e10cSrcweir                                 aFInfo.GetFrm()->Prt().Right()),
972cdf0e10cSrcweir 								aPosArr.Count() );
973cdf0e10cSrcweir 			}
974cdf0e10cSrcweir 		}
975cdf0e10cSrcweir 
976cdf0e10cSrcweir 		// die alten Frames loeschen, es werden neue erzeugt
977cdf0e10cSrcweir 		pTxtNd->DelFrms();
978cdf0e10cSrcweir 
979cdf0e10cSrcweir 		// PageBreaks/PageDesc/ColBreak rausschmeissen.
980cdf0e10cSrcweir         const SfxItemSet* pSet = pTxtNd->GetpSwAttrSet();
981cdf0e10cSrcweir 		if( pSet )
982cdf0e10cSrcweir 		{
983cdf0e10cSrcweir // das entfernen der PageBreaks erst nach dem erzeugen der Tabelle
984cdf0e10cSrcweir // erfolgen, denn sonst stehen sie falsch in der History !!!
985cdf0e10cSrcweir //			SwRegHistory aRegH( pTxtNd, *pTxtNd, pHistory );
986cdf0e10cSrcweir 			const SfxPoolItem* pItem;
987cdf0e10cSrcweir 			if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
988cdf0e10cSrcweir 			{
989cdf0e10cSrcweir 				if( !nLines )
990cdf0e10cSrcweir                     pTblFmt->SetFmtAttr( *pItem );
991cdf0e10cSrcweir                 pTxtNd->ResetAttr( RES_BREAK );
992cdf0e10cSrcweir                 pSet = pTxtNd->GetpSwAttrSet();
993cdf0e10cSrcweir 			}
994cdf0e10cSrcweir 
995cdf0e10cSrcweir 			if( pSet && SFX_ITEM_SET == pSet->GetItemState(
996cdf0e10cSrcweir 				RES_PAGEDESC, sal_False, &pItem ) &&
997cdf0e10cSrcweir 				((SwFmtPageDesc*)pItem)->GetPageDesc() )
998cdf0e10cSrcweir 			{
999cdf0e10cSrcweir 				if( !nLines )
1000cdf0e10cSrcweir                     pTblFmt->SetFmtAttr( *pItem );
1001cdf0e10cSrcweir                 pTxtNd->ResetAttr( RES_PAGEDESC );
1002cdf0e10cSrcweir 			}
1003cdf0e10cSrcweir 		}
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir 		// setze den bei allen TextNode in der Tabelle den TableNode
1006cdf0e10cSrcweir 		// als StartNode
1007cdf0e10cSrcweir 		pTxtNd->pStartOfSection = pTblNd;
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir 		pLine = new SwTableLine( pLineFmt, 1, 0 );
1010cdf0e10cSrcweir 		pTable->GetTabLines().C40_INSERT( SwTableLine, pLine, nLines );
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 		SwStartNode* pSttNd;
1013cdf0e10cSrcweir 		SwPosition aCntPos( aSttIdx, SwIndex( pTxtNd ));
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir 		SvULongs aBkmkArr( 15, 15 );
1016cdf0e10cSrcweir 		_SaveCntntIdx( pDoc, aSttIdx.GetIndex(), pTxtNd->GetTxt().Len(), aBkmkArr );
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir 		const sal_Unicode* pTxt = pTxtNd->GetTxt().GetBuffer();
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir 		if( T2T_PARA != cCh )
1021cdf0e10cSrcweir 			for( xub_StrLen nChPos = 0; *pTxt; ++nChPos, ++pTxt )
1022cdf0e10cSrcweir 				if( *pTxt == cCh )
1023cdf0e10cSrcweir 				{
1024cdf0e10cSrcweir 					aCntPos.nContent = nChPos;
1025cdf0e10cSrcweir                     SwCntntNode* pNewNd = pTxtNd->SplitCntntNode( aCntPos );
1026cdf0e10cSrcweir 
1027cdf0e10cSrcweir 					if( aBkmkArr.Count() )
1028cdf0e10cSrcweir 						_RestoreCntntIdx( aBkmkArr, *pNewNd, nChPos,
1029cdf0e10cSrcweir 											nChPos + 1 );
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir 					// Trennzeichen loeschen und SuchString korrigieren
1032cdf0e10cSrcweir                     pTxtNd->EraseText( aCntPos.nContent, 1 );
1033cdf0e10cSrcweir 					pTxt = pTxtNd->GetTxt().GetBuffer();
1034cdf0e10cSrcweir 					nChPos = 0;
1035cdf0e10cSrcweir 					--nChPos, --pTxt;           // for the ++ in the for loop !!!
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir 					// setze bei allen TextNodes in der Tabelle den TableNode
1038cdf0e10cSrcweir 					// als StartNode
1039cdf0e10cSrcweir 					const SwNodeIndex aTmpIdx( aCntPos.nNode, -1 );
1040cdf0e10cSrcweir 					pSttNd = new SwStartNode( aTmpIdx, ND_STARTNODE,
1041cdf0e10cSrcweir 												SwTableBoxStartNode );
1042cdf0e10cSrcweir 					new SwEndNode( aCntPos.nNode, *pSttNd );
1043cdf0e10cSrcweir 					pNewNd->pStartOfSection = pSttNd;
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir 					// Section der Box zuweisen
1046cdf0e10cSrcweir 					pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
1047cdf0e10cSrcweir 					pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, nBoxes++ );
1048cdf0e10cSrcweir 				}
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 		// und jetzt den letzten Teil-String
1051cdf0e10cSrcweir 		if( aBkmkArr.Count() )
1052cdf0e10cSrcweir 			_RestoreCntntIdx( aBkmkArr, *pTxtNd, pTxtNd->GetTxt().Len(),
1053cdf0e10cSrcweir 								pTxtNd->GetTxt().Len()+1 );
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir 		pSttNd = new SwStartNode( aCntPos.nNode, ND_STARTNODE, SwTableBoxStartNode );
1056cdf0e10cSrcweir 		const SwNodeIndex aTmpIdx( aCntPos.nNode, 1 );
1057cdf0e10cSrcweir 		new SwEndNode( aTmpIdx, *pSttNd  );
1058cdf0e10cSrcweir 		pTxtNd->pStartOfSection = pSttNd;
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 		pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
1061cdf0e10cSrcweir 		pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, nBoxes++ );
1062cdf0e10cSrcweir 		if( nMaxBoxes < nBoxes )
1063cdf0e10cSrcweir 			nMaxBoxes = nBoxes;
1064cdf0e10cSrcweir 	}
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir 	// die Tabelle ausgleichen, leere Sections einfuegen
1067cdf0e10cSrcweir 	sal_uInt16 n;
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir 	for( n = 0; n < pTable->GetTabLines().Count(); ++n )
1070cdf0e10cSrcweir 	{
1071cdf0e10cSrcweir 		SwTableLine* pCurrLine = pTable->GetTabLines()[ n ];
1072cdf0e10cSrcweir 		if( nMaxBoxes != ( nBoxes = pCurrLine->GetTabBoxes().Count() ))
1073cdf0e10cSrcweir 		{
1074cdf0e10cSrcweir 			InsBoxen( pTblNd, pCurrLine, pBoxFmt, pTxtColl, 0,
1075cdf0e10cSrcweir 						nBoxes, nMaxBoxes - nBoxes );
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir 			if( pUndo )
1078cdf0e10cSrcweir 				for( sal_uInt16 i = nBoxes; i < nMaxBoxes; ++i )
1079cdf0e10cSrcweir 					pUndo->AddFillBox( *pCurrLine->GetTabBoxes()[ i ] );
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir 			// fehlen der 1. Line Boxen, dann kann man das Breiten Array
1082cdf0e10cSrcweir 			// vergessen!
1083cdf0e10cSrcweir 			if( !n )
1084cdf0e10cSrcweir 				aPosArr.Remove( 0, aPosArr.Count() );
1085cdf0e10cSrcweir 		}
1086cdf0e10cSrcweir 	}
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir 	if( aPosArr.Count() )
1089cdf0e10cSrcweir 	{
1090cdf0e10cSrcweir 		SwTableLines& rLns = pTable->GetTabLines();
1091cdf0e10cSrcweir 		sal_uInt16 nLastPos = 0;
1092cdf0e10cSrcweir 		for( n = 0; n < aPosArr.Count(); ++n )
1093cdf0e10cSrcweir 		{
1094cdf0e10cSrcweir 			SwTableBoxFmt *pNewFmt = pDoc->MakeTableBoxFmt();
1095cdf0e10cSrcweir             pNewFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
1096cdf0e10cSrcweir 												aPosArr[ n ] - nLastPos ));
1097cdf0e10cSrcweir 			for( sal_uInt16 nTmpLine = 0; nTmpLine < rLns.Count(); ++nTmpLine )
1098cdf0e10cSrcweir 				//JP 24.06.98: hier muss ein Add erfolgen, da das BoxFormat
1099cdf0e10cSrcweir 				//				von der rufenden Methode noch gebraucht wird!
1100cdf0e10cSrcweir 				pNewFmt->Add( rLns[ nTmpLine ]->GetTabBoxes()[ n ] );
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir 			nLastPos = aPosArr[ n ];
1103cdf0e10cSrcweir 		}
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir 		// damit die Tabelle die richtige Groesse bekommt, im BoxFormat die
1106cdf0e10cSrcweir 		// Groesse nach "oben" transportieren.
1107cdf0e10cSrcweir 		ASSERT( !pBoxFmt->GetDepends(), "wer ist in dem Format noch angemeldet" );
1108cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
1109cdf0e10cSrcweir 	}
1110cdf0e10cSrcweir 	else
1111cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes ));
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 	// das wars doch wohl ??
1114cdf0e10cSrcweir 	return pTblNd;
1115cdf0e10cSrcweir }
1116cdf0e10cSrcweir /*-- 18.05.2006 10:30:29---------------------------------------------------
1117cdf0e10cSrcweir 
1118cdf0e10cSrcweir   -----------------------------------------------------------------------*/
TextToTable(const std::vector<std::vector<SwNodeRange>> & rTableNodes)1119cdf0e10cSrcweir const SwTable* SwDoc::TextToTable( const std::vector< std::vector<SwNodeRange> >& rTableNodes )
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir     /* #106283# Save first node in the selection if it is a content node. */
1122cdf0e10cSrcweir     SwCntntNode * pSttCntntNd = rTableNodes.begin()->begin()->aStart.GetNode().GetCntntNode();
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir     /**debug**/
1125cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1126cdf0e10cSrcweir     const SwNodeRange& rStartRange = *rTableNodes.begin()->begin();
1127cdf0e10cSrcweir     const SwNodeRange& rEndRange = *rTableNodes.rbegin()->rbegin();
1128cdf0e10cSrcweir     (void) rStartRange;
1129cdf0e10cSrcweir     (void) rEndRange;
1130cdf0e10cSrcweir #endif
1131cdf0e10cSrcweir     /**debug**/
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir     //!!! not necessarily TextNodes !!!
1134cdf0e10cSrcweir     SwPaM aOriginal( rTableNodes.begin()->begin()->aStart, rTableNodes.rbegin()->rbegin()->aEnd );
1135cdf0e10cSrcweir     const SwPosition *pStt = aOriginal.GetMark();
1136cdf0e10cSrcweir     const SwPosition *pEnd = aOriginal.GetPoint();
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
1139cdf0e10cSrcweir     lcl_DelRedlines aDelRedl( aOriginal );
1140cdf0e10cSrcweir #endif
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir //    SwUndoTxtToTbl* pUndo = 0;
1143cdf0e10cSrcweir     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
1144cdf0e10cSrcweir     if (bUndo)
1145cdf0e10cSrcweir     {
1146cdf0e10cSrcweir         // das Splitten vom TextNode nicht in die Undohistory aufnehmen
1147cdf0e10cSrcweir         GetIDocumentUndoRedo().DoUndo(false);
1148cdf0e10cSrcweir     }
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir     ::PaMCorrAbs( aOriginal, *pEnd );
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir     // sorge dafuer, das der Bereich auf Node-Grenzen liegt
1153cdf0e10cSrcweir     SwNodeRange aRg( pStt->nNode, pEnd->nNode );
1154cdf0e10cSrcweir     if( pStt->nContent.GetIndex() )
1155cdf0e10cSrcweir         SplitNode( *pStt, false );
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir     sal_Bool bEndCntnt = 0 != pEnd->nContent.GetIndex();
1158cdf0e10cSrcweir     // nicht splitten am Ende der Zeile (aber am Ende vom Doc!!)
1159cdf0e10cSrcweir     if( bEndCntnt )
1160cdf0e10cSrcweir     {
1161cdf0e10cSrcweir         if( pEnd->nNode.GetNode().GetCntntNode()->Len() != pEnd->nContent.GetIndex()
1162cdf0e10cSrcweir             || pEnd->nNode.GetIndex() >= GetNodes().GetEndOfContent().GetIndex()-1 )
1163cdf0e10cSrcweir         {
1164cdf0e10cSrcweir             SplitNode( *pEnd, false );
1165cdf0e10cSrcweir             ((SwNodeIndex&)pEnd->nNode)--;
1166cdf0e10cSrcweir             ((SwIndex&)pEnd->nContent).Assign(
1167cdf0e10cSrcweir                                 pEnd->nNode.GetNode().GetCntntNode(), 0 );
1168cdf0e10cSrcweir             // ein Node und am Ende ??
1169cdf0e10cSrcweir             if( pStt->nNode.GetIndex() >= pEnd->nNode.GetIndex() )
1170cdf0e10cSrcweir                 aRg.aStart--;
1171cdf0e10cSrcweir         }
1172cdf0e10cSrcweir         else
1173cdf0e10cSrcweir             aRg.aEnd++;
1174cdf0e10cSrcweir     }
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir     if( aRg.aEnd.GetIndex() == aRg.aStart.GetIndex() )
1178cdf0e10cSrcweir     {
1179cdf0e10cSrcweir         ASSERT( sal_False, "Kein Bereich" );
1180cdf0e10cSrcweir         aRg.aEnd++;
1181cdf0e10cSrcweir     }
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir     // Wir gehen jetzt immer ueber die Upper, um die Tabelle einzufuegen:
1184cdf0e10cSrcweir     SwNode2Layout aNode2Layout( aRg.aStart.GetNode() );
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir     GetIDocumentUndoRedo().DoUndo(bUndo);
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     // dann erstelle die Box/Line/Table-Struktur
1189cdf0e10cSrcweir     SwTableBoxFmt* pBoxFmt = MakeTableBoxFmt();
1190cdf0e10cSrcweir     SwTableLineFmt* pLineFmt = MakeTableLineFmt();
1191cdf0e10cSrcweir     SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir     // alle Zeilen haben die Fill-Order von links nach rechts !
1194cdf0e10cSrcweir     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
1195cdf0e10cSrcweir     // die Tabelle bekommt USHRT_MAX als default SSize
1196cdf0e10cSrcweir     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX ));
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir     /* #106283# If the first node in the selection is a context node and if it
1199cdf0e10cSrcweir        has an item FRAMEDIR set (no default) propagate the item to the
1200cdf0e10cSrcweir        replacing table. */
1201cdf0e10cSrcweir     if (pSttCntntNd)
1202cdf0e10cSrcweir     {
1203cdf0e10cSrcweir         const SwAttrSet & aNdSet = pSttCntntNd->GetSwAttrSet();
1204cdf0e10cSrcweir         const SfxPoolItem *pItem = NULL;
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir         if (SFX_ITEM_SET == aNdSet.GetItemState( RES_FRAMEDIR, sal_True, &pItem )
1207cdf0e10cSrcweir             && pItem != NULL)
1208cdf0e10cSrcweir         {
1209cdf0e10cSrcweir             pTableFmt->SetFmtAttr( *pItem );
1210cdf0e10cSrcweir         }
1211cdf0e10cSrcweir     }
1212cdf0e10cSrcweir 
1213cdf0e10cSrcweir     SwTableNode* pTblNd = GetNodes().TextToTable(
1214cdf0e10cSrcweir             rTableNodes, pTableFmt, pLineFmt, pBoxFmt,
1215cdf0e10cSrcweir             GetTxtCollFromPool( RES_POOLCOLL_STANDARD )/*, pUndo*/ );
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir     SwTable * pNdTbl = &pTblNd->GetTable();
1218cdf0e10cSrcweir     ASSERT( pNdTbl, "kein Tabellen-Node angelegt."  )
1219cdf0e10cSrcweir     pNdTbl->RegisterToFormat( *pTableFmt );
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir     sal_Bool bUseBoxFmt = sal_False;
1222cdf0e10cSrcweir     if( !pBoxFmt->GetDepends() )
1223cdf0e10cSrcweir     {
1224cdf0e10cSrcweir         // die Formate an den Boxen haben schon die richtige Size, es darf
1225cdf0e10cSrcweir         // also nur noch die richtige Umrandung/AutoFmt gesetzt werden.
1226cdf0e10cSrcweir         bUseBoxFmt = sal_True;
1227cdf0e10cSrcweir         pTableFmt->SetFmtAttr( pBoxFmt->GetFrmSize() );
1228cdf0e10cSrcweir         delete pBoxFmt;
1229cdf0e10cSrcweir     }
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir     sal_uLong nIdx = pTblNd->GetIndex();
1232cdf0e10cSrcweir     aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir     SetModified();
1235cdf0e10cSrcweir     SetFieldsDirty( true, NULL, 0 );
1236cdf0e10cSrcweir     return pNdTbl;
1237cdf0e10cSrcweir }
1238cdf0e10cSrcweir 
ExpandRangeForTableBox(const SwNodeRange & rRange)1239cdf0e10cSrcweir SwNodeRange * SwNodes::ExpandRangeForTableBox(const SwNodeRange & rRange)
1240cdf0e10cSrcweir {
1241cdf0e10cSrcweir     SwNodeRange * pResult = NULL;
1242cdf0e10cSrcweir     bool bChanged = false;
1243cdf0e10cSrcweir 
1244cdf0e10cSrcweir 	SwNodeIndex aNewStart = rRange.aStart;
1245cdf0e10cSrcweir 	SwNodeIndex aNewEnd = rRange.aEnd;
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir 	SwNodeIndex aEndIndex = rRange.aEnd;
1248cdf0e10cSrcweir 	SwNodeIndex aIndex = rRange.aStart;
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 	while (aIndex < aEndIndex)
1251cdf0e10cSrcweir 	{
1252cdf0e10cSrcweir 		SwNode& rNode = aIndex.GetNode();
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir 		if (rNode.IsStartNode())
1255cdf0e10cSrcweir 		{
1256cdf0e10cSrcweir             // advance aIndex to the end node of this start node
1257cdf0e10cSrcweir             SwNode * pEndNode = rNode.EndOfSectionNode();
1258cdf0e10cSrcweir             aIndex = *pEndNode;
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir             if (aIndex > aNewEnd)
1261cdf0e10cSrcweir             {
1262cdf0e10cSrcweir                 aNewEnd = aIndex;
1263cdf0e10cSrcweir                 bChanged = true;
1264cdf0e10cSrcweir             }
1265cdf0e10cSrcweir 		}
1266cdf0e10cSrcweir 		else if (rNode.IsEndNode())
1267cdf0e10cSrcweir 		{
1268cdf0e10cSrcweir             SwNode * pStartNode = rNode.StartOfSectionNode();
1269cdf0e10cSrcweir 			SwNodeIndex aStartIndex = *pStartNode;
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir 			if (aStartIndex < aNewStart)
1272cdf0e10cSrcweir             {
1273cdf0e10cSrcweir 				aNewStart = aStartIndex;
1274cdf0e10cSrcweir                 bChanged = true;
1275cdf0e10cSrcweir             }
1276cdf0e10cSrcweir 		}
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir 		if (aIndex < aEndIndex)
1279cdf0e10cSrcweir 			++aIndex;
1280cdf0e10cSrcweir 	}
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir     SwNode * pNode = &aIndex.GetNode();
1283cdf0e10cSrcweir     while (pNode->IsEndNode())
1284cdf0e10cSrcweir     {
1285cdf0e10cSrcweir         SwNode * pStartNode = pNode->StartOfSectionNode();
1286cdf0e10cSrcweir         SwNodeIndex aStartIndex(*pStartNode);
1287cdf0e10cSrcweir         aNewStart = aStartIndex;
1288cdf0e10cSrcweir         aNewEnd = aIndex;
1289cdf0e10cSrcweir         bChanged = true;
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir         ++aIndex;
1292cdf0e10cSrcweir         pNode = &aIndex.GetNode();
1293cdf0e10cSrcweir     }
1294cdf0e10cSrcweir 
1295cdf0e10cSrcweir     if (bChanged)
1296cdf0e10cSrcweir         pResult = new SwNodeRange(aNewStart, aNewEnd);
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir     return pResult;
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir 
1301cdf0e10cSrcweir /*-- 18.05.2006 08:23:28---------------------------------------------------
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir   -----------------------------------------------------------------------*/
TextToTable(const SwNodes::TableRanges_t & rTableNodes,SwTableFmt * pTblFmt,SwTableLineFmt * pLineFmt,SwTableBoxFmt * pBoxFmt,SwTxtFmtColl *)1304cdf0e10cSrcweir SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
1305cdf0e10cSrcweir                                     SwTableFmt* pTblFmt,
1306cdf0e10cSrcweir                                     SwTableLineFmt* pLineFmt,
1307cdf0e10cSrcweir                                     SwTableBoxFmt* pBoxFmt,
1308cdf0e10cSrcweir                                     SwTxtFmtColl* /*pTxtColl*/  /*, SwUndo... pUndo*/  )
1309cdf0e10cSrcweir {
1310cdf0e10cSrcweir     if( !rTableNodes.size() )
1311cdf0e10cSrcweir         return 0;
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir     SwTableNode * pTblNd = new SwTableNode( rTableNodes.begin()->begin()->aStart );
1314cdf0e10cSrcweir     //insert the end node after the last text node
1315cdf0e10cSrcweir    SwNodeIndex aInsertIndex( rTableNodes.rbegin()->rbegin()->aEnd );
1316cdf0e10cSrcweir    ++aInsertIndex;
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir    //!! owner ship will be transferred in c-tor to SwNodes array.
1319cdf0e10cSrcweir    //!! Thus no real problem here...
1320cdf0e10cSrcweir    new SwEndNode( aInsertIndex, *pTblNd );
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1323cdf0e10cSrcweir     /**debug**/
1324cdf0e10cSrcweir     const SwNodeRange& rStartRange = *rTableNodes.begin()->begin();
1325cdf0e10cSrcweir     const SwNodeRange& rEndRange = *rTableNodes.rbegin()->rbegin();
1326cdf0e10cSrcweir     (void) rStartRange;
1327cdf0e10cSrcweir     (void) rEndRange;
1328cdf0e10cSrcweir     /**debug**/
1329cdf0e10cSrcweir #endif
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir     SwDoc* pDoc = GetDoc();
1332cdf0e10cSrcweir     SvUShorts aPosArr( 0, 16 );
1333cdf0e10cSrcweir     SwTable * pTable = &pTblNd->GetTable();
1334cdf0e10cSrcweir     SwTableLine* pLine;
1335cdf0e10cSrcweir     SwTableBox* pBox;
1336cdf0e10cSrcweir     sal_uInt16 nBoxes, nLines, nMaxBoxes = 0;
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir //    SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir     SwNodeIndex aNodeIndex = rTableNodes.begin()->begin()->aStart;
1342cdf0e10cSrcweir     // delete frames of all contained content nodes
1343cdf0e10cSrcweir     for( nLines = 0; aNodeIndex <= rTableNodes.rbegin()->rbegin()->aEnd; ++aNodeIndex,++nLines )
1344cdf0e10cSrcweir     {
1345cdf0e10cSrcweir         SwNode& rNode = aNodeIndex.GetNode();
1346cdf0e10cSrcweir         if( rNode.IsCntntNode() )
1347cdf0e10cSrcweir         {
1348cdf0e10cSrcweir             static_cast<SwCntntNode&>(rNode).DelFrms();
1349cdf0e10cSrcweir             if(rNode.IsTxtNode())
1350cdf0e10cSrcweir             {
1351cdf0e10cSrcweir                 SwTxtNode& rTxtNode = static_cast<SwTxtNode&>(rNode);
1352cdf0e10cSrcweir                 // setze den bei allen TextNode in der Tabelle den TableNode
1353cdf0e10cSrcweir                 // als StartNode
1354cdf0e10cSrcweir // FIXME: this is setting wrong node StartOfSections in nested tables.
1355cdf0e10cSrcweir //                rTxtNode.pStartOfSection = pTblNd;
1356cdf0e10cSrcweir                 // remove PageBreaks/PageDesc/ColBreak
1357cdf0e10cSrcweir                 const SwAttrSet* pSet = rTxtNode.GetpSwAttrSet();
1358cdf0e10cSrcweir                 if( pSet )
1359cdf0e10cSrcweir                 {
1360cdf0e10cSrcweir         // das entfernen der PageBreaks erst nach dem erzeugen der Tabelle
1361cdf0e10cSrcweir         // erfolgen, denn sonst stehen sie falsch in der History !!!
1362cdf0e10cSrcweir         //          SwRegHistory aRegH( pTxtNd, *pTxtNd, pHistory );
1363cdf0e10cSrcweir                     const SfxPoolItem* pItem;
1364cdf0e10cSrcweir                     if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
1365cdf0e10cSrcweir                     {
1366cdf0e10cSrcweir                         if( !nLines )
1367cdf0e10cSrcweir                             pTblFmt->SetFmtAttr( *pItem );
1368cdf0e10cSrcweir                         rTxtNode.ResetAttr( RES_BREAK );
1369cdf0e10cSrcweir                         pSet = rTxtNode.GetpSwAttrSet();
1370cdf0e10cSrcweir                     }
1371cdf0e10cSrcweir 
1372cdf0e10cSrcweir                     if( pSet && SFX_ITEM_SET == pSet->GetItemState(
1373cdf0e10cSrcweir                         RES_PAGEDESC, sal_False, &pItem ) &&
1374cdf0e10cSrcweir                         ((SwFmtPageDesc*)pItem)->GetPageDesc() )
1375cdf0e10cSrcweir                     {
1376cdf0e10cSrcweir                         if( !nLines )
1377cdf0e10cSrcweir                             pTblFmt->SetFmtAttr( *pItem );
1378cdf0e10cSrcweir                         rTxtNode.ResetAttr( RES_PAGEDESC );
1379cdf0e10cSrcweir                     }
1380cdf0e10cSrcweir                 }
1381cdf0e10cSrcweir             }
1382cdf0e10cSrcweir         }
1383cdf0e10cSrcweir     }
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir //    SwNodeIndex aSttIdx( *pTblNd, 1 );
1386cdf0e10cSrcweir //    SwNodeIndex aEndIdx( rlNodes.rbegin()->aEnd, -1 );
1387cdf0e10cSrcweir     std::vector<std::vector < SwNodeRange > >::const_iterator aRowIter = rTableNodes.begin();
1388cdf0e10cSrcweir     for( nLines = 0, nBoxes = 0;
1389cdf0e10cSrcweir         aRowIter != rTableNodes.end();
1390cdf0e10cSrcweir         ++aRowIter, /*aSttIdx += 2, */nLines++, nBoxes = 0 )
1391cdf0e10cSrcweir     {
1392cdf0e10cSrcweir //        SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
1393cdf0e10cSrcweir //        ASSERT( pTxtNd, "nur TextNodes in der Tabelle aufnehmen" );
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir         pLine = new SwTableLine( pLineFmt, 1, 0 );
1396cdf0e10cSrcweir         pTable->GetTabLines().C40_INSERT( SwTableLine, pLine, nLines );
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir //        SwStartNode* pSttNd;
1399cdf0e10cSrcweir //        SwPosition aCntPos( aSttIdx, SwIndex( pTxtNd ));
1400cdf0e10cSrcweir 
1401cdf0e10cSrcweir         std::vector< SwNodeRange >::const_iterator aCellIter = aRowIter->begin();
1402cdf0e10cSrcweir //        SvULongs aBkmkArr( 15, 15 );
1403cdf0e10cSrcweir //        _SaveCntntIdx( pDoc, aCellIter->aStart.GetIndex(), pTxtNd->GetTxt().Len(), aBkmkArr );
1404cdf0e10cSrcweir //        const sal_Unicode* pTxt = pTxtNd->GetTxt().GetBuffer();
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir         for( ; aCellIter != aRowIter->end(); ++aCellIter )
1407cdf0e10cSrcweir         {
1408cdf0e10cSrcweir //            aCellIter->aStart aCellIter->aEnd
1409cdf0e10cSrcweir //                aCntPos.nContent = nChPos;
1410cdf0e10cSrcweir //                SwCntntNode* pNewNd = pTxtNd->SplitNode( aCntPos );
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir //        auch f?rs undo?
1413cdf0e10cSrcweir //                if( aBkmkArr.Count() )
1414cdf0e10cSrcweir //                    _RestoreCntntIdx( aBkmkArr, *pNewNd, nChPos,
1415cdf0e10cSrcweir //                                        nChPos + 1 );
1416cdf0e10cSrcweir 
1417cdf0e10cSrcweir                 const SwNodeIndex aTmpIdx( aCellIter->aStart, 0 );
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir                SwNodeIndex aCellEndIdx(aCellIter->aEnd);
1420cdf0e10cSrcweir                ++aCellEndIdx;
1421cdf0e10cSrcweir                SwStartNode* pSttNd = new SwStartNode( aTmpIdx, ND_STARTNODE,
1422cdf0e10cSrcweir                                             SwTableBoxStartNode );
1423cdf0e10cSrcweir                 new SwEndNode( aCellEndIdx, *pSttNd );
1424cdf0e10cSrcweir                 //set the start node on all node of the current cell
1425cdf0e10cSrcweir                 SwNodeIndex aCellNodeIdx = aCellIter->aStart;
1426cdf0e10cSrcweir                 for(;aCellNodeIdx <= aCellIter->aEnd; ++aCellNodeIdx )
1427cdf0e10cSrcweir                 {
1428cdf0e10cSrcweir                     aCellNodeIdx.GetNode().pStartOfSection = pSttNd;
1429cdf0e10cSrcweir                     //skip start/end node pairs
1430cdf0e10cSrcweir                     if( aCellNodeIdx.GetNode().IsStartNode() )
1431cdf0e10cSrcweir                         aCellNodeIdx = SwNodeIndex( *aCellNodeIdx.GetNode().EndOfSectionNode() );
1432cdf0e10cSrcweir                 }
1433cdf0e10cSrcweir 
1434cdf0e10cSrcweir                 // Section der Box zuweisen
1435cdf0e10cSrcweir                 pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
1436cdf0e10cSrcweir                 pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, nBoxes++ );
1437cdf0e10cSrcweir         }
1438cdf0e10cSrcweir         if( nMaxBoxes < nBoxes )
1439cdf0e10cSrcweir             nMaxBoxes = nBoxes;
1440cdf0e10cSrcweir     }
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir     // die Tabelle ausgleichen, leere Sections einfuegen
1443cdf0e10cSrcweir     sal_uInt16 n;
1444cdf0e10cSrcweir 
1445cdf0e10cSrcweir     if( aPosArr.Count() )
1446cdf0e10cSrcweir     {
1447cdf0e10cSrcweir         SwTableLines& rLns = pTable->GetTabLines();
1448cdf0e10cSrcweir         sal_uInt16 nLastPos = 0;
1449cdf0e10cSrcweir         for( n = 0; n < aPosArr.Count(); ++n )
1450cdf0e10cSrcweir         {
1451cdf0e10cSrcweir             SwTableBoxFmt *pNewFmt = pDoc->MakeTableBoxFmt();
1452cdf0e10cSrcweir             pNewFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
1453cdf0e10cSrcweir                                                 aPosArr[ n ] - nLastPos ));
1454cdf0e10cSrcweir             for( sal_uInt16 nLines2 = 0; nLines2 < rLns.Count(); ++nLines2 )
1455cdf0e10cSrcweir                 //JP 24.06.98: hier muss ein Add erfolgen, da das BoxFormat
1456cdf0e10cSrcweir                 //              von der rufenden Methode noch gebraucht wird!
1457cdf0e10cSrcweir                 pNewFmt->Add( rLns[ nLines2 ]->GetTabBoxes()[ n ] );
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir             nLastPos = aPosArr[ n ];
1460cdf0e10cSrcweir         }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir         // damit die Tabelle die richtige Groesse bekommt, im BoxFormat die
1463cdf0e10cSrcweir         // Groesse nach "oben" transportieren.
1464cdf0e10cSrcweir         ASSERT( !pBoxFmt->GetDepends(), "wer ist in dem Format noch angemeldet" );
1465cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
1466cdf0e10cSrcweir     }
1467cdf0e10cSrcweir     else
1468cdf0e10cSrcweir         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes ));
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir     // das wars doch wohl ??
1471cdf0e10cSrcweir     return pTblNd;
1472cdf0e10cSrcweir }
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir //---------------- Tabelle -> Text -----------------------
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir 
TableToText(const SwTableNode * pTblNd,sal_Unicode cCh)1478cdf0e10cSrcweir sal_Bool SwDoc::TableToText( const SwTableNode* pTblNd, sal_Unicode cCh )
1479cdf0e10cSrcweir {
1480cdf0e10cSrcweir 	if( !pTblNd )
1481cdf0e10cSrcweir 		return sal_False;
1482cdf0e10cSrcweir 
1483cdf0e10cSrcweir     // --> FME 2004-09-28 #i34471#
1484cdf0e10cSrcweir     // If this is trigged by SwUndoTblToTxt::Repeat() nobody ever deleted
1485cdf0e10cSrcweir     // the table cursor.
1486cdf0e10cSrcweir     SwEditShell* pESh = GetEditShell();
1487cdf0e10cSrcweir     if( pESh && pESh->IsTableMode() )
1488cdf0e10cSrcweir         pESh->ClearMark();
1489cdf0e10cSrcweir     // <--
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
1492cdf0e10cSrcweir     lcl_DelRedlines aDelRedl( *pTblNd, sal_False );
1493cdf0e10cSrcweir #endif
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir 	SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode() );
1496cdf0e10cSrcweir 	SwUndoTblToTxt* pUndo = 0;
1497cdf0e10cSrcweir 	SwNodeRange* pUndoRg = 0;
1498cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
1499cdf0e10cSrcweir     {
1500cdf0e10cSrcweir         GetIDocumentUndoRedo().ClearRedo();
1501cdf0e10cSrcweir 		pUndoRg = new SwNodeRange( aRg.aStart, -1, aRg.aEnd, +1 );
1502cdf0e10cSrcweir 		pUndo = new SwUndoTblToTxt( pTblNd->GetTable(), cCh );
1503cdf0e10cSrcweir 	}
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
1506cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXNAME;
1507cdf0e10cSrcweir 	UpdateTblFlds( &aMsgHnt );
1508cdf0e10cSrcweir 
1509cdf0e10cSrcweir 	sal_Bool bRet = GetNodes().TableToText( aRg, cCh, pUndo );
1510cdf0e10cSrcweir 	if( pUndoRg )
1511cdf0e10cSrcweir 	{
1512cdf0e10cSrcweir 		pUndoRg->aStart++;
1513cdf0e10cSrcweir 		pUndoRg->aEnd--;
1514cdf0e10cSrcweir 		pUndo->SetRange( *pUndoRg );
1515cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
1516cdf0e10cSrcweir 		delete pUndoRg;
1517cdf0e10cSrcweir 	}
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir 	if( bRet )
1520cdf0e10cSrcweir 		SetModified();
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 	return bRet;
1523cdf0e10cSrcweir }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir // -- benutze die ForEach Methode vom PtrArray um aus einer Tabelle wieder
1526cdf0e10cSrcweir //		Text zuerzeugen. (Die Boxen koennen auch noch Lines enthalten !!)
1527cdf0e10cSrcweir struct _DelTabPara
1528cdf0e10cSrcweir {
1529cdf0e10cSrcweir 	SwTxtNode* pLastNd;
1530cdf0e10cSrcweir 	SwNodes& rNds;
1531cdf0e10cSrcweir 	SwUndoTblToTxt* pUndo;
1532cdf0e10cSrcweir 	sal_Unicode cCh;
1533cdf0e10cSrcweir 
_DelTabPara_DelTabPara1534cdf0e10cSrcweir 	_DelTabPara( SwNodes& rNodes, sal_Unicode cChar, SwUndoTblToTxt* pU ) :
1535cdf0e10cSrcweir 		pLastNd(0), rNds( rNodes ), pUndo( pU ), cCh( cChar ) {}
_DelTabPara_DelTabPara1536cdf0e10cSrcweir 	_DelTabPara( const _DelTabPara& rPara ) :
1537cdf0e10cSrcweir 		pLastNd(rPara.pLastNd), rNds( rPara.rNds ),
1538cdf0e10cSrcweir 		pUndo( rPara.pUndo ), cCh( rPara.cCh ) {}
1539cdf0e10cSrcweir };
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir // forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen
1542cdf0e10cSrcweir // koennen.
1543cdf0e10cSrcweir sal_Bool lcl_DelBox( const SwTableBox*&, void *pPara );
1544cdf0e10cSrcweir 
lcl_DelLine(const SwTableLine * & rpLine,void * pPara)1545cdf0e10cSrcweir sal_Bool lcl_DelLine( const SwTableLine*& rpLine, void* pPara )
1546cdf0e10cSrcweir {
1547cdf0e10cSrcweir 	ASSERT( pPara, "die Parameter fehlen" );
1548cdf0e10cSrcweir 	_DelTabPara aPara( *(_DelTabPara*)pPara );
1549cdf0e10cSrcweir 	((SwTableLine*&)rpLine)->GetTabBoxes().ForEach( &lcl_DelBox, &aPara );
1550cdf0e10cSrcweir 	if( rpLine->GetUpper() )		// gibt es noch eine uebergeordnete Box ??
1551cdf0e10cSrcweir 		// dann gebe den letzten TextNode zurueck
1552cdf0e10cSrcweir 		((_DelTabPara*)pPara)->pLastNd = aPara.pLastNd;
1553cdf0e10cSrcweir 	return sal_True;
1554cdf0e10cSrcweir }
1555cdf0e10cSrcweir 
1556cdf0e10cSrcweir 
lcl_DelBox(const SwTableBox * & rpBox,void * pPara)1557cdf0e10cSrcweir sal_Bool lcl_DelBox( const SwTableBox*& rpBox, void* pPara )
1558cdf0e10cSrcweir {
1559cdf0e10cSrcweir 	ASSERT( pPara, "die Parameter fehlen" );
1560cdf0e10cSrcweir 
1561cdf0e10cSrcweir 	// loesche erstmal die Lines der Box
1562cdf0e10cSrcweir 	_DelTabPara* pDelPara = (_DelTabPara*)pPara;
1563cdf0e10cSrcweir 	if( rpBox->GetTabLines().Count() )
1564cdf0e10cSrcweir 		((SwTableBox*&)rpBox)->GetTabLines().ForEach( &lcl_DelLine, pDelPara );
1565cdf0e10cSrcweir 	else
1566cdf0e10cSrcweir 	{
1567cdf0e10cSrcweir 		SwDoc* pDoc = pDelPara->rNds.GetDoc();
1568cdf0e10cSrcweir 		SwNodeRange aDelRg( *rpBox->GetSttNd(), 0,
1569cdf0e10cSrcweir 							*rpBox->GetSttNd()->EndOfSectionNode() );
1570cdf0e10cSrcweir 		// loesche die Section
1571cdf0e10cSrcweir 		pDelPara->rNds.SectionUp( &aDelRg );
1572cdf0e10cSrcweir 		const SwTxtNode* pCurTxtNd;
1573cdf0e10cSrcweir 		if( T2T_PARA != pDelPara->cCh && pDelPara->pLastNd &&
1574cdf0e10cSrcweir 			0 != ( pCurTxtNd = aDelRg.aStart.GetNode().GetTxtNode() ))
1575cdf0e10cSrcweir 		{
1576cdf0e10cSrcweir 			// Join the current text node with the last from the previous box if possible
1577cdf0e10cSrcweir 			sal_uLong nNdIdx = aDelRg.aStart.GetIndex();
1578cdf0e10cSrcweir 			aDelRg.aStart--;
1579cdf0e10cSrcweir 			if( pDelPara->pLastNd == &aDelRg.aStart.GetNode() )
1580cdf0e10cSrcweir 			{
1581cdf0e10cSrcweir                 // Inserting the seperator
1582cdf0e10cSrcweir                 SwIndex aCntIdx( pDelPara->pLastNd, pDelPara->pLastNd->GetTxt().Len());
1583cdf0e10cSrcweir                 pDelPara->pLastNd->InsertText( pDelPara->cCh, aCntIdx,
1584cdf0e10cSrcweir                     IDocumentContentOperations::INS_EMPTYEXPAND );
1585cdf0e10cSrcweir 				if( pDelPara->pUndo )
1586cdf0e10cSrcweir 					pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx, aDelRg.aEnd.GetIndex(),
1587cdf0e10cSrcweir 												aCntIdx.GetIndex() );
1588cdf0e10cSrcweir 
1589cdf0e10cSrcweir 				SvULongs aBkmkArr( 4, 4 );
1590cdf0e10cSrcweir 				xub_StrLen nOldTxtLen = aCntIdx.GetIndex();
1591cdf0e10cSrcweir 				_SaveCntntIdx( pDoc, nNdIdx, pCurTxtNd->GetTxt().Len(),
1592cdf0e10cSrcweir 								aBkmkArr );
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir 				pDelPara->pLastNd->JoinNext();
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir 				if( aBkmkArr.Count() )
1597cdf0e10cSrcweir 					_RestoreCntntIdx( pDoc, aBkmkArr,
1598cdf0e10cSrcweir 										pDelPara->pLastNd->GetIndex(),
1599cdf0e10cSrcweir 										nOldTxtLen );
1600cdf0e10cSrcweir 			}
1601cdf0e10cSrcweir 			else if( pDelPara->pUndo )
1602cdf0e10cSrcweir             {
1603cdf0e10cSrcweir                 aDelRg.aStart++;
1604cdf0e10cSrcweir 				pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx, aDelRg.aEnd.GetIndex() );
1605cdf0e10cSrcweir             }
1606cdf0e10cSrcweir 		}
1607cdf0e10cSrcweir 		else if( pDelPara->pUndo )
1608cdf0e10cSrcweir 			pDelPara->pUndo->AddBoxPos( *pDoc, aDelRg.aStart.GetIndex(), aDelRg.aEnd.GetIndex() );
1609cdf0e10cSrcweir 		aDelRg.aEnd--;
1610cdf0e10cSrcweir 		pDelPara->pLastNd = aDelRg.aEnd.GetNode().GetTxtNode();
1611cdf0e10cSrcweir 
1612cdf0e10cSrcweir 		//JP 03.04.97: die Ausrichtung der ZahlenFormatierung auf
1613cdf0e10cSrcweir 		//				keinen Fall uebernehmen
1614cdf0e10cSrcweir         if( pDelPara->pLastNd && pDelPara->pLastNd->HasSwAttrSet() )
1615cdf0e10cSrcweir 			pDelPara->pLastNd->ResetAttr( RES_PARATR_ADJUST );
1616cdf0e10cSrcweir 	}
1617cdf0e10cSrcweir 	return sal_True;
1618cdf0e10cSrcweir }
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 
TableToText(const SwNodeRange & rRange,sal_Unicode cCh,SwUndoTblToTxt * pUndo)1621cdf0e10cSrcweir sal_Bool SwNodes::TableToText( const SwNodeRange& rRange, sal_Unicode cCh,
1622cdf0e10cSrcweir 							SwUndoTblToTxt* pUndo )
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir 	// ist eine Tabelle selektiert ?
1625cdf0e10cSrcweir 	SwTableNode* pTblNd;
1626cdf0e10cSrcweir 	if( rRange.aStart.GetIndex() >= rRange.aEnd.GetIndex() ||
1627cdf0e10cSrcweir         0 == ( pTblNd = rRange.aStart.GetNode().GetTableNode()) ||
1628cdf0e10cSrcweir 		&rRange.aEnd.GetNode() != pTblNd->EndOfSectionNode() )
1629cdf0e10cSrcweir 		return sal_False;
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir 	// stand die Tabelle ganz alleine in einer Section ?
1632cdf0e10cSrcweir 	// dann ueber den Upper der Tabelle die Frames anlegen
1633cdf0e10cSrcweir 	SwNode2Layout* pNode2Layout = 0;
1634cdf0e10cSrcweir 	SwNodeIndex aFrmIdx( rRange.aStart );
1635cdf0e10cSrcweir 	SwNode* pFrmNd = FindPrvNxtFrmNode( aFrmIdx, &rRange.aEnd.GetNode() );
1636cdf0e10cSrcweir 	if( !pFrmNd )
1637cdf0e10cSrcweir 		// dann sammel mal alle Uppers ein
1638cdf0e10cSrcweir 		pNode2Layout = new SwNode2Layout( *pTblNd );
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir 	// loesche schon mal die Frames
1641cdf0e10cSrcweir 	pTblNd->DelFrms();
1642cdf0e10cSrcweir 
1643cdf0e10cSrcweir 	// dann "loeschen" die Tabellen und fasse alle Lines/Boxen zusammen
1644cdf0e10cSrcweir 	_DelTabPara aDelPara( *this, cCh, pUndo );
1645cdf0e10cSrcweir 	pTblNd->pTable->GetTabLines().ForEach( &lcl_DelLine, &aDelPara );
1646cdf0e10cSrcweir 
1647cdf0e10cSrcweir 	// jetzt ist aus jeder TableLine ein TextNode mit dem entsprechenden
1648cdf0e10cSrcweir 	// Trenner erzeugt worden. Es braucht nur noch die Table-Section
1649cdf0e10cSrcweir 	// geloescht und fuer die neuen TextNode die Frames erzeugt werden.
1650cdf0e10cSrcweir 	SwNodeRange aDelRg( rRange.aStart, rRange.aEnd );
1651cdf0e10cSrcweir 
1652cdf0e10cSrcweir 	// JP 14.01.97: hat die Tabelle PageDesc-/Break-Attribute? Dann in den
1653cdf0e10cSrcweir 	//				ersten TextNode uebernehmen
1654cdf0e10cSrcweir 	{
1655cdf0e10cSrcweir // was ist mit UNDO???
1656cdf0e10cSrcweir 		const SfxItemSet& rTblSet = pTblNd->pTable->GetFrmFmt()->GetAttrSet();
1657cdf0e10cSrcweir 		const SfxPoolItem *pBreak, *pDesc;
1658cdf0e10cSrcweir 		if( SFX_ITEM_SET != rTblSet.GetItemState( RES_PAGEDESC, sal_False, &pDesc ))
1659cdf0e10cSrcweir 			pDesc = 0;
1660cdf0e10cSrcweir 		if( SFX_ITEM_SET != rTblSet.GetItemState( RES_BREAK, sal_False, &pBreak ))
1661cdf0e10cSrcweir 			pBreak = 0;
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir 		if( pBreak || pDesc )
1664cdf0e10cSrcweir 		{
1665cdf0e10cSrcweir 			SwNodeIndex aIdx( *pTblNd  );
1666cdf0e10cSrcweir 			SwCntntNode* pCNd = GoNext( &aIdx );
1667cdf0e10cSrcweir 			if( pBreak )
1668cdf0e10cSrcweir 				pCNd->SetAttr( *pBreak );
1669cdf0e10cSrcweir 			if( pDesc )
1670cdf0e10cSrcweir 				pCNd->SetAttr( *pDesc );
1671cdf0e10cSrcweir 		}
1672cdf0e10cSrcweir 	}
1673cdf0e10cSrcweir 
1674cdf0e10cSrcweir 	SectionUp( &aDelRg );		// loesche die Section und damit die Tabelle
1675cdf0e10cSrcweir     // #i28006#
1676cdf0e10cSrcweir     sal_uLong nStt = aDelRg.aStart.GetIndex(), nEnd = aDelRg.aEnd.GetIndex();
1677cdf0e10cSrcweir 	if( !pFrmNd )
1678cdf0e10cSrcweir 	{
1679cdf0e10cSrcweir 		pNode2Layout->RestoreUpperFrms( *this,
1680cdf0e10cSrcweir 						aDelRg.aStart.GetIndex(), aDelRg.aEnd.GetIndex() );
1681cdf0e10cSrcweir 		delete pNode2Layout;
1682cdf0e10cSrcweir 	}
1683cdf0e10cSrcweir 	else
1684cdf0e10cSrcweir 	{
1685cdf0e10cSrcweir 		SwCntntNode *pCNd;
1686cdf0e10cSrcweir 		SwSectionNode *pSNd;
1687cdf0e10cSrcweir 		while( aDelRg.aStart.GetIndex() < nEnd )
1688cdf0e10cSrcweir 		{
1689cdf0e10cSrcweir 			if( 0 != ( pCNd = aDelRg.aStart.GetNode().GetCntntNode()))
1690cdf0e10cSrcweir 			{
1691cdf0e10cSrcweir 				if( pFrmNd->IsCntntNode() )
1692cdf0e10cSrcweir 					((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
1693cdf0e10cSrcweir 				else if( pFrmNd->IsTableNode() )
1694cdf0e10cSrcweir 					((SwTableNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
1695cdf0e10cSrcweir 				else if( pFrmNd->IsSectionNode() )
1696cdf0e10cSrcweir 					((SwSectionNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
1697cdf0e10cSrcweir 				pFrmNd = pCNd;
1698cdf0e10cSrcweir 			}
1699cdf0e10cSrcweir 			else if( 0 != ( pSNd = aDelRg.aStart.GetNode().GetSectionNode()))
1700cdf0e10cSrcweir 			{
1701cdf0e10cSrcweir 				if( !pSNd->GetSection().IsHidden() && !pSNd->IsCntntHidden() )
1702cdf0e10cSrcweir 				{
1703cdf0e10cSrcweir 					pSNd->MakeFrms( &aFrmIdx, &aDelRg.aEnd );
1704cdf0e10cSrcweir 					pFrmNd = pSNd;
1705cdf0e10cSrcweir 					break;
1706cdf0e10cSrcweir 				}
1707cdf0e10cSrcweir 				aDelRg.aStart = *pSNd->EndOfSectionNode();
1708cdf0e10cSrcweir 			}
1709cdf0e10cSrcweir 			aDelRg.aStart++;
1710cdf0e10cSrcweir 		}
1711cdf0e10cSrcweir     }
1712cdf0e10cSrcweir 
1713cdf0e10cSrcweir     // #i28006# Fly frames have to be restored even if the table was
1714cdf0e10cSrcweir     // #alone in the section
1715cdf0e10cSrcweir     const SwSpzFrmFmts& rFlyArr = *GetDoc()->GetSpzFrmFmts();
1716cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < rFlyArr.Count(); ++n )
1717cdf0e10cSrcweir     {
1718cdf0e10cSrcweir         SwFrmFmt *const pFmt = (SwFrmFmt*)rFlyArr[n];
1719cdf0e10cSrcweir         const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
1720cdf0e10cSrcweir         SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1721cdf0e10cSrcweir         if (pAPos &&
1722cdf0e10cSrcweir             ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1723cdf0e10cSrcweir              (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
1724cdf0e10cSrcweir             nStt <= pAPos->nNode.GetIndex() &&
1725cdf0e10cSrcweir             pAPos->nNode.GetIndex() < nEnd )
1726cdf0e10cSrcweir         {
1727cdf0e10cSrcweir             pFmt->MakeFrms();
1728cdf0e10cSrcweir         }
1729cdf0e10cSrcweir 	}
1730cdf0e10cSrcweir 
1731cdf0e10cSrcweir 	return sal_True;
1732cdf0e10cSrcweir }
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir // ----- einfuegen von Spalten/Zeilen ------------------------
1736cdf0e10cSrcweir 
InsertCol(const SwCursor & rCursor,sal_uInt16 nCnt,sal_Bool bBehind)1737cdf0e10cSrcweir sal_Bool SwDoc::InsertCol( const SwCursor& rCursor, sal_uInt16 nCnt, sal_Bool bBehind )
1738cdf0e10cSrcweir {
1739cdf0e10cSrcweir 	if( !::CheckSplitCells( rCursor, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) )
1740cdf0e10cSrcweir 		return sal_False;
1741cdf0e10cSrcweir 
1742cdf0e10cSrcweir 	// lasse ueber das Layout die Boxen suchen
1743cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1744cdf0e10cSrcweir 	::GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
1745cdf0e10cSrcweir 
1746cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1747cdf0e10cSrcweir 	if( aBoxes.Count() )
1748cdf0e10cSrcweir 		bRet = InsertCol( aBoxes, nCnt, bBehind );
1749cdf0e10cSrcweir 	return bRet;
1750cdf0e10cSrcweir }
1751cdf0e10cSrcweir 
InsertCol(const SwSelBoxes & rBoxes,sal_uInt16 nCnt,sal_Bool bBehind)1752cdf0e10cSrcweir sal_Bool SwDoc::InsertCol( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, sal_Bool bBehind )
1753cdf0e10cSrcweir {
1754cdf0e10cSrcweir 	// uebers SwDoc fuer Undo !!
1755cdf0e10cSrcweir 	ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
1756cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
1757cdf0e10cSrcweir 	if( !pTblNd )
1758cdf0e10cSrcweir 		return sal_False;
1759cdf0e10cSrcweir 
1760cdf0e10cSrcweir 	SwTable& rTbl = pTblNd->GetTable();
1761cdf0e10cSrcweir 	if( rTbl.ISA( SwDDETable ))
1762cdf0e10cSrcweir 		return sal_False;
1763cdf0e10cSrcweir 
1764cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
1765cdf0e10cSrcweir 	lcl_DelRedlines aDelRedl( *pTblNd, sal_True );
1766cdf0e10cSrcweir #endif
1767cdf0e10cSrcweir 
1768cdf0e10cSrcweir 	SwTableSortBoxes aTmpLst( 0, 5 );
1769cdf0e10cSrcweir 	SwUndoTblNdsChg* pUndo = 0;
1770cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
1771cdf0e10cSrcweir     {
1772cdf0e10cSrcweir 		pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSCOL, rBoxes, *pTblNd,
1773cdf0e10cSrcweir                                      0, 0, nCnt, bBehind, sal_False );
1774cdf0e10cSrcweir 		aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
1775cdf0e10cSrcweir 	}
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir     bool bRet(false);
1778cdf0e10cSrcweir     {
1779cdf0e10cSrcweir         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir         SwTableFmlUpdate aMsgHnt( &rTbl );
1782cdf0e10cSrcweir         aMsgHnt.eFlags = TBL_BOXPTR;
1783cdf0e10cSrcweir         UpdateTblFlds( &aMsgHnt );
1784cdf0e10cSrcweir 
1785cdf0e10cSrcweir         bRet = rTbl.InsertCol( this, rBoxes, nCnt, bBehind );
1786cdf0e10cSrcweir         if (bRet)
1787cdf0e10cSrcweir         {
1788cdf0e10cSrcweir             SetModified();
1789cdf0e10cSrcweir             ::ClearFEShellTabCols();
1790cdf0e10cSrcweir             SetFieldsDirty( true, NULL, 0 );
1791cdf0e10cSrcweir         }
1792cdf0e10cSrcweir     }
1793cdf0e10cSrcweir 
1794cdf0e10cSrcweir 	if( pUndo )
1795cdf0e10cSrcweir     {
1796cdf0e10cSrcweir 		if( bRet )
1797cdf0e10cSrcweir         {
1798cdf0e10cSrcweir 			pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
1799cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
1800cdf0e10cSrcweir         }
1801cdf0e10cSrcweir         else
1802cdf0e10cSrcweir 			delete pUndo;
1803cdf0e10cSrcweir 	}
1804cdf0e10cSrcweir 	return bRet;
1805cdf0e10cSrcweir }
1806cdf0e10cSrcweir 
InsertRow(const SwCursor & rCursor,sal_uInt16 nCnt,sal_Bool bBehind)1807cdf0e10cSrcweir sal_Bool SwDoc::InsertRow( const SwCursor& rCursor, sal_uInt16 nCnt, sal_Bool bBehind )
1808cdf0e10cSrcweir {
1809cdf0e10cSrcweir 	// lasse ueber das Layout die Boxen suchen
1810cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1811cdf0e10cSrcweir 	GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
1812cdf0e10cSrcweir 
1813cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1814cdf0e10cSrcweir 	if( aBoxes.Count() )
1815cdf0e10cSrcweir 		bRet = InsertRow( aBoxes, nCnt, bBehind );
1816cdf0e10cSrcweir 	return bRet;
1817cdf0e10cSrcweir }
1818cdf0e10cSrcweir 
InsertRow(const SwSelBoxes & rBoxes,sal_uInt16 nCnt,sal_Bool bBehind)1819cdf0e10cSrcweir sal_Bool SwDoc::InsertRow( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, sal_Bool bBehind )
1820cdf0e10cSrcweir {
1821cdf0e10cSrcweir 	// uebers SwDoc fuer Undo !!
1822cdf0e10cSrcweir 	ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
1823cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
1824cdf0e10cSrcweir 	if( !pTblNd )
1825cdf0e10cSrcweir 		return sal_False;
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir 	SwTable& rTbl = pTblNd->GetTable();
1828cdf0e10cSrcweir 	if( rTbl.ISA( SwDDETable ))
1829cdf0e10cSrcweir 		return sal_False;
1830cdf0e10cSrcweir 
1831cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
1832cdf0e10cSrcweir 	lcl_DelRedlines aDelRedl( *pTblNd, sal_True );
1833cdf0e10cSrcweir #endif
1834cdf0e10cSrcweir 
1835cdf0e10cSrcweir 	SwTableSortBoxes aTmpLst( 0, 5 );
1836cdf0e10cSrcweir 	SwUndoTblNdsChg* pUndo = 0;
1837cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
1838cdf0e10cSrcweir     {
1839cdf0e10cSrcweir 		pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW,rBoxes, *pTblNd,
1840cdf0e10cSrcweir 									 0, 0, nCnt, bBehind, sal_False );
1841cdf0e10cSrcweir 		aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
1842cdf0e10cSrcweir 	}
1843cdf0e10cSrcweir 
1844cdf0e10cSrcweir     bool bRet(false);
1845cdf0e10cSrcweir     {
1846cdf0e10cSrcweir         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
1847cdf0e10cSrcweir 
1848cdf0e10cSrcweir         SwTableFmlUpdate aMsgHnt( &rTbl );
1849cdf0e10cSrcweir         aMsgHnt.eFlags = TBL_BOXPTR;
1850cdf0e10cSrcweir         UpdateTblFlds( &aMsgHnt );
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir         bRet = rTbl.InsertRow( this, rBoxes, nCnt, bBehind );
1853cdf0e10cSrcweir         if (bRet)
1854cdf0e10cSrcweir         {
1855cdf0e10cSrcweir             SetModified();
1856cdf0e10cSrcweir             ::ClearFEShellTabCols();
1857cdf0e10cSrcweir             SetFieldsDirty( true, NULL, 0 );
1858cdf0e10cSrcweir         }
1859cdf0e10cSrcweir     }
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir 	if( pUndo )
1862cdf0e10cSrcweir     {
1863cdf0e10cSrcweir 		if( bRet )
1864cdf0e10cSrcweir         {
1865cdf0e10cSrcweir 			pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
1866cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
1867cdf0e10cSrcweir         }
1868cdf0e10cSrcweir         else
1869cdf0e10cSrcweir 			delete pUndo;
1870cdf0e10cSrcweir 	}
1871cdf0e10cSrcweir 	return bRet;
1872cdf0e10cSrcweir 
1873cdf0e10cSrcweir }
1874cdf0e10cSrcweir 
1875cdf0e10cSrcweir // ----- loeschen von Spalten/Zeilen ------------------------
1876cdf0e10cSrcweir 
DeleteRow(const SwCursor & rCursor)1877cdf0e10cSrcweir sal_Bool SwDoc::DeleteRow( const SwCursor& rCursor )
1878cdf0e10cSrcweir {
1879cdf0e10cSrcweir 	// lasse ueber das Layout die Boxen suchen
1880cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1881cdf0e10cSrcweir 	GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
1882cdf0e10cSrcweir 	if( ::HasProtectedCells( aBoxes ))
1883cdf0e10cSrcweir 		return sal_False;
1884cdf0e10cSrcweir 
1885cdf0e10cSrcweir 	// die Crsr aus dem Loeschbereich entfernen.
1886cdf0e10cSrcweir 	// Der Cursor steht danach:
1887cdf0e10cSrcweir 	//	- es folgt noch eine Zeile, in dieser
1888cdf0e10cSrcweir 	//	- vorher steht noch eine Zeile, in dieser
1889cdf0e10cSrcweir 	//	- sonst immer dahinter
1890cdf0e10cSrcweir 	{
1891cdf0e10cSrcweir 		SwTableNode* pTblNd = rCursor.GetNode()->FindTableNode();
1892cdf0e10cSrcweir 
1893cdf0e10cSrcweir 		if( pTblNd->GetTable().ISA( SwDDETable ))
1894cdf0e10cSrcweir 			return sal_False;
1895cdf0e10cSrcweir 
1896cdf0e10cSrcweir 		// suche alle Boxen / Lines
1897cdf0e10cSrcweir 		_FndBox aFndBox( 0, 0 );
1898cdf0e10cSrcweir 		{
1899cdf0e10cSrcweir 			_FndPara aPara( aBoxes, &aFndBox );
1900cdf0e10cSrcweir 			pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
1901cdf0e10cSrcweir 		}
1902cdf0e10cSrcweir 
1903cdf0e10cSrcweir 		if( !aFndBox.GetLines().Count() )
1904cdf0e10cSrcweir 			return sal_False;
1905cdf0e10cSrcweir 
1906cdf0e10cSrcweir 		SwEditShell* pESh = GetEditShell();
1907cdf0e10cSrcweir 		if( pESh )
1908cdf0e10cSrcweir 		{
1909cdf0e10cSrcweir 			pESh->KillPams();
1910cdf0e10cSrcweir 			// JP: eigentlich sollte man ueber alle Shells iterieren!!
1911cdf0e10cSrcweir 		}
1912cdf0e10cSrcweir 
1913cdf0e10cSrcweir 		_FndBox* pFndBox = &aFndBox;
1914cdf0e10cSrcweir 		while( 1 == pFndBox->GetLines().Count() &&
1915cdf0e10cSrcweir 				1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
1916cdf0e10cSrcweir 		{
1917cdf0e10cSrcweir 			_FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0];
1918cdf0e10cSrcweir 			if( pTmp->GetBox()->GetSttNd() )
1919cdf0e10cSrcweir 				break;		// das ist sonst zu weit
1920cdf0e10cSrcweir 			pFndBox = pTmp;
1921cdf0e10cSrcweir 		}
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir 		SwTableLine* pDelLine = pFndBox->GetLines()[
1924cdf0e10cSrcweir 						pFndBox->GetLines().Count()-1 ]->GetLine();
1925cdf0e10cSrcweir 		SwTableBox* pDelBox = pDelLine->GetTabBoxes()[
1926cdf0e10cSrcweir 							pDelLine->GetTabBoxes().Count() - 1 ];
1927cdf0e10cSrcweir 		while( !pDelBox->GetSttNd() )
1928cdf0e10cSrcweir 		{
1929cdf0e10cSrcweir 			SwTableLine* pLn = pDelBox->GetTabLines()[
1930cdf0e10cSrcweir 						pDelBox->GetTabLines().Count()-1 ];
1931cdf0e10cSrcweir 			pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
1932cdf0e10cSrcweir 		}
1933cdf0e10cSrcweir 		SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
1934cdf0e10cSrcweir 														pDelBox, sal_True );
1935cdf0e10cSrcweir 		while( pNextBox &&
1936cdf0e10cSrcweir 				pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
1937cdf0e10cSrcweir 			pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
1938cdf0e10cSrcweir 
1939cdf0e10cSrcweir 		if( !pNextBox )			// keine nachfolgende? dann die vorhergehende
1940cdf0e10cSrcweir 		{
1941cdf0e10cSrcweir 			pDelLine = pFndBox->GetLines()[ 0 ]->GetLine();
1942cdf0e10cSrcweir 			pDelBox = pDelLine->GetTabBoxes()[ 0 ];
1943cdf0e10cSrcweir 			while( !pDelBox->GetSttNd() )
1944cdf0e10cSrcweir 				pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
1945cdf0e10cSrcweir 			pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
1946cdf0e10cSrcweir 														pDelBox, sal_True );
1947cdf0e10cSrcweir 			while( pNextBox &&
1948cdf0e10cSrcweir 					pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
1949cdf0e10cSrcweir 				pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
1950cdf0e10cSrcweir 		}
1951cdf0e10cSrcweir 
1952cdf0e10cSrcweir 		sal_uLong nIdx;
1953cdf0e10cSrcweir 		if( pNextBox )		// dann den Cursor hier hinein
1954cdf0e10cSrcweir 			nIdx = pNextBox->GetSttIdx() + 1;
1955cdf0e10cSrcweir 		else				// ansonsten hinter die Tabelle
1956cdf0e10cSrcweir 			nIdx = pTblNd->EndOfSectionIndex() + 1;
1957cdf0e10cSrcweir 
1958cdf0e10cSrcweir 		SwNodeIndex aIdx( GetNodes(), nIdx );
1959cdf0e10cSrcweir 		SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
1960cdf0e10cSrcweir 		if( !pCNd )
1961cdf0e10cSrcweir 			pCNd = GetNodes().GoNext( &aIdx );
1962cdf0e10cSrcweir 
1963cdf0e10cSrcweir 		if( pCNd )
1964cdf0e10cSrcweir 		{
1965cdf0e10cSrcweir 			// die Cursor von der Shell oder den uebergebenen Cursor aendern?
1966cdf0e10cSrcweir 			SwPaM* pPam = (SwPaM*)&rCursor;
1967cdf0e10cSrcweir 			pPam->GetPoint()->nNode = aIdx;
1968cdf0e10cSrcweir 			pPam->GetPoint()->nContent.Assign( pCNd, 0 );
1969cdf0e10cSrcweir 			pPam->SetMark();			// beide wollen etwas davon haben
1970cdf0e10cSrcweir 			pPam->DeleteMark();
1971cdf0e10cSrcweir 		}
1972cdf0e10cSrcweir 	}
1973cdf0e10cSrcweir 
1974cdf0e10cSrcweir 	// dann loesche doch die Zeilen
1975cdf0e10cSrcweir 
1976cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo(UNDO_ROW_DELETE, NULL);
1977cdf0e10cSrcweir     sal_Bool bResult = DeleteRowCol( aBoxes );
1978cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo(UNDO_ROW_DELETE, NULL);
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir 	return bResult;
1981cdf0e10cSrcweir }
1982cdf0e10cSrcweir 
DeleteCol(const SwCursor & rCursor)1983cdf0e10cSrcweir sal_Bool SwDoc::DeleteCol( const SwCursor& rCursor )
1984cdf0e10cSrcweir {
1985cdf0e10cSrcweir 	// lasse ueber das Layout die Boxen suchen
1986cdf0e10cSrcweir 	SwSelBoxes aBoxes;
1987cdf0e10cSrcweir 	GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
1988cdf0e10cSrcweir 	if( ::HasProtectedCells( aBoxes ))
1989cdf0e10cSrcweir 		return sal_False;
1990cdf0e10cSrcweir 
1991cdf0e10cSrcweir 	// die Crsr muessen noch aus dem Loesch Bereich entfernt
1992cdf0e10cSrcweir 	// werden. Setze sie immer hinter/auf die Tabelle; ueber die
1993cdf0e10cSrcweir 	// Dokument-Position werden sie dann immer an die alte Position gesetzt.
1994cdf0e10cSrcweir 	SwEditShell* pESh = GetEditShell();
1995cdf0e10cSrcweir 	if( pESh )
1996cdf0e10cSrcweir 	{
1997cdf0e10cSrcweir 		const SwNode* pNd = rCursor.GetNode()->FindTableBoxStartNode();
1998cdf0e10cSrcweir 		pESh->ParkCrsr( SwNodeIndex( *pNd ) );
1999cdf0e10cSrcweir 	}
2000cdf0e10cSrcweir 
2001cdf0e10cSrcweir 	// dann loesche doch die Spalten
2002cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo(UNDO_COL_DELETE, NULL);
2003cdf0e10cSrcweir     sal_Bool bResult = DeleteRowCol( aBoxes, true );
2004cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo(UNDO_COL_DELETE, NULL);
2005cdf0e10cSrcweir 
2006cdf0e10cSrcweir 	return bResult;
2007cdf0e10cSrcweir }
2008cdf0e10cSrcweir 
DeleteRowCol(const SwSelBoxes & rBoxes,bool bColumn)2009cdf0e10cSrcweir sal_Bool SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn )
2010cdf0e10cSrcweir {
2011cdf0e10cSrcweir 	if( ::HasProtectedCells( rBoxes ))
2012cdf0e10cSrcweir 		return sal_False;
2013cdf0e10cSrcweir 
2014cdf0e10cSrcweir 	// uebers SwDoc fuer Undo !!
2015cdf0e10cSrcweir 	ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
2016cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
2017cdf0e10cSrcweir 	if( !pTblNd )
2018cdf0e10cSrcweir 		return sal_False;
2019cdf0e10cSrcweir 
2020cdf0e10cSrcweir 	if( pTblNd->GetTable().ISA( SwDDETable ))
2021cdf0e10cSrcweir 		return sal_False;
2022cdf0e10cSrcweir 
2023cdf0e10cSrcweir 	::ClearFEShellTabCols();
2024cdf0e10cSrcweir     SwSelBoxes aSelBoxes;
2025cdf0e10cSrcweir     aSelBoxes.Insert(rBoxes.GetData(), rBoxes.Count());
2026cdf0e10cSrcweir     SwTable &rTable = pTblNd->GetTable();
2027cdf0e10cSrcweir     long nMin = 0;
2028cdf0e10cSrcweir     long nMax = 0;
2029cdf0e10cSrcweir     if( rTable.IsNewModel() )
2030cdf0e10cSrcweir 	{
2031cdf0e10cSrcweir 		if( bColumn )
2032cdf0e10cSrcweir 			rTable.ExpandColumnSelection( aSelBoxes, nMin, nMax );
2033cdf0e10cSrcweir 		else
2034cdf0e10cSrcweir 			rTable.FindSuperfluousRows( aSelBoxes );
2035cdf0e10cSrcweir 	}
2036cdf0e10cSrcweir 
2037cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
2038cdf0e10cSrcweir 	lcl_DelRedlines aDelRedl( *pTblNd, sal_True );
2039cdf0e10cSrcweir #endif
2040cdf0e10cSrcweir 
2041cdf0e10cSrcweir 	// soll die gesamte Tabelle geloescht werden ??
2042cdf0e10cSrcweir 	const sal_uLong nTmpIdx1 = pTblNd->GetIndex();
2043cdf0e10cSrcweir 	const sal_uLong nTmpIdx2 = aSelBoxes[ aSelBoxes.Count()-1 ]->GetSttNd()->
2044cdf0e10cSrcweir 								EndOfSectionIndex()+1;
2045cdf0e10cSrcweir 	if( pTblNd->GetTable().GetTabSortBoxes().Count() == aSelBoxes.Count() &&
2046cdf0e10cSrcweir 		aSelBoxes[0]->GetSttIdx()-1 == nTmpIdx1 &&
2047cdf0e10cSrcweir 		nTmpIdx2 == pTblNd->EndOfSectionIndex() )
2048cdf0e10cSrcweir 	{
2049cdf0e10cSrcweir 		sal_Bool bNewTxtNd = sal_False;
2050cdf0e10cSrcweir 		// steht diese auch noch alleine in einem FlyFrame ?
2051cdf0e10cSrcweir 		SwNodeIndex aIdx( *pTblNd, -1 );
2052cdf0e10cSrcweir 		const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
2053cdf0e10cSrcweir 		if( pSttNd )
2054cdf0e10cSrcweir 		{
2055cdf0e10cSrcweir 			const sal_uLong nTblEnd = pTblNd->EndOfSectionIndex() + 1;
2056cdf0e10cSrcweir 			const sal_uLong nSectEnd = pSttNd->EndOfSectionIndex();
2057cdf0e10cSrcweir 			if( nTblEnd == nSectEnd )
2058cdf0e10cSrcweir 			{
2059cdf0e10cSrcweir 				if( SwFlyStartNode == pSttNd->GetStartNodeType() )
2060cdf0e10cSrcweir 				{
2061cdf0e10cSrcweir 					SwFrmFmt* pFmt = pSttNd->GetFlyFmt();
2062cdf0e10cSrcweir 					if( pFmt )
2063cdf0e10cSrcweir 					{
2064cdf0e10cSrcweir 						// Ok, das ist das gesuchte FlyFormat
2065cdf0e10cSrcweir 						DelLayoutFmt( pFmt );
2066cdf0e10cSrcweir 						return sal_True;
2067cdf0e10cSrcweir 					}
2068cdf0e10cSrcweir 				}
2069cdf0e10cSrcweir 				// kein Fly ?? also Kopf- oder Fusszeile: dann immer einen
2070cdf0e10cSrcweir 				// TextNode ueberig lassen.
2071cdf0e10cSrcweir 				// Undo koennen wir dann vergessen !!
2072cdf0e10cSrcweir 				bNewTxtNd = sal_True;
2073cdf0e10cSrcweir 			}
2074cdf0e10cSrcweir 		}
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir 		// kein Fly ?? also Kopf- oder Fusszeile: dann immer einen
2077cdf0e10cSrcweir 		// TextNode ueberig lassen.
2078cdf0e10cSrcweir 		aIdx++;
2079cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
2080cdf0e10cSrcweir         {
2081cdf0e10cSrcweir             GetIDocumentUndoRedo().ClearRedo();
2082cdf0e10cSrcweir 			SwPaM aPaM( *pTblNd->EndOfSectionNode(), aIdx.GetNode() );
2083cdf0e10cSrcweir 
2084cdf0e10cSrcweir 			if( bNewTxtNd )
2085cdf0e10cSrcweir 			{
2086cdf0e10cSrcweir 				const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
2087cdf0e10cSrcweir 				GetNodes().MakeTxtNode( aTmpIdx,
2088cdf0e10cSrcweir 							GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
2089cdf0e10cSrcweir 			}
2090cdf0e10cSrcweir 
2091cdf0e10cSrcweir             // save the cursors (UNO and otherwise)
2092cdf0e10cSrcweir             SwPaM aSavePaM( SwNodeIndex( *pTblNd->EndOfSectionNode() ) );
2093cdf0e10cSrcweir             if( ! aSavePaM.Move( fnMoveForward, fnGoNode ) )
2094cdf0e10cSrcweir             {
2095cdf0e10cSrcweir                 *aSavePaM.GetMark() = SwPosition( *pTblNd );
2096cdf0e10cSrcweir                 aSavePaM.Move( fnMoveBackward, fnGoNode );
2097cdf0e10cSrcweir             }
2098cdf0e10cSrcweir             {
2099cdf0e10cSrcweir                 SwPaM const tmpPaM(*pTblNd, *pTblNd->EndOfSectionNode());
2100cdf0e10cSrcweir                 ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
2101cdf0e10cSrcweir             }
2102cdf0e10cSrcweir 
2103cdf0e10cSrcweir 			// harte SeitenUmbrueche am nachfolgenden Node verschieben
2104cdf0e10cSrcweir 			sal_Bool bSavePageBreak = sal_False, bSavePageDesc = sal_False;
2105cdf0e10cSrcweir 			sal_uLong nNextNd = pTblNd->EndOfSectionIndex()+1;
2106cdf0e10cSrcweir 			SwCntntNode* pNextNd = GetNodes()[ nNextNd ]->GetCntntNode();
2107cdf0e10cSrcweir 			if( pNextNd )
2108cdf0e10cSrcweir 			{
2109cdf0e10cSrcweir //JP 24.08.98: will man wirklich den PageDesc/Break vom
2110cdf0e10cSrcweir //				nachfolgen Absatz ueberbuegeln?
2111cdf0e10cSrcweir //				const SwAttrSet& rAttrSet = pNextNd->GetSwAttrSet();
2112cdf0e10cSrcweir //				if( SFX_ITEM_SET != rAttrSet.GetItemState( RES_PAGEDESC ) &&
2113cdf0e10cSrcweir //					SFX_ITEM_SET != rAttrSet.GetItemState( RES_BREAK ))
2114cdf0e10cSrcweir 				{
2115cdf0e10cSrcweir 					SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
2116cdf0e10cSrcweir 					const SfxPoolItem *pItem;
2117cdf0e10cSrcweir 					if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
2118cdf0e10cSrcweir 						sal_False, &pItem ) )
2119cdf0e10cSrcweir 					{
2120cdf0e10cSrcweir 						pNextNd->SetAttr( *pItem );
2121cdf0e10cSrcweir 						bSavePageDesc = sal_True;
2122cdf0e10cSrcweir 					}
2123cdf0e10cSrcweir 
2124cdf0e10cSrcweir 					if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
2125cdf0e10cSrcweir 						sal_False, &pItem ) )
2126cdf0e10cSrcweir 					{
2127cdf0e10cSrcweir 						pNextNd->SetAttr( *pItem );
2128cdf0e10cSrcweir 						bSavePageBreak = sal_True;
2129cdf0e10cSrcweir 					}
2130cdf0e10cSrcweir 				}
2131cdf0e10cSrcweir 			}
2132cdf0e10cSrcweir 			SwUndoDelete* pUndo = new SwUndoDelete( aPaM );
2133cdf0e10cSrcweir 			if( bNewTxtNd )
2134cdf0e10cSrcweir 				pUndo->SetTblDelLastNd();
2135cdf0e10cSrcweir 			pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
2136cdf0e10cSrcweir             pUndo->SetTableName(pTblNd->GetTable().GetFrmFmt()->GetName());
2137cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
2138cdf0e10cSrcweir         }
2139cdf0e10cSrcweir         else
2140cdf0e10cSrcweir         {
2141cdf0e10cSrcweir 			if( bNewTxtNd )
2142cdf0e10cSrcweir 			{
2143cdf0e10cSrcweir 				const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
2144cdf0e10cSrcweir 				GetNodes().MakeTxtNode( aTmpIdx,
2145cdf0e10cSrcweir 							GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
2146cdf0e10cSrcweir 			}
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir             // save the cursors (UNO and otherwise)
2149cdf0e10cSrcweir             SwPaM aSavePaM( SwNodeIndex( *pTblNd->EndOfSectionNode() ) );
2150cdf0e10cSrcweir             if( ! aSavePaM.Move( fnMoveForward, fnGoNode ) )
2151cdf0e10cSrcweir             {
2152cdf0e10cSrcweir                 *aSavePaM.GetMark() = SwPosition( *pTblNd );
2153cdf0e10cSrcweir                 aSavePaM.Move( fnMoveBackward, fnGoNode );
2154cdf0e10cSrcweir             }
2155cdf0e10cSrcweir             {
2156cdf0e10cSrcweir                 SwPaM const tmpPaM(*pTblNd, *pTblNd->EndOfSectionNode());
2157cdf0e10cSrcweir                 ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
2158cdf0e10cSrcweir             }
2159cdf0e10cSrcweir 
2160cdf0e10cSrcweir 			// harte SeitenUmbrueche am nachfolgenden Node verschieben
2161cdf0e10cSrcweir 			SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
2162cdf0e10cSrcweir 			if( pNextNd )
2163cdf0e10cSrcweir 			{
2164cdf0e10cSrcweir 				SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
2165cdf0e10cSrcweir 				const SfxPoolItem *pItem;
2166cdf0e10cSrcweir 				if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
2167cdf0e10cSrcweir 					sal_False, &pItem ) )
2168cdf0e10cSrcweir 					pNextNd->SetAttr( *pItem );
2169cdf0e10cSrcweir 
2170cdf0e10cSrcweir 				if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
2171cdf0e10cSrcweir 					sal_False, &pItem ) )
2172cdf0e10cSrcweir 					pNextNd->SetAttr( *pItem );
2173cdf0e10cSrcweir 			}
2174cdf0e10cSrcweir 
2175cdf0e10cSrcweir 			pTblNd->DelFrms();
2176cdf0e10cSrcweir 			DeleteSection( pTblNd );
2177cdf0e10cSrcweir 		}
2178cdf0e10cSrcweir 		SetModified();
2179cdf0e10cSrcweir 		SetFieldsDirty( true, NULL, 0 );
2180cdf0e10cSrcweir 		return sal_True;
2181cdf0e10cSrcweir 	}
2182cdf0e10cSrcweir 
2183cdf0e10cSrcweir 	SwUndoTblNdsChg* pUndo = 0;
2184cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
2185cdf0e10cSrcweir     {
2186cdf0e10cSrcweir 		pUndo = new SwUndoTblNdsChg( UNDO_TABLE_DELBOX, aSelBoxes, *pTblNd,
2187cdf0e10cSrcweir                                      nMin, nMax, 0, sal_False, sal_False );
2188cdf0e10cSrcweir 	}
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir     bool bRet(false);
2191cdf0e10cSrcweir     {
2192cdf0e10cSrcweir         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2193cdf0e10cSrcweir 
2194cdf0e10cSrcweir         SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
2195cdf0e10cSrcweir         aMsgHnt.eFlags = TBL_BOXPTR;
2196cdf0e10cSrcweir         UpdateTblFlds( &aMsgHnt );
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir         if (rTable.IsNewModel())
2199cdf0e10cSrcweir         {
2200cdf0e10cSrcweir             if (bColumn)
2201cdf0e10cSrcweir                 rTable.PrepareDeleteCol( nMin, nMax );
2202cdf0e10cSrcweir             rTable.FindSuperfluousRows( aSelBoxes );
2203cdf0e10cSrcweir             if (pUndo)
2204cdf0e10cSrcweir                 pUndo->ReNewBoxes( aSelBoxes );
2205cdf0e10cSrcweir         }
2206cdf0e10cSrcweir         bRet = rTable.DeleteSel( this, aSelBoxes, 0, pUndo, sal_True, sal_True );
2207cdf0e10cSrcweir         if (bRet)
2208cdf0e10cSrcweir         {
2209cdf0e10cSrcweir             SetModified();
2210cdf0e10cSrcweir             SetFieldsDirty( true, NULL, 0 );
2211cdf0e10cSrcweir         }
2212cdf0e10cSrcweir     }
2213cdf0e10cSrcweir 
2214cdf0e10cSrcweir 	if( pUndo )
2215cdf0e10cSrcweir     {
2216cdf0e10cSrcweir 		if( bRet )
2217cdf0e10cSrcweir         {
2218cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
2219cdf0e10cSrcweir         }
2220cdf0e10cSrcweir         else
2221cdf0e10cSrcweir 			delete pUndo;
2222cdf0e10cSrcweir 	}
2223cdf0e10cSrcweir 
2224cdf0e10cSrcweir 	return bRet;
2225cdf0e10cSrcweir }
2226cdf0e10cSrcweir 
2227cdf0e10cSrcweir 
2228cdf0e10cSrcweir // ---------- teilen / zusammenfassen von Boxen in der Tabelle --------
2229cdf0e10cSrcweir 
SplitTbl(const SwSelBoxes & rBoxes,sal_Bool bVert,sal_uInt16 nCnt,sal_Bool bSameHeight)2230cdf0e10cSrcweir sal_Bool SwDoc::SplitTbl( const SwSelBoxes& rBoxes, sal_Bool bVert, sal_uInt16 nCnt,
2231cdf0e10cSrcweir                       sal_Bool bSameHeight )
2232cdf0e10cSrcweir {
2233cdf0e10cSrcweir 	// uebers SwDoc fuer Undo !!
2234cdf0e10cSrcweir 	ASSERT( rBoxes.Count() && nCnt, "keine gueltige Box-Liste" );
2235cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
2236cdf0e10cSrcweir 	if( !pTblNd )
2237cdf0e10cSrcweir 		return sal_False;
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir 	SwTable& rTbl = pTblNd->GetTable();
2240cdf0e10cSrcweir 	if( rTbl.ISA( SwDDETable ))
2241cdf0e10cSrcweir 		return sal_False;
2242cdf0e10cSrcweir 
2243cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
2244cdf0e10cSrcweir 	lcl_DelRedlines aDelRedl( *pTblNd, sal_True );
2245cdf0e10cSrcweir #endif
2246cdf0e10cSrcweir 
2247cdf0e10cSrcweir 	SvULongs aNdsCnts;
2248cdf0e10cSrcweir 	SwTableSortBoxes aTmpLst( 0, 5 );
2249cdf0e10cSrcweir 	SwUndoTblNdsChg* pUndo = 0;
2250cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
2251cdf0e10cSrcweir     {
2252cdf0e10cSrcweir         pUndo = new SwUndoTblNdsChg( UNDO_TABLE_SPLIT, rBoxes, *pTblNd, 0, 0,
2253cdf0e10cSrcweir                                      nCnt, bVert, bSameHeight );
2254cdf0e10cSrcweir 
2255cdf0e10cSrcweir 		aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );
2256cdf0e10cSrcweir 		if( !bVert )
2257cdf0e10cSrcweir 		{
2258cdf0e10cSrcweir 			for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
2259cdf0e10cSrcweir 			{
2260cdf0e10cSrcweir 				const SwStartNode* pSttNd = rBoxes[ n ]->GetSttNd();
2261cdf0e10cSrcweir 				aNdsCnts.Insert( pSttNd->EndOfSectionIndex() -
2262cdf0e10cSrcweir 								 pSttNd->GetIndex(), n );
2263cdf0e10cSrcweir 			}
2264cdf0e10cSrcweir 		}
2265cdf0e10cSrcweir 	}
2266cdf0e10cSrcweir 
2267cdf0e10cSrcweir     bool bRet(false);
2268cdf0e10cSrcweir     {
2269cdf0e10cSrcweir         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2270cdf0e10cSrcweir 
2271cdf0e10cSrcweir         SwTableFmlUpdate aMsgHnt( &rTbl );
2272cdf0e10cSrcweir         aMsgHnt.eFlags = TBL_BOXPTR;
2273cdf0e10cSrcweir         UpdateTblFlds( &aMsgHnt );
2274cdf0e10cSrcweir 
2275cdf0e10cSrcweir         if (bVert)
2276cdf0e10cSrcweir             bRet = rTbl.SplitCol( this, rBoxes, nCnt );
2277cdf0e10cSrcweir         else
2278cdf0e10cSrcweir             bRet = rTbl.SplitRow( this, rBoxes, nCnt, bSameHeight );
2279cdf0e10cSrcweir 
2280cdf0e10cSrcweir         if (bRet)
2281cdf0e10cSrcweir         {
2282cdf0e10cSrcweir             SetModified();
2283cdf0e10cSrcweir             SetFieldsDirty( true, NULL, 0 );
2284cdf0e10cSrcweir         }
2285cdf0e10cSrcweir     }
2286cdf0e10cSrcweir 
2287cdf0e10cSrcweir 	if( pUndo )
2288cdf0e10cSrcweir 	{
2289cdf0e10cSrcweir 		if( bRet )
2290cdf0e10cSrcweir 		{
2291cdf0e10cSrcweir 			if( bVert )
2292cdf0e10cSrcweir 				pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
2293cdf0e10cSrcweir 			else
2294cdf0e10cSrcweir 				pUndo->SaveNewBoxes( *pTblNd, aTmpLst, rBoxes, aNdsCnts );
2295cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
2296cdf0e10cSrcweir         }
2297cdf0e10cSrcweir         else
2298cdf0e10cSrcweir 			delete pUndo;
2299cdf0e10cSrcweir 	}
2300cdf0e10cSrcweir 
2301cdf0e10cSrcweir 	return bRet;
2302cdf0e10cSrcweir }
2303cdf0e10cSrcweir 
2304cdf0e10cSrcweir 
MergeTbl(SwPaM & rPam)2305cdf0e10cSrcweir sal_uInt16 SwDoc::MergeTbl( SwPaM& rPam )
2306cdf0e10cSrcweir {
2307cdf0e10cSrcweir 	// pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
2308cdf0e10cSrcweir 	SwTableNode* pTblNd = rPam.GetNode()->FindTableNode();
2309cdf0e10cSrcweir 	if( !pTblNd )
2310cdf0e10cSrcweir 		return TBLMERGE_NOSELECTION;
2311cdf0e10cSrcweir     SwTable& rTable = pTblNd->GetTable();
2312cdf0e10cSrcweir     if( rTable.ISA(SwDDETable) )
2313cdf0e10cSrcweir 		return TBLMERGE_NOSELECTION;
2314cdf0e10cSrcweir 	sal_uInt16 nRet = TBLMERGE_NOSELECTION;
2315cdf0e10cSrcweir     if( !rTable.IsNewModel() )
2316cdf0e10cSrcweir     {
2317cdf0e10cSrcweir         nRet =::CheckMergeSel( rPam );
2318cdf0e10cSrcweir         if( TBLMERGE_OK != nRet )
2319cdf0e10cSrcweir             return nRet;
2320cdf0e10cSrcweir         nRet = TBLMERGE_NOSELECTION;
2321cdf0e10cSrcweir     }
2322cdf0e10cSrcweir 
2323cdf0e10cSrcweir     // --> FME 2004-10-08 #i33394#
2324cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_MERGE, NULL );
2325cdf0e10cSrcweir     // <--
2326cdf0e10cSrcweir 
2327cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
2328cdf0e10cSrcweir 	if( !IsIgnoreRedline() && GetRedlineTbl().Count() )
2329cdf0e10cSrcweir 		DeleteRedline( *pTblNd, true, USHRT_MAX );
2330cdf0e10cSrcweir #endif
2331cdf0e10cSrcweir 	RedlineMode_t eOld = GetRedlineMode();
2332cdf0e10cSrcweir 	SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
2333cdf0e10cSrcweir 
2334cdf0e10cSrcweir     SwUndoTblMerge *const pUndo( (GetIDocumentUndoRedo().DoesUndo())
2335cdf0e10cSrcweir         ?   new SwUndoTblMerge( rPam )
2336cdf0e10cSrcweir         :   0 );
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir 	// lasse ueber das Layout die Boxen suchen
2339cdf0e10cSrcweir 	SwSelBoxes aBoxes;
2340cdf0e10cSrcweir     SwSelBoxes aMerged;
2341cdf0e10cSrcweir 	SwTableBox* pMergeBox;
2342cdf0e10cSrcweir 
2343cdf0e10cSrcweir 	if( !rTable.PrepareMerge( rPam, aBoxes, aMerged, &pMergeBox, pUndo ) )
2344cdf0e10cSrcweir 	{   // no cells found to merge
2345cdf0e10cSrcweir 		SetRedlineMode_intern( eOld );
2346cdf0e10cSrcweir 		if( pUndo )
2347cdf0e10cSrcweir 		{
2348cdf0e10cSrcweir 			delete pUndo;
2349cdf0e10cSrcweir             SwUndoId nLastUndoId(UNDO_EMPTY);
2350cdf0e10cSrcweir             if (GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId)
2351cdf0e10cSrcweir                 && (UNDO_REDLINE == nLastUndoId))
2352cdf0e10cSrcweir             {
2353cdf0e10cSrcweir                 // FIXME: why is this horrible cleanup necessary?
2354cdf0e10cSrcweir                 SwUndoRedline *const pU = dynamic_cast<SwUndoRedline*>(
2355cdf0e10cSrcweir                         GetUndoManager().RemoveLastUndo());
2356cdf0e10cSrcweir 				if( pU->GetRedlSaveCount() )
2357cdf0e10cSrcweir                 {
2358cdf0e10cSrcweir                     SwEditShell *const pEditShell(GetEditShell(0));
2359cdf0e10cSrcweir                     OSL_ASSERT(pEditShell);
2360cdf0e10cSrcweir                     ::sw::UndoRedoContext context(*this, *pEditShell);
2361cdf0e10cSrcweir                     static_cast<SfxUndoAction *>(pU)->UndoWithContext(context);
2362cdf0e10cSrcweir                 }
2363cdf0e10cSrcweir 				delete pU;
2364cdf0e10cSrcweir 			}
2365cdf0e10cSrcweir 		}
2366cdf0e10cSrcweir 	}
2367cdf0e10cSrcweir 	else
2368cdf0e10cSrcweir 	{
2369cdf0e10cSrcweir 		// die PaMs muessen noch aus dem Loesch Bereich entfernt
2370cdf0e10cSrcweir 		// werden. Setze sie immer hinter/auf die Tabelle; ueber die
2371cdf0e10cSrcweir 		// Dokument-Position werden sie dann immer an die alte Position gesetzt.
2372cdf0e10cSrcweir 		// Erstmal einen Index auf die Parkposition merken, denn nach GetMergeSel
2373cdf0e10cSrcweir 		// komme ich nicht mehr dran.
2374cdf0e10cSrcweir 		{
2375cdf0e10cSrcweir 			rPam.DeleteMark();
2376cdf0e10cSrcweir 			rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
2377cdf0e10cSrcweir 			rPam.GetPoint()->nContent.Assign( 0, 0 );
2378cdf0e10cSrcweir 			rPam.SetMark();
2379cdf0e10cSrcweir 			rPam.DeleteMark();
2380cdf0e10cSrcweir 
2381cdf0e10cSrcweir 			SwPaM* pTmp = &rPam;
2382cdf0e10cSrcweir 			while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ))
2383cdf0e10cSrcweir 				for( int i = 0; i < 2; ++i )
2384cdf0e10cSrcweir 					pTmp->GetBound( (sal_Bool)i ) = *rPam.GetPoint();
2385cdf0e10cSrcweir 		}
2386cdf0e10cSrcweir 
2387cdf0e10cSrcweir 		// dann fuege sie zusammen
2388cdf0e10cSrcweir 		SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
2389cdf0e10cSrcweir 		aMsgHnt.eFlags = TBL_BOXPTR;
2390cdf0e10cSrcweir 		UpdateTblFlds( &aMsgHnt );
2391cdf0e10cSrcweir 
2392cdf0e10cSrcweir 		if( pTblNd->GetTable().Merge( this, aBoxes, aMerged, pMergeBox, pUndo ))
2393cdf0e10cSrcweir 		{
2394cdf0e10cSrcweir 			nRet = TBLMERGE_OK;
2395cdf0e10cSrcweir 			SetModified();
2396cdf0e10cSrcweir 			SetFieldsDirty( true, NULL, 0 );
2397cdf0e10cSrcweir 			if( pUndo )
2398cdf0e10cSrcweir             {
2399cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo( pUndo );
2400cdf0e10cSrcweir             }
2401cdf0e10cSrcweir         }
2402cdf0e10cSrcweir 		else if( pUndo )
2403cdf0e10cSrcweir 			delete pUndo;
2404cdf0e10cSrcweir 
2405cdf0e10cSrcweir 		rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
2406cdf0e10cSrcweir 		rPam.Move();
2407cdf0e10cSrcweir 
2408cdf0e10cSrcweir 		::ClearFEShellTabCols();
2409cdf0e10cSrcweir 		SetRedlineMode_intern( eOld );
2410cdf0e10cSrcweir 	}
2411cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo( UNDO_TABLE_MERGE, NULL );
2412cdf0e10cSrcweir 	return nRet;
2413cdf0e10cSrcweir }
2414cdf0e10cSrcweir 
2415cdf0e10cSrcweir 
2416cdf0e10cSrcweir 
2417cdf0e10cSrcweir // -------------------------------------------------------
2418cdf0e10cSrcweir 
2419cdf0e10cSrcweir //---------
2420cdf0e10cSrcweir // SwTableNode
2421cdf0e10cSrcweir //---------
2422cdf0e10cSrcweir 
SwTableNode(const SwNodeIndex & rIdx)2423cdf0e10cSrcweir SwTableNode::SwTableNode( const SwNodeIndex& rIdx )
2424cdf0e10cSrcweir 	: SwStartNode( rIdx, ND_TABLENODE )
2425cdf0e10cSrcweir {
2426cdf0e10cSrcweir 	pTable = new SwTable( 0 );
2427cdf0e10cSrcweir }
2428cdf0e10cSrcweir 
~SwTableNode()2429cdf0e10cSrcweir SwTableNode::~SwTableNode()
2430cdf0e10cSrcweir {
2431cdf0e10cSrcweir 	//don't forget to notify uno wrappers
2432cdf0e10cSrcweir 	SwFrmFmt* pTblFmt = GetTable().GetFrmFmt();
2433cdf0e10cSrcweir 	SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
2434cdf0e10cSrcweir 								pTblFmt );
2435cdf0e10cSrcweir 	pTblFmt->ModifyNotification( &aMsgHint, &aMsgHint );
2436cdf0e10cSrcweir 	DelFrms();
2437cdf0e10cSrcweir 	delete pTable;
2438cdf0e10cSrcweir }
2439cdf0e10cSrcweir 
MakeFrm(SwFrm * pSib)2440cdf0e10cSrcweir SwTabFrm *SwTableNode::MakeFrm( SwFrm* pSib )
2441cdf0e10cSrcweir {
2442cdf0e10cSrcweir 	return new SwTabFrm( *pTable, pSib );
2443cdf0e10cSrcweir }
2444cdf0e10cSrcweir 
2445cdf0e10cSrcweir //Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom
2446cdf0e10cSrcweir //Dokument. Die erzeugten Contentframes werden in das entsprechende
2447cdf0e10cSrcweir //Layout gehaengt.
MakeFrms(const SwNodeIndex & rIdx)2448cdf0e10cSrcweir void SwTableNode::MakeFrms(const SwNodeIndex & rIdx )
2449cdf0e10cSrcweir {
2450cdf0e10cSrcweir 	if( !GetTable().GetFrmFmt()->GetDepends())//gibt es ueberhaupt Frames ??
2451cdf0e10cSrcweir 		return;
2452cdf0e10cSrcweir 
2453cdf0e10cSrcweir 	SwFrm *pFrm, *pNew;
2454cdf0e10cSrcweir 	SwCntntNode * pNode = rIdx.GetNode().GetCntntNode();
2455cdf0e10cSrcweir 
2456cdf0e10cSrcweir 	ASSERT( pNode, "Kein Contentnode oder Copy-Node und neuer Node identisch.");
2457cdf0e10cSrcweir 
2458cdf0e10cSrcweir 	sal_Bool bBefore = rIdx < GetIndex();
2459cdf0e10cSrcweir 
2460cdf0e10cSrcweir 	SwNode2Layout aNode2Layout( *this, rIdx.GetIndex() );
2461cdf0e10cSrcweir 
2462cdf0e10cSrcweir 	while( 0 != (pFrm = aNode2Layout.NextFrm()) )
2463cdf0e10cSrcweir 	{
2464cdf0e10cSrcweir 		pNew = pNode->MakeFrm( pFrm );
2465cdf0e10cSrcweir 		// wird ein Node vorher oder nachher mit Frames versehen
2466cdf0e10cSrcweir 		if ( bBefore )
2467cdf0e10cSrcweir 			// der neue liegt vor mir
2468cdf0e10cSrcweir 			pNew->Paste( pFrm->GetUpper(), pFrm );
2469cdf0e10cSrcweir 		else
2470cdf0e10cSrcweir 			// der neue liegt hinter mir
2471cdf0e10cSrcweir 			pNew->Paste( pFrm->GetUpper(), pFrm->GetNext() );
2472cdf0e10cSrcweir 	}
2473cdf0e10cSrcweir }
2474cdf0e10cSrcweir 
2475cdf0e10cSrcweir //Fuer jede Shell einen TblFrm anlegen und vor den entsprechenden
2476cdf0e10cSrcweir //CntntFrm pasten.
2477cdf0e10cSrcweir 
MakeFrms(SwNodeIndex * pIdxBehind)2478cdf0e10cSrcweir void SwTableNode::MakeFrms( SwNodeIndex* pIdxBehind )
2479cdf0e10cSrcweir {
2480cdf0e10cSrcweir 	ASSERT( pIdxBehind, "kein Index" );
2481cdf0e10cSrcweir 	*pIdxBehind = *this;
2482cdf0e10cSrcweir 	SwNode *pNd = GetNodes().FindPrvNxtFrmNode( *pIdxBehind, EndOfSectionNode() );
2483cdf0e10cSrcweir 	if( !pNd )
2484cdf0e10cSrcweir 		return ;
2485cdf0e10cSrcweir 
2486cdf0e10cSrcweir     SwFrm *pFrm( 0L );
2487cdf0e10cSrcweir 	SwLayoutFrm *pUpper( 0L );
2488cdf0e10cSrcweir 	SwNode2Layout aNode2Layout( *pNd, GetIndex() );
2489cdf0e10cSrcweir 	while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, *this )) )
2490cdf0e10cSrcweir 	{
2491cdf0e10cSrcweir         SwTabFrm* pNew = MakeFrm( pUpper );
2492cdf0e10cSrcweir 		pNew->Paste( pUpper, pFrm );
2493cdf0e10cSrcweir         // --> OD 2005-12-01 #i27138#
2494cdf0e10cSrcweir         // notify accessibility paragraphs objects about changed
2495cdf0e10cSrcweir         // CONTENT_FLOWS_FROM/_TO relation.
2496cdf0e10cSrcweir         // Relation CONTENT_FLOWS_FROM for next paragraph will change
2497cdf0e10cSrcweir         // and relation CONTENT_FLOWS_TO for previous paragraph will change.
2498cdf0e10cSrcweir         {
2499cdf0e10cSrcweir             ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
2500cdf0e10cSrcweir             if ( pViewShell && pViewShell->GetLayout() &&
2501cdf0e10cSrcweir                  pViewShell->GetLayout()->IsAnyShellAccessible() )
2502cdf0e10cSrcweir             {
2503cdf0e10cSrcweir                 pViewShell->InvalidateAccessibleParaFlowRelation(
2504cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
2505cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
2506cdf0e10cSrcweir             }
2507cdf0e10cSrcweir         }
2508cdf0e10cSrcweir         // <--
2509cdf0e10cSrcweir         ((SwTabFrm*)pNew)->RegistFlys();
2510cdf0e10cSrcweir 	}
2511cdf0e10cSrcweir }
2512cdf0e10cSrcweir 
DelFrms()2513cdf0e10cSrcweir void SwTableNode::DelFrms()
2514cdf0e10cSrcweir {
2515cdf0e10cSrcweir 	//Erstmal die TabFrms ausschneiden und deleten, die Columns und Rows
2516cdf0e10cSrcweir 	//nehmen sie mit in's Grab.
2517cdf0e10cSrcweir 	//Die TabFrms haengen am FrmFmt des SwTable.
2518cdf0e10cSrcweir 	//Sie muessen etwas umstaendlich zerstort werden, damit die Master
2519cdf0e10cSrcweir 	//die Follows mit in's Grab nehmen.
2520cdf0e10cSrcweir 
2521cdf0e10cSrcweir 	SwIterator<SwTabFrm,SwFmt> aIter( *(pTable->GetFrmFmt()) );
2522cdf0e10cSrcweir 	SwTabFrm *pFrm = aIter.First();
2523cdf0e10cSrcweir 	while ( pFrm )
2524cdf0e10cSrcweir 	{
2525cdf0e10cSrcweir 		sal_Bool bAgain = sal_False;
2526cdf0e10cSrcweir 		{
2527cdf0e10cSrcweir 			if ( !pFrm->IsFollow() )
2528cdf0e10cSrcweir 			{
2529cdf0e10cSrcweir 				while ( pFrm->HasFollow() )
2530cdf0e10cSrcweir 					pFrm->JoinAndDelFollows();
2531cdf0e10cSrcweir                 // --> OD 2005-12-01 #i27138#
2532cdf0e10cSrcweir                 // notify accessibility paragraphs objects about changed
2533cdf0e10cSrcweir                 // CONTENT_FLOWS_FROM/_TO relation.
2534cdf0e10cSrcweir                 // Relation CONTENT_FLOWS_FROM for current next paragraph will change
2535cdf0e10cSrcweir                 // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
2536cdf0e10cSrcweir                 {
2537cdf0e10cSrcweir                     ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
2538cdf0e10cSrcweir                     if ( pViewShell && pViewShell->GetLayout() &&
2539cdf0e10cSrcweir                          pViewShell->GetLayout()->IsAnyShellAccessible() )
2540cdf0e10cSrcweir                     {
2541cdf0e10cSrcweir                         pViewShell->InvalidateAccessibleParaFlowRelation(
2542cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
2543cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
2544cdf0e10cSrcweir                     }
2545cdf0e10cSrcweir                 }
2546cdf0e10cSrcweir                 // <--
2547cdf0e10cSrcweir                 pFrm->Cut();
2548cdf0e10cSrcweir 				delete pFrm;
2549cdf0e10cSrcweir 				bAgain = sal_True;
2550cdf0e10cSrcweir 			}
2551cdf0e10cSrcweir 		}
2552cdf0e10cSrcweir 		pFrm = bAgain ? aIter.First() : aIter.Next();
2553cdf0e10cSrcweir 	}
2554cdf0e10cSrcweir }
2555cdf0e10cSrcweir 
2556cdf0e10cSrcweir 
SetNewTable(SwTable * pNewTable,sal_Bool bNewFrames)2557cdf0e10cSrcweir void SwTableNode::SetNewTable( SwTable* pNewTable, sal_Bool bNewFrames )
2558cdf0e10cSrcweir {
2559cdf0e10cSrcweir 	DelFrms();
2560cdf0e10cSrcweir 	delete pTable;
2561cdf0e10cSrcweir 	pTable = pNewTable;
2562cdf0e10cSrcweir 	if( bNewFrames )
2563cdf0e10cSrcweir 	{
2564cdf0e10cSrcweir 		SwNodeIndex aIdx( *EndOfSectionNode());
2565cdf0e10cSrcweir 		GetNodes().GoNext( &aIdx );
2566cdf0e10cSrcweir 		MakeFrms( &aIdx );
2567cdf0e10cSrcweir 	}
2568cdf0e10cSrcweir }
2569cdf0e10cSrcweir 
GetTabCols(SwTabCols & rFill,const SwCursor * pCrsr,const SwCellFrm * pBoxFrm) const2570cdf0e10cSrcweir void SwDoc::GetTabCols( SwTabCols &rFill, const SwCursor* pCrsr,
2571cdf0e10cSrcweir 						const SwCellFrm* pBoxFrm ) const
2572cdf0e10cSrcweir {
2573cdf0e10cSrcweir 	const SwTableBox* pBox = 0;
2574cdf0e10cSrcweir 	SwTabFrm *pTab = 0;
2575cdf0e10cSrcweir 
2576cdf0e10cSrcweir 	if( pBoxFrm )
2577cdf0e10cSrcweir 	{
2578cdf0e10cSrcweir 		pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
2579cdf0e10cSrcweir 		pBox = pBoxFrm->GetTabBox();
2580cdf0e10cSrcweir 	}
2581cdf0e10cSrcweir 	else if( pCrsr )
2582cdf0e10cSrcweir 	{
2583cdf0e10cSrcweir 		const SwCntntNode* pCNd = pCrsr->GetCntntNode();
2584cdf0e10cSrcweir 		if( !pCNd )
2585cdf0e10cSrcweir 			return ;
2586cdf0e10cSrcweir 
2587cdf0e10cSrcweir 		Point aPt;
2588cdf0e10cSrcweir         const SwShellCrsr *pShCrsr = dynamic_cast<const SwShellCrsr*>(pCrsr);
2589cdf0e10cSrcweir 		if( pShCrsr )
2590cdf0e10cSrcweir 			aPt = pShCrsr->GetPtPos();
2591cdf0e10cSrcweir 
2592cdf0e10cSrcweir 		const SwFrm* pTmpFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
2593cdf0e10cSrcweir 		do {
2594cdf0e10cSrcweir 			pTmpFrm = pTmpFrm->GetUpper();
2595cdf0e10cSrcweir 		} while ( !pTmpFrm->IsCellFrm() );
2596cdf0e10cSrcweir 
2597cdf0e10cSrcweir 		pBoxFrm = (SwCellFrm*)pTmpFrm;
2598cdf0e10cSrcweir 		pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
2599cdf0e10cSrcweir 		pBox = pBoxFrm->GetTabBox();
2600cdf0e10cSrcweir 	}
2601cdf0e10cSrcweir 	else if( !pCrsr && !pBoxFrm )
2602cdf0e10cSrcweir 	{
2603cdf0e10cSrcweir 		ASSERT( !this, "einer von beiden muss angegeben werden!" );
2604cdf0e10cSrcweir 		return ;
2605cdf0e10cSrcweir 	}
2606cdf0e10cSrcweir 
2607cdf0e10cSrcweir 	//Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
2608cdf0e10cSrcweir     SWRECTFN( pTab )
2609cdf0e10cSrcweir     const SwPageFrm* pPage = pTab->FindPageFrm();
2610cdf0e10cSrcweir     const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
2611cdf0e10cSrcweir                            (pPage->Frm().*fnRect->fnGetLeft)();
2612cdf0e10cSrcweir     const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
2613cdf0e10cSrcweir                             (pPage->Frm().*fnRect->fnGetLeft)();
2614cdf0e10cSrcweir 
2615cdf0e10cSrcweir     rFill.SetLeftMin ( nLeftMin );
2616cdf0e10cSrcweir     rFill.SetLeft    ( (pTab->Prt().*fnRect->fnGetLeft)() );
2617cdf0e10cSrcweir     rFill.SetRight   ( (pTab->Prt().*fnRect->fnGetRight)());
2618cdf0e10cSrcweir     rFill.SetRightMax( nRightMax - nLeftMin );
2619cdf0e10cSrcweir 
2620cdf0e10cSrcweir 	pTab->GetTable()->GetTabCols( rFill, pBox );
2621cdf0e10cSrcweir }
2622cdf0e10cSrcweir 
2623cdf0e10cSrcweir //
2624cdf0e10cSrcweir // Here are some little helpers used in SwDoc::GetTabRows
2625cdf0e10cSrcweir //
2626cdf0e10cSrcweir 
2627cdf0e10cSrcweir #define ROWFUZZY 25
2628cdf0e10cSrcweir 
2629cdf0e10cSrcweir struct FuzzyCompare
2630cdf0e10cSrcweir {
2631cdf0e10cSrcweir     bool operator() ( long s1, long s2 ) const;
2632cdf0e10cSrcweir };
2633cdf0e10cSrcweir 
operator ()(long s1,long s2) const2634cdf0e10cSrcweir bool FuzzyCompare::operator() ( long s1, long s2 ) const
2635cdf0e10cSrcweir {
2636cdf0e10cSrcweir     return ( s1 < s2 && abs( s1 - s2 ) > ROWFUZZY );
2637cdf0e10cSrcweir }
2638cdf0e10cSrcweir 
lcl_IsFrmInColumn(const SwCellFrm & rFrm,SwSelBoxes & rBoxes)2639cdf0e10cSrcweir bool lcl_IsFrmInColumn( const SwCellFrm& rFrm, SwSelBoxes& rBoxes )
2640cdf0e10cSrcweir {
2641cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
2642cdf0e10cSrcweir     {
2643cdf0e10cSrcweir         if ( rFrm.GetTabBox() == rBoxes[ i ] )
2644cdf0e10cSrcweir             return true;
2645cdf0e10cSrcweir     }
2646cdf0e10cSrcweir 
2647cdf0e10cSrcweir     return false;
2648cdf0e10cSrcweir }
2649cdf0e10cSrcweir 
2650cdf0e10cSrcweir //
2651cdf0e10cSrcweir // SwDoc::GetTabRows()
2652cdf0e10cSrcweir //
2653cdf0e10cSrcweir 
GetTabRows(SwTabCols & rFill,const SwCursor *,const SwCellFrm * pBoxFrm) const2654cdf0e10cSrcweir void SwDoc::GetTabRows( SwTabCols &rFill, const SwCursor* ,
2655cdf0e10cSrcweir 						const SwCellFrm* pBoxFrm ) const
2656cdf0e10cSrcweir {
2657cdf0e10cSrcweir     ASSERT( pBoxFrm, "GetTabRows called without pBoxFrm" )
2658cdf0e10cSrcweir 
2659cdf0e10cSrcweir     // --> FME 2005-09-12 #121591# Make code robust:
2660cdf0e10cSrcweir     if ( !pBoxFrm )
2661cdf0e10cSrcweir         return;
2662cdf0e10cSrcweir     // <--
2663cdf0e10cSrcweir 
2664cdf0e10cSrcweir     // --> FME 2005-01-06 #i39552# Collection of the boxes of the current
2665cdf0e10cSrcweir     // column has to be done at the beginning of this function, because
2666cdf0e10cSrcweir     // the table may be formatted in ::GetTblSel.
2667cdf0e10cSrcweir     SwDeletionChecker aDelCheck( pBoxFrm );
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir     SwSelBoxes aBoxes;
2670cdf0e10cSrcweir     const SwCntntFrm* pCntnt = ::GetCellCntnt( *pBoxFrm );
2671cdf0e10cSrcweir     if ( pCntnt && pCntnt->IsTxtFrm() )
2672cdf0e10cSrcweir     {
2673cdf0e10cSrcweir         const SwPosition aPos( *((SwTxtFrm*)pCntnt)->GetTxtNode() );
2674cdf0e10cSrcweir         const SwCursor aTmpCrsr( aPos, 0, false );
2675cdf0e10cSrcweir         ::GetTblSel( aTmpCrsr, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
2676cdf0e10cSrcweir     }
2677cdf0e10cSrcweir     // <--
2678cdf0e10cSrcweir 
2679cdf0e10cSrcweir     // --> FME 2005-09-12 #121591# Make code robust:
2680cdf0e10cSrcweir     if ( aDelCheck.HasBeenDeleted() )
2681cdf0e10cSrcweir     {
2682cdf0e10cSrcweir         ASSERT( false, "Current box has been deleted during GetTabRows()" )
2683cdf0e10cSrcweir         return;
2684cdf0e10cSrcweir     }
2685cdf0e10cSrcweir     // <--
2686cdf0e10cSrcweir 
2687cdf0e10cSrcweir     // --> FME 2005-09-12 #121591# Make code robust:
2688cdf0e10cSrcweir     const SwTabFrm* pTab = pBoxFrm->FindTabFrm();
2689cdf0e10cSrcweir     ASSERT( pTab, "GetTabRows called without a table" )
2690cdf0e10cSrcweir     if ( !pTab )
2691cdf0e10cSrcweir         return;
2692cdf0e10cSrcweir     // <--
2693cdf0e10cSrcweir 
2694cdf0e10cSrcweir     const SwFrm* pFrm = pTab->GetNextLayoutLeaf();
2695cdf0e10cSrcweir 
2696cdf0e10cSrcweir 	//Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
2697cdf0e10cSrcweir     SWRECTFN( pTab )
2698cdf0e10cSrcweir     const SwPageFrm* pPage = pTab->FindPageFrm();
2699cdf0e10cSrcweir     const long nLeftMin  = ( bVert ?
2700cdf0e10cSrcweir                              pTab->GetPrtLeft() - pPage->Frm().Left() :
2701cdf0e10cSrcweir                              pTab->GetPrtTop() - pPage->Frm().Top() );
2702cdf0e10cSrcweir     const long nLeft     = bVert ? LONG_MAX : 0;
2703cdf0e10cSrcweir     const long nRight    = (pTab->Prt().*fnRect->fnGetHeight)();
2704cdf0e10cSrcweir     const long nRightMax = bVert ? nRight : LONG_MAX;
2705cdf0e10cSrcweir 
2706cdf0e10cSrcweir     rFill.SetLeftMin( nLeftMin );
2707cdf0e10cSrcweir     rFill.SetLeft( nLeft );
2708cdf0e10cSrcweir     rFill.SetRight( nRight );
2709cdf0e10cSrcweir     rFill.SetRightMax( nRightMax );
2710cdf0e10cSrcweir 
2711cdf0e10cSrcweir     typedef std::map< long, std::pair< long, long >, FuzzyCompare > BoundaryMap;
2712cdf0e10cSrcweir     BoundaryMap aBoundaries;
2713cdf0e10cSrcweir     BoundaryMap::iterator aIter;
2714cdf0e10cSrcweir     std::pair< long, long > aPair;
2715cdf0e10cSrcweir 
2716cdf0e10cSrcweir     typedef std::map< long, bool > HiddenMap;
2717cdf0e10cSrcweir     HiddenMap aHidden;
2718cdf0e10cSrcweir     HiddenMap::iterator aHiddenIter;
2719cdf0e10cSrcweir 
2720cdf0e10cSrcweir     while ( pFrm && pTab->IsAnLower( pFrm ) )
2721cdf0e10cSrcweir     {
2722cdf0e10cSrcweir         if ( pFrm->IsCellFrm() && pFrm->FindTabFrm() == pTab )
2723cdf0e10cSrcweir         {
2724cdf0e10cSrcweir             // upper and lower borders of current cell frame:
2725cdf0e10cSrcweir             long nUpperBorder = (pFrm->Frm().*fnRect->fnGetTop)();
2726cdf0e10cSrcweir             long nLowerBorder = (pFrm->Frm().*fnRect->fnGetBottom)();
2727cdf0e10cSrcweir 
2728cdf0e10cSrcweir             // get boundaries for nUpperBorder:
2729cdf0e10cSrcweir             aIter = aBoundaries.find( nUpperBorder );
2730cdf0e10cSrcweir             if ( aIter == aBoundaries.end() )
2731cdf0e10cSrcweir             {
2732cdf0e10cSrcweir                 aPair.first = nUpperBorder; aPair.second = LONG_MAX;
2733cdf0e10cSrcweir                 aBoundaries[ nUpperBorder ] = aPair;
2734cdf0e10cSrcweir             }
2735cdf0e10cSrcweir 
2736cdf0e10cSrcweir             // get boundaries for nLowerBorder:
2737cdf0e10cSrcweir             aIter = aBoundaries.find( nLowerBorder );
2738cdf0e10cSrcweir             if ( aIter == aBoundaries.end() )
2739cdf0e10cSrcweir             {
2740cdf0e10cSrcweir                 aPair.first = nUpperBorder; aPair.second = LONG_MAX;
2741cdf0e10cSrcweir             }
2742cdf0e10cSrcweir             else
2743cdf0e10cSrcweir             {
2744cdf0e10cSrcweir                 nLowerBorder = (*aIter).first;
2745cdf0e10cSrcweir                 long nNewLowerBorderUpperBoundary = Max( (*aIter).second.first, nUpperBorder );
2746cdf0e10cSrcweir                 aPair.first = nNewLowerBorderUpperBoundary; aPair.second = LONG_MAX;
2747cdf0e10cSrcweir             }
2748cdf0e10cSrcweir             aBoundaries[ nLowerBorder ] = aPair;
2749cdf0e10cSrcweir 
2750cdf0e10cSrcweir             // calculate hidden flags for entry nUpperBorder/nLowerBorder:
2751cdf0e10cSrcweir             long nTmpVal = nUpperBorder;
2752cdf0e10cSrcweir             for ( sal_uInt8 i = 0; i < 2; ++i )
2753cdf0e10cSrcweir             {
2754cdf0e10cSrcweir                 aHiddenIter = aHidden.find( nTmpVal );
2755cdf0e10cSrcweir                 if ( aHiddenIter == aHidden.end() )
2756cdf0e10cSrcweir                     aHidden[ nTmpVal ] = !lcl_IsFrmInColumn( *((SwCellFrm*)pFrm), aBoxes );
2757cdf0e10cSrcweir                 else
2758cdf0e10cSrcweir                 {
2759cdf0e10cSrcweir                     if ( aHidden[ nTmpVal ] &&
2760cdf0e10cSrcweir                          lcl_IsFrmInColumn( *((SwCellFrm*)pFrm), aBoxes ) )
2761cdf0e10cSrcweir                         aHidden[ nTmpVal ] = false;
2762cdf0e10cSrcweir                 }
2763cdf0e10cSrcweir                 nTmpVal = nLowerBorder;
2764cdf0e10cSrcweir             }
2765cdf0e10cSrcweir         }
2766cdf0e10cSrcweir 
2767cdf0e10cSrcweir         pFrm = pFrm->GetNextLayoutLeaf();
2768cdf0e10cSrcweir     }
2769cdf0e10cSrcweir 
2770cdf0e10cSrcweir     // transfer calculated values from BoundaryMap and HiddenMap into rFill:
2771cdf0e10cSrcweir     sal_uInt16 nIdx = 0;
2772cdf0e10cSrcweir     for ( aIter = aBoundaries.begin(); aIter != aBoundaries.end(); ++aIter )
2773cdf0e10cSrcweir     {
2774cdf0e10cSrcweir         const long nTabTop = (pTab->*fnRect->fnGetPrtTop)();
2775cdf0e10cSrcweir         const long nKey = (*fnRect->fnYDiff)( (*aIter).first, nTabTop );
2776cdf0e10cSrcweir         const std::pair< long, long > aTmpPair = (*aIter).second;
2777cdf0e10cSrcweir         const long nFirst = (*fnRect->fnYDiff)( aTmpPair.first, nTabTop );
2778cdf0e10cSrcweir         const long nSecond = aTmpPair.second;
2779cdf0e10cSrcweir 
2780cdf0e10cSrcweir         aHiddenIter = aHidden.find( (*aIter).first );
2781cdf0e10cSrcweir         const bool bHidden = aHiddenIter != aHidden.end() && (*aHiddenIter).second;
2782cdf0e10cSrcweir         rFill.Insert( nKey, nFirst, nSecond, bHidden, nIdx++ );
2783cdf0e10cSrcweir     }
2784cdf0e10cSrcweir 
2785cdf0e10cSrcweir     // delete first and last entry
2786cdf0e10cSrcweir     ASSERT( rFill.Count(), "Deleting from empty vector. Fasten your seatbelts!" )
2787cdf0e10cSrcweir     // --> FME 2006-01-19 #i60818# There may be only one entry in rFill. Make
2788cdf0e10cSrcweir     // code robust by checking count of rFill.
2789cdf0e10cSrcweir     if ( rFill.Count() ) rFill.Remove( 0, 1 );
2790cdf0e10cSrcweir     if ( rFill.Count() ) rFill.Remove( rFill.Count() - 1 , 1 );
2791cdf0e10cSrcweir     // <--
2792cdf0e10cSrcweir     rFill.SetLastRowAllowedToChange( !pTab->HasFollowFlowLine() );
2793cdf0e10cSrcweir }
2794cdf0e10cSrcweir 
SetTabCols(const SwTabCols & rNew,sal_Bool bCurRowOnly,const SwCursor * pCrsr,const SwCellFrm * pBoxFrm)2795cdf0e10cSrcweir void SwDoc::SetTabCols( const SwTabCols &rNew, sal_Bool bCurRowOnly,
2796cdf0e10cSrcweir 						const SwCursor* pCrsr, const SwCellFrm* pBoxFrm )
2797cdf0e10cSrcweir {
2798cdf0e10cSrcweir 	const SwTableBox* pBox = 0;
2799cdf0e10cSrcweir 	SwTabFrm *pTab = 0;
2800cdf0e10cSrcweir 
2801cdf0e10cSrcweir 	if( pBoxFrm )
2802cdf0e10cSrcweir 	{
2803cdf0e10cSrcweir 		pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
2804cdf0e10cSrcweir 		pBox = pBoxFrm->GetTabBox();
2805cdf0e10cSrcweir 	}
2806cdf0e10cSrcweir 	else if( pCrsr )
2807cdf0e10cSrcweir 	{
2808cdf0e10cSrcweir 		const SwCntntNode* pCNd = pCrsr->GetCntntNode();
2809cdf0e10cSrcweir 		if( !pCNd )
2810cdf0e10cSrcweir 			return ;
2811cdf0e10cSrcweir 
2812cdf0e10cSrcweir 		Point aPt;
2813cdf0e10cSrcweir         const SwShellCrsr *pShCrsr = dynamic_cast<const SwShellCrsr*>(pCrsr);
2814cdf0e10cSrcweir 		if( pShCrsr )
2815cdf0e10cSrcweir 			aPt = pShCrsr->GetPtPos();
2816cdf0e10cSrcweir 
2817cdf0e10cSrcweir 		const SwFrm* pTmpFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
2818cdf0e10cSrcweir 		do {
2819cdf0e10cSrcweir 			pTmpFrm = pTmpFrm->GetUpper();
2820cdf0e10cSrcweir 		} while ( !pTmpFrm->IsCellFrm() );
2821cdf0e10cSrcweir 
2822cdf0e10cSrcweir 		pBoxFrm = (SwCellFrm*)pTmpFrm;
2823cdf0e10cSrcweir 		pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
2824cdf0e10cSrcweir 		pBox = pBoxFrm->GetTabBox();
2825cdf0e10cSrcweir 	}
2826cdf0e10cSrcweir 	else if( !pCrsr && !pBoxFrm )
2827cdf0e10cSrcweir 	{
2828cdf0e10cSrcweir 		ASSERT( !this, "einer von beiden muss angegeben werden!" );
2829cdf0e10cSrcweir 		return ;
2830cdf0e10cSrcweir 	}
2831cdf0e10cSrcweir 
2832cdf0e10cSrcweir 	// sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
2833cdf0e10cSrcweir 	// dann muss es jetzt auf absolute umgerechnet werden.
2834cdf0e10cSrcweir 	SwTable& rTab = *pTab->GetTable();
2835cdf0e10cSrcweir 	const SwFmtFrmSize& rTblFrmSz = rTab.GetFrmFmt()->GetFrmSize();
2836cdf0e10cSrcweir     SWRECTFN( pTab )
2837cdf0e10cSrcweir     // OD 06.08.2003 #i17174# - With fix for #i9040# the shadow size is taken
2838cdf0e10cSrcweir     // from the table width. Thus, add its left and right size to current table
2839cdf0e10cSrcweir     // printing area width in order to get the correct table size attribute.
2840cdf0e10cSrcweir     SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
2841cdf0e10cSrcweir     {
2842cdf0e10cSrcweir         SvxShadowItem aShadow( rTab.GetFrmFmt()->GetShadow() );
2843cdf0e10cSrcweir         nPrtWidth += aShadow.CalcShadowSpace( SHADOW_LEFT ) +
2844cdf0e10cSrcweir                      aShadow.CalcShadowSpace( SHADOW_RIGHT );
2845cdf0e10cSrcweir     }
2846cdf0e10cSrcweir     if( nPrtWidth != rTblFrmSz.GetWidth() )
2847cdf0e10cSrcweir 	{
2848cdf0e10cSrcweir 		SwFmtFrmSize aSz( rTblFrmSz );
2849cdf0e10cSrcweir         aSz.SetWidth( nPrtWidth );
2850cdf0e10cSrcweir         rTab.GetFrmFmt()->SetFmtAttr( aSz );
2851cdf0e10cSrcweir 	}
2852cdf0e10cSrcweir 
2853cdf0e10cSrcweir     SwTabCols aOld( rNew.Count() );
2854cdf0e10cSrcweir 
2855cdf0e10cSrcweir     const SwPageFrm* pPage = pTab->FindPageFrm();
2856cdf0e10cSrcweir     const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
2857cdf0e10cSrcweir                            (pPage->Frm().*fnRect->fnGetLeft)();
2858cdf0e10cSrcweir     const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
2859cdf0e10cSrcweir                             (pPage->Frm().*fnRect->fnGetLeft)();
2860cdf0e10cSrcweir 
2861cdf0e10cSrcweir     //Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
2862cdf0e10cSrcweir     aOld.SetLeftMin ( nLeftMin );
2863cdf0e10cSrcweir     aOld.SetLeft    ( (pTab->Prt().*fnRect->fnGetLeft)() );
2864cdf0e10cSrcweir     aOld.SetRight   ( (pTab->Prt().*fnRect->fnGetRight)());
2865cdf0e10cSrcweir     aOld.SetRightMax( nRightMax - nLeftMin );
2866cdf0e10cSrcweir 
2867cdf0e10cSrcweir     rTab.GetTabCols( aOld, pBox );
2868cdf0e10cSrcweir     SetTabCols(rTab, rNew, aOld, pBox, bCurRowOnly );
2869cdf0e10cSrcweir }
2870cdf0e10cSrcweir 
SetTabRows(const SwTabCols & rNew,sal_Bool bCurColOnly,const SwCursor *,const SwCellFrm * pBoxFrm)2871cdf0e10cSrcweir void SwDoc::SetTabRows( const SwTabCols &rNew, sal_Bool bCurColOnly, const SwCursor*,
2872cdf0e10cSrcweir                         const SwCellFrm* pBoxFrm )
2873cdf0e10cSrcweir {
2874cdf0e10cSrcweir 	const SwTableBox* pBox;
2875cdf0e10cSrcweir 	SwTabFrm *pTab;
2876cdf0e10cSrcweir 
2877cdf0e10cSrcweir     ASSERT( pBoxFrm, "SetTabRows called without pBoxFrm" )
2878cdf0e10cSrcweir 
2879cdf0e10cSrcweir 	pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
2880cdf0e10cSrcweir 	pBox = pBoxFrm->GetTabBox();
2881cdf0e10cSrcweir 
2882cdf0e10cSrcweir 	// sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
2883cdf0e10cSrcweir 	// dann muss es jetzt auf absolute umgerechnet werden.
2884cdf0e10cSrcweir     SWRECTFN( pTab )
2885cdf0e10cSrcweir 	SwTabCols aOld( rNew.Count() );
2886cdf0e10cSrcweir 
2887cdf0e10cSrcweir     //Fix-Punkte setzen, LeftMin in Dokumentkoordinaten die anderen relativ.
2888cdf0e10cSrcweir     const SwPageFrm* pPage = pTab->FindPageFrm();
2889cdf0e10cSrcweir 
2890cdf0e10cSrcweir     aOld.SetRight( (pTab->Prt().*fnRect->fnGetHeight)() );
2891cdf0e10cSrcweir     long nLeftMin;
2892cdf0e10cSrcweir     if ( bVert )
2893cdf0e10cSrcweir     {
2894cdf0e10cSrcweir         nLeftMin = pTab->GetPrtLeft() - pPage->Frm().Left();
2895cdf0e10cSrcweir         aOld.SetLeft    ( LONG_MAX );
2896cdf0e10cSrcweir         aOld.SetRightMax( aOld.GetRight() );
2897cdf0e10cSrcweir 
2898cdf0e10cSrcweir     }
2899cdf0e10cSrcweir     else
2900cdf0e10cSrcweir     {
2901cdf0e10cSrcweir         nLeftMin = pTab->GetPrtTop() - pPage->Frm().Top();
2902cdf0e10cSrcweir         aOld.SetLeft    ( 0 );
2903cdf0e10cSrcweir         aOld.SetRightMax( LONG_MAX );
2904cdf0e10cSrcweir     }
2905cdf0e10cSrcweir     aOld.SetLeftMin ( nLeftMin );
2906cdf0e10cSrcweir 
2907cdf0e10cSrcweir     GetTabRows( aOld, 0, pBoxFrm );
2908cdf0e10cSrcweir 
2909cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_ATTR, NULL );
2910cdf0e10cSrcweir 
2911cdf0e10cSrcweir     // check for differences between aOld and rNew:
2912cdf0e10cSrcweir     const sal_uInt16 nCount = rNew.Count();
2913cdf0e10cSrcweir     const SwTable* pTable = pTab->GetTable();
2914cdf0e10cSrcweir     ASSERT( pTable, "My colleague told me, this couldn't happen" );
2915cdf0e10cSrcweir 
2916cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i <= nCount; ++i )
2917cdf0e10cSrcweir     {
2918cdf0e10cSrcweir         const sal_uInt16 nIdxStt = bVert ? nCount - i : i - 1;
2919cdf0e10cSrcweir         const sal_uInt16 nIdxEnd = bVert ? nCount - i - 1 : i;
2920cdf0e10cSrcweir 
2921cdf0e10cSrcweir         const long nOldRowStart = i == 0  ? 0 : aOld[ nIdxStt ];
2922cdf0e10cSrcweir         const long nOldRowEnd =   i == nCount ? aOld.GetRight() : aOld[ nIdxEnd ];
2923cdf0e10cSrcweir         const long nOldRowHeight = nOldRowEnd - nOldRowStart;
2924cdf0e10cSrcweir 
2925cdf0e10cSrcweir         const long nNewRowStart = i == 0  ? 0 : rNew[ nIdxStt ];
2926cdf0e10cSrcweir         const long nNewRowEnd =   i == nCount ? rNew.GetRight() : rNew[ nIdxEnd ];
2927cdf0e10cSrcweir         const long nNewRowHeight = nNewRowEnd - nNewRowStart;
2928cdf0e10cSrcweir 
2929cdf0e10cSrcweir         const long nDiff = nNewRowHeight - nOldRowHeight;
2930cdf0e10cSrcweir         if ( abs( nDiff ) >= ROWFUZZY )
2931cdf0e10cSrcweir         {
2932cdf0e10cSrcweir             // For the old table model pTxtFrm and pLine will be set for every box.
2933cdf0e10cSrcweir             // For the new table model pTxtFrm will be set if the box is not covered,
2934cdf0e10cSrcweir             // but the pLine will be set if the box is not an overlapping box
2935cdf0e10cSrcweir             // In the new table model the row height can be adjusted,
2936cdf0e10cSrcweir             // when both variables are set.
2937cdf0e10cSrcweir             SwTxtFrm* pTxtFrm = 0;
2938cdf0e10cSrcweir             const SwTableLine* pLine = 0;
2939cdf0e10cSrcweir 
2940cdf0e10cSrcweir             // Iterate over all SwCellFrms with Bottom = nOldPos
2941cdf0e10cSrcweir             const SwFrm* pFrm = pTab->GetNextLayoutLeaf();
2942cdf0e10cSrcweir             while ( pFrm && pTab->IsAnLower( pFrm ) )
2943cdf0e10cSrcweir             {
2944cdf0e10cSrcweir                 if ( pFrm->IsCellFrm() && pFrm->FindTabFrm() == pTab )
2945cdf0e10cSrcweir                 {
2946cdf0e10cSrcweir                     const long nLowerBorder = (pFrm->Frm().*fnRect->fnGetBottom)();
2947cdf0e10cSrcweir                     const sal_uLong nTabTop = (pTab->*fnRect->fnGetPrtTop)();
2948cdf0e10cSrcweir                     if ( abs( (*fnRect->fnYInc)( nTabTop, nOldRowEnd ) - nLowerBorder ) <= ROWFUZZY )
2949cdf0e10cSrcweir                     {
2950cdf0e10cSrcweir                         if ( !bCurColOnly || pFrm == pBoxFrm )
2951cdf0e10cSrcweir                         {
2952cdf0e10cSrcweir                             const SwFrm* pCntnt = ::GetCellCntnt( static_cast<const SwCellFrm&>(*pFrm) );
2953cdf0e10cSrcweir 
2954cdf0e10cSrcweir                             if ( pCntnt && pCntnt->IsTxtFrm() )
2955cdf0e10cSrcweir                             {
2956cdf0e10cSrcweir                                 pBox = ((SwCellFrm*)pFrm)->GetTabBox();
2957cdf0e10cSrcweir                                 const long nRowSpan = pBox->getRowSpan();
2958cdf0e10cSrcweir                                 if( nRowSpan > 0 ) // Not overlapped
2959cdf0e10cSrcweir                                     pTxtFrm = (SwTxtFrm*)pCntnt;
2960cdf0e10cSrcweir                                 if( nRowSpan < 2 ) // Not overlapping for row height
2961cdf0e10cSrcweir                                     pLine = pBox->GetUpper();
2962cdf0e10cSrcweir                                 if( pLine && pTxtFrm ) // always for old table model
2963cdf0e10cSrcweir                                 {
2964cdf0e10cSrcweir                                     // The new row height must not to be calculated from a overlapping box
2965cdf0e10cSrcweir                                     SwFmtFrmSize aNew( pLine->GetFrmFmt()->GetFrmSize() );
2966cdf0e10cSrcweir                                     const long nNewSize = (pFrm->Frm().*fnRect->fnGetHeight)() + nDiff;
2967cdf0e10cSrcweir                                     if( nNewSize != aNew.GetHeight() )
2968cdf0e10cSrcweir                                     {
2969cdf0e10cSrcweir                                         aNew.SetHeight( nNewSize );
2970cdf0e10cSrcweir                                         if ( ATT_VAR_SIZE == aNew.GetHeightSizeType() )
2971cdf0e10cSrcweir                                             aNew.SetHeightSizeType( ATT_MIN_SIZE );
2972cdf0e10cSrcweir                                         // This position must not be in an overlapped box
2973cdf0e10cSrcweir                                         const SwPosition aPos( *((SwTxtFrm*)pCntnt)->GetTxtNode() );
2974cdf0e10cSrcweir                                         const SwCursor aTmpCrsr( aPos, 0, false );
2975cdf0e10cSrcweir                                         SetRowHeight( aTmpCrsr, aNew );
2976cdf0e10cSrcweir                                         // For the new table model we're done, for the old one
2977cdf0e10cSrcweir                                         // there might be another (sub)row to adjust...
2978cdf0e10cSrcweir                                         if( pTable->IsNewModel() )
2979cdf0e10cSrcweir                                             break;
2980cdf0e10cSrcweir                                     }
2981cdf0e10cSrcweir                                     pLine = 0;
2982cdf0e10cSrcweir                                 }
2983cdf0e10cSrcweir                             }
2984cdf0e10cSrcweir                         }
2985cdf0e10cSrcweir                     }
2986cdf0e10cSrcweir                 }
2987cdf0e10cSrcweir                 pFrm = pFrm->GetNextLayoutLeaf();
2988cdf0e10cSrcweir             }
2989cdf0e10cSrcweir         }
2990cdf0e10cSrcweir     }
2991cdf0e10cSrcweir 
2992cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo( UNDO_TABLE_ATTR, NULL );
2993cdf0e10cSrcweir 
2994cdf0e10cSrcweir 	::ClearFEShellTabCols();
2995cdf0e10cSrcweir }
2996cdf0e10cSrcweir 
2997cdf0e10cSrcweir /* -----------------18.07.98 11:45-------------------
2998cdf0e10cSrcweir  *  Direktzugriff fuer UNO
2999cdf0e10cSrcweir  * --------------------------------------------------*/
SetTabCols(SwTable & rTab,const SwTabCols & rNew,const SwTabCols & rOld,const SwTableBox * pStart,sal_Bool bCurRowOnly)3000cdf0e10cSrcweir void SwDoc::SetTabCols(SwTable& rTab, const SwTabCols &rNew, const SwTabCols &rOld,
3001cdf0e10cSrcweir 								const SwTableBox *pStart, sal_Bool bCurRowOnly )
3002cdf0e10cSrcweir {
3003cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
3004cdf0e10cSrcweir     {
3005cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(
3006cdf0e10cSrcweir             new SwUndoAttrTbl( *rTab.GetTableNode(), sal_True ));
3007cdf0e10cSrcweir 	}
3008cdf0e10cSrcweir 	rTab.SetTabCols( rNew, rOld, pStart, bCurRowOnly );
3009cdf0e10cSrcweir   	::ClearFEShellTabCols();
3010cdf0e10cSrcweir 	SetModified();
3011cdf0e10cSrcweir }
3012cdf0e10cSrcweir 
SetRowsToRepeat(SwTable & rTable,sal_uInt16 nSet)3013cdf0e10cSrcweir void SwDoc::SetRowsToRepeat( SwTable &rTable, sal_uInt16 nSet )
3014cdf0e10cSrcweir {
3015cdf0e10cSrcweir     if( nSet == rTable.GetRowsToRepeat() )
3016cdf0e10cSrcweir         return;
3017cdf0e10cSrcweir 
3018cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
3019cdf0e10cSrcweir     {
3020cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(
3021cdf0e10cSrcweir             new SwUndoTblHeadline(rTable, rTable.GetRowsToRepeat(), nSet) );
3022cdf0e10cSrcweir     }
3023cdf0e10cSrcweir 
3024cdf0e10cSrcweir     SwMsgPoolItem aChg( RES_TBLHEADLINECHG );
3025cdf0e10cSrcweir     rTable.SetRowsToRepeat( nSet );
3026cdf0e10cSrcweir     rTable.GetFrmFmt()->ModifyNotification( &aChg, &aChg );
3027cdf0e10cSrcweir     SetModified();
3028cdf0e10cSrcweir }
3029cdf0e10cSrcweir 
3030cdf0e10cSrcweir 
3031cdf0e10cSrcweir 
3032cdf0e10cSrcweir 
3033cdf0e10cSrcweir // Splittet eine Tabelle in der Grund-Zeile, in der der Index steht.
3034cdf0e10cSrcweir // Alle GrundZeilen dahinter wandern in eine neue Tabelle/-Node.
3035cdf0e10cSrcweir // Ist das Flag bCalcNewSize auf sal_True, wird fuer beide neuen Tabellen
3036cdf0e10cSrcweir // die neue Size aus dem Max der Boxen errechnet; vorrausgesetzt,
3037cdf0e10cSrcweir // die Size ist "absolut" gesetzt (USHRT_MAX)
3038cdf0e10cSrcweir 
AddToUndoHistory(const SwCntntNode & rNd)3039cdf0e10cSrcweir void SwCollectTblLineBoxes::AddToUndoHistory( const SwCntntNode& rNd )
3040cdf0e10cSrcweir {
3041cdf0e10cSrcweir 	if( pHst )
3042cdf0e10cSrcweir 		pHst->Add( rNd.GetFmtColl(), rNd.GetIndex(), ND_TEXTNODE );
3043cdf0e10cSrcweir }
3044cdf0e10cSrcweir 
AddBox(const SwTableBox & rBox)3045cdf0e10cSrcweir void SwCollectTblLineBoxes::AddBox( const SwTableBox& rBox )
3046cdf0e10cSrcweir {
3047cdf0e10cSrcweir 	aPosArr.Insert( nWidth, aPosArr.Count() );
3048cdf0e10cSrcweir 	SwTableBox* p = (SwTableBox*)&rBox;
3049cdf0e10cSrcweir 	aBoxes.Insert( p, aBoxes.Count() );
3050cdf0e10cSrcweir 	nWidth = nWidth + (sal_uInt16)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
3051cdf0e10cSrcweir }
3052cdf0e10cSrcweir 
GetBoxOfPos(const SwTableBox & rBox)3053cdf0e10cSrcweir const SwTableBox* SwCollectTblLineBoxes::GetBoxOfPos( const SwTableBox& rBox )
3054cdf0e10cSrcweir {
3055cdf0e10cSrcweir 	const SwTableBox* pRet = 0;
3056cdf0e10cSrcweir 	sal_uInt16 n;
3057cdf0e10cSrcweir 
3058cdf0e10cSrcweir 	if( aPosArr.Count() )
3059cdf0e10cSrcweir 	{
3060cdf0e10cSrcweir 		for( n = 0; n < aPosArr.Count(); ++n )
3061cdf0e10cSrcweir 			if( aPosArr[ n ] == nWidth )
3062cdf0e10cSrcweir 				break;
3063cdf0e10cSrcweir 			else if( aPosArr[ n ] > nWidth )
3064cdf0e10cSrcweir 			{
3065cdf0e10cSrcweir 				if( n )
3066cdf0e10cSrcweir 					--n;
3067cdf0e10cSrcweir 				break;
3068cdf0e10cSrcweir 			}
3069cdf0e10cSrcweir 
3070cdf0e10cSrcweir 		if( n >= aPosArr.Count() )
3071cdf0e10cSrcweir 			--n;
3072cdf0e10cSrcweir 
3073cdf0e10cSrcweir 		nWidth = nWidth + (sal_uInt16)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
3074cdf0e10cSrcweir 		pRet = aBoxes[ n ];
3075cdf0e10cSrcweir 	}
3076cdf0e10cSrcweir 	return pRet;
3077cdf0e10cSrcweir }
3078cdf0e10cSrcweir 
Resize(sal_uInt16 nOffset,sal_uInt16 nOldWidth)3079cdf0e10cSrcweir sal_Bool SwCollectTblLineBoxes::Resize( sal_uInt16 nOffset, sal_uInt16 nOldWidth )
3080cdf0e10cSrcweir {
3081cdf0e10cSrcweir 	sal_uInt16 n;
3082cdf0e10cSrcweir 
3083cdf0e10cSrcweir 	if( aPosArr.Count() )
3084cdf0e10cSrcweir 	{
3085cdf0e10cSrcweir 		for( n = 0; n < aPosArr.Count(); ++n )
3086cdf0e10cSrcweir 			if( aPosArr[ n ] == nOffset )
3087cdf0e10cSrcweir 				break;
3088cdf0e10cSrcweir 			else if( aPosArr[ n ] > nOffset )
3089cdf0e10cSrcweir 			{
3090cdf0e10cSrcweir 				if( n )
3091cdf0e10cSrcweir 					--n;
3092cdf0e10cSrcweir 				break;
3093cdf0e10cSrcweir 			}
3094cdf0e10cSrcweir 
3095cdf0e10cSrcweir 		aPosArr.Remove( 0, n );
3096cdf0e10cSrcweir 		aBoxes.Remove( 0, n );
3097cdf0e10cSrcweir 
3098cdf0e10cSrcweir 		// dann die Positionen der neuen Size anpassen
3099cdf0e10cSrcweir 		for( n = 0; n < aPosArr.Count(); ++n )
3100cdf0e10cSrcweir 		{
3101cdf0e10cSrcweir 			sal_uLong nSize = nWidth;
3102cdf0e10cSrcweir 			nSize *= ( aPosArr[ n ] - nOffset );
3103cdf0e10cSrcweir 			nSize /= nOldWidth;
3104cdf0e10cSrcweir 			aPosArr[ n ] = sal_uInt16( nSize );
3105cdf0e10cSrcweir 		}
3106cdf0e10cSrcweir 	}
3107cdf0e10cSrcweir 	return 0 != aPosArr.Count();
3108cdf0e10cSrcweir }
3109cdf0e10cSrcweir 
lcl_Line_CollectBox(const SwTableLine * & rpLine,void * pPara)3110cdf0e10cSrcweir sal_Bool lcl_Line_CollectBox( const SwTableLine*& rpLine, void* pPara )
3111cdf0e10cSrcweir {
3112cdf0e10cSrcweir 	SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
3113cdf0e10cSrcweir 	if( pSplPara->IsGetValues() )
3114cdf0e10cSrcweir 		((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_Box_CollectBox, pPara );
3115cdf0e10cSrcweir 	else
3116cdf0e10cSrcweir 		((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, pPara );
3117cdf0e10cSrcweir 	return sal_True;
3118cdf0e10cSrcweir }
3119cdf0e10cSrcweir 
lcl_Box_CollectBox(const SwTableBox * & rpBox,void * pPara)3120cdf0e10cSrcweir sal_Bool lcl_Box_CollectBox( const SwTableBox*& rpBox, void* pPara )
3121cdf0e10cSrcweir {
3122cdf0e10cSrcweir 	SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
3123cdf0e10cSrcweir 	sal_uInt16 nLen = rpBox->GetTabLines().Count();
3124cdf0e10cSrcweir 	if( nLen )
3125cdf0e10cSrcweir 	{
3126cdf0e10cSrcweir 		// dann mit der richtigen Line weitermachen
3127cdf0e10cSrcweir 		if( pSplPara->IsGetFromTop() )
3128cdf0e10cSrcweir 			nLen = 0;
3129cdf0e10cSrcweir 		else
3130cdf0e10cSrcweir 			--nLen;
3131cdf0e10cSrcweir 
3132cdf0e10cSrcweir 		const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ];
3133cdf0e10cSrcweir 		lcl_Line_CollectBox( pLn, pPara );
3134cdf0e10cSrcweir 	}
3135cdf0e10cSrcweir 	else
3136cdf0e10cSrcweir 		pSplPara->AddBox( *rpBox );
3137cdf0e10cSrcweir 	return sal_True;
3138cdf0e10cSrcweir }
3139cdf0e10cSrcweir 
lcl_BoxSetSplitBoxFmts(const SwTableBox * & rpBox,void * pPara)3140cdf0e10cSrcweir sal_Bool lcl_BoxSetSplitBoxFmts( const SwTableBox*& rpBox, void* pPara )
3141cdf0e10cSrcweir {
3142cdf0e10cSrcweir 	SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
3143cdf0e10cSrcweir 	sal_uInt16 nLen = rpBox->GetTabLines().Count();
3144cdf0e10cSrcweir 	if( nLen )
3145cdf0e10cSrcweir 	{
3146cdf0e10cSrcweir 		// dann mit der richtigen Line weitermachen
3147cdf0e10cSrcweir 		if( pSplPara->IsGetFromTop() )
3148cdf0e10cSrcweir 			nLen = 0;
3149cdf0e10cSrcweir 		else
3150cdf0e10cSrcweir 			--nLen;
3151cdf0e10cSrcweir 
3152cdf0e10cSrcweir 		const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ];
3153cdf0e10cSrcweir 		lcl_Line_CollectBox( pLn, pPara );
3154cdf0e10cSrcweir 	}
3155cdf0e10cSrcweir 	else
3156cdf0e10cSrcweir 	{
3157cdf0e10cSrcweir 		const SwTableBox* pSrcBox = pSplPara->GetBoxOfPos( *rpBox );
3158cdf0e10cSrcweir 		SwFrmFmt* pFmt = pSrcBox->GetFrmFmt();
3159cdf0e10cSrcweir 		SwTableBox* pBox = (SwTableBox*)rpBox;
3160cdf0e10cSrcweir 
3161cdf0e10cSrcweir 		if( HEADLINE_BORDERCOPY == pSplPara->GetMode() )
3162cdf0e10cSrcweir 		{
3163cdf0e10cSrcweir 			const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
3164cdf0e10cSrcweir 			if( !rBoxItem.GetTop() )
3165cdf0e10cSrcweir 			{
3166cdf0e10cSrcweir 				SvxBoxItem aNew( rBoxItem );
3167cdf0e10cSrcweir 				aNew.SetLine( pFmt->GetBox().GetBottom(), BOX_LINE_TOP );
3168cdf0e10cSrcweir 				if( aNew != rBoxItem )
3169cdf0e10cSrcweir                     pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
3170cdf0e10cSrcweir 			}
3171cdf0e10cSrcweir 		}
3172cdf0e10cSrcweir 		else
3173cdf0e10cSrcweir 		{
3174cdf0e10cSrcweir sal_uInt16 __FAR_DATA aTableSplitBoxSetRange[] = {
3175cdf0e10cSrcweir 	RES_LR_SPACE, 		RES_UL_SPACE,
3176cdf0e10cSrcweir 	RES_BACKGROUND, 	RES_SHADOW,
3177cdf0e10cSrcweir 	RES_PROTECT, 		RES_PROTECT,
3178cdf0e10cSrcweir 	RES_VERT_ORIENT,	RES_VERT_ORIENT,
3179cdf0e10cSrcweir 	0 };
3180cdf0e10cSrcweir 			SfxItemSet aTmpSet( pFmt->GetDoc()->GetAttrPool(),
3181cdf0e10cSrcweir 								aTableSplitBoxSetRange );
3182cdf0e10cSrcweir 			aTmpSet.Put( pFmt->GetAttrSet() );
3183cdf0e10cSrcweir 			if( aTmpSet.Count() )
3184cdf0e10cSrcweir                 pBox->ClaimFrmFmt()->SetFmtAttr( aTmpSet );
3185cdf0e10cSrcweir 
3186cdf0e10cSrcweir 			if( HEADLINE_BOXATRCOLLCOPY == pSplPara->GetMode() )
3187cdf0e10cSrcweir 			{
3188cdf0e10cSrcweir 				SwNodeIndex aIdx( *pSrcBox->GetSttNd(), 1 );
3189cdf0e10cSrcweir 				SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
3190cdf0e10cSrcweir 				if( !pCNd )
3191cdf0e10cSrcweir 					pCNd = aIdx.GetNodes().GoNext( &aIdx );
3192cdf0e10cSrcweir 				aIdx = *pBox->GetSttNd();
3193cdf0e10cSrcweir 				SwCntntNode* pDNd = aIdx.GetNodes().GoNext( &aIdx );
3194cdf0e10cSrcweir 
3195cdf0e10cSrcweir 				// nur wenn der Node alleine in der Section steht
3196cdf0e10cSrcweir 				if( 2 == pDNd->EndOfSectionIndex() -
3197cdf0e10cSrcweir 						pDNd->StartOfSectionIndex() )
3198cdf0e10cSrcweir 				{
3199cdf0e10cSrcweir 					pSplPara->AddToUndoHistory( *pDNd );
3200cdf0e10cSrcweir 					pDNd->ChgFmtColl( pCNd->GetFmtColl() );
3201cdf0e10cSrcweir 				}
3202cdf0e10cSrcweir 			}
3203cdf0e10cSrcweir 
3204cdf0e10cSrcweir 			// bedingte Vorlage beachten
3205cdf0e10cSrcweir 			pBox->GetSttNd()->CheckSectionCondColl();
3206cdf0e10cSrcweir 		}
3207cdf0e10cSrcweir 	}
3208cdf0e10cSrcweir 	return sal_True;
3209cdf0e10cSrcweir }
3210cdf0e10cSrcweir 
3211cdf0e10cSrcweir 
SplitTable(const SwPosition & rPos,sal_uInt16 eHdlnMode,sal_Bool bCalcNewSize)3212cdf0e10cSrcweir sal_Bool SwDoc::SplitTable( const SwPosition& rPos, sal_uInt16 eHdlnMode,
3213cdf0e10cSrcweir 						sal_Bool bCalcNewSize )
3214cdf0e10cSrcweir {
3215cdf0e10cSrcweir 	SwNode* pNd = &rPos.nNode.GetNode();
3216cdf0e10cSrcweir 	SwTableNode* pTNd = pNd->FindTableNode();
3217cdf0e10cSrcweir 	if( !pTNd || pNd->IsTableNode() )
3218cdf0e10cSrcweir 		return 0;
3219cdf0e10cSrcweir 
3220cdf0e10cSrcweir 	if( pTNd->GetTable().ISA( SwDDETable ))
3221cdf0e10cSrcweir 		return sal_False;
3222cdf0e10cSrcweir 
3223cdf0e10cSrcweir 	SwTable& rTbl = pTNd->GetTable();
3224cdf0e10cSrcweir 	rTbl.SetHTMLTableLayout( 0 ); 	// MIB 9.7.97: HTML-Layout loeschen
3225cdf0e10cSrcweir 
3226cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &rTbl );
3227cdf0e10cSrcweir 
3228cdf0e10cSrcweir 	SwHistory aHistory;
3229cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
3230cdf0e10cSrcweir     {
3231cdf0e10cSrcweir 		aMsgHnt.pHistory = &aHistory;
3232cdf0e10cSrcweir     }
3233cdf0e10cSrcweir 
3234cdf0e10cSrcweir 	{
3235cdf0e10cSrcweir 		sal_uLong nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
3236cdf0e10cSrcweir 
3237cdf0e10cSrcweir 		// Suche die Grund-Line dieser Box:
3238cdf0e10cSrcweir 		SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
3239cdf0e10cSrcweir 		if( pBox )
3240cdf0e10cSrcweir 		{
3241cdf0e10cSrcweir 			SwTableLine* pLine = pBox->GetUpper();
3242cdf0e10cSrcweir 			while( pLine->GetUpper() )
3243cdf0e10cSrcweir 				pLine = pLine->GetUpper()->GetUpper();
3244cdf0e10cSrcweir 
3245cdf0e10cSrcweir 			// in pLine steht jetzt die GrundLine.
3246cdf0e10cSrcweir 			aMsgHnt.nSplitLine = rTbl.GetTabLines().C40_GETPOS( SwTableLine, pLine );
3247cdf0e10cSrcweir 		}
3248cdf0e10cSrcweir 
3249cdf0e10cSrcweir 		String sNewTblNm( GetUniqueTblName() );
3250cdf0e10cSrcweir 		aMsgHnt.DATA.pNewTblNm = &sNewTblNm;
3251cdf0e10cSrcweir 		aMsgHnt.eFlags = TBL_SPLITTBL;
3252cdf0e10cSrcweir 		UpdateTblFlds( &aMsgHnt );
3253cdf0e10cSrcweir 	}
3254cdf0e10cSrcweir 
3255cdf0e10cSrcweir 	//Lines fuer das Layout-Update heraussuchen.
3256cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
3257cdf0e10cSrcweir     aFndBox.SetTableLines( rTbl );
3258cdf0e10cSrcweir     aFndBox.DelFrms( rTbl );
3259cdf0e10cSrcweir 
3260cdf0e10cSrcweir     // TL_CHART2: need to inform chart of probably changed cell names
3261cdf0e10cSrcweir     //pDoc->UpdateCharts( rTbl.GetFrmFmt()->GetName() );
3262cdf0e10cSrcweir 
3263cdf0e10cSrcweir 	SwTableNode* pNew = GetNodes().SplitTable( rPos.nNode, sal_False, bCalcNewSize );
3264cdf0e10cSrcweir 
3265cdf0e10cSrcweir 	if( pNew )
3266cdf0e10cSrcweir 	{
3267cdf0e10cSrcweir         SwSaveRowSpan* pSaveRowSp = pNew->GetTable().CleanUpTopRowSpan( rTbl.GetTabLines().Count() );
3268cdf0e10cSrcweir 		SwUndoSplitTbl* pUndo = 0;
3269cdf0e10cSrcweir         if (GetIDocumentUndoRedo().DoesUndo())
3270cdf0e10cSrcweir         {
3271cdf0e10cSrcweir             pUndo = new SwUndoSplitTbl(
3272cdf0e10cSrcweir                         *pNew, pSaveRowSp, eHdlnMode, bCalcNewSize);
3273cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(pUndo);
3274cdf0e10cSrcweir 			if( aHistory.Count() )
3275cdf0e10cSrcweir 				pUndo->SaveFormula( aHistory );
3276cdf0e10cSrcweir 		}
3277cdf0e10cSrcweir 
3278cdf0e10cSrcweir 		switch( eHdlnMode )
3279cdf0e10cSrcweir 		{
3280cdf0e10cSrcweir 			// setze die untere Border der vorherige Line,
3281cdf0e10cSrcweir 			// an der aktuellen als obere
3282cdf0e10cSrcweir 		case HEADLINE_BORDERCOPY:
3283cdf0e10cSrcweir 			{
3284cdf0e10cSrcweir 				SwCollectTblLineBoxes aPara( sal_False, eHdlnMode );
3285cdf0e10cSrcweir 				SwTableLine* pLn = rTbl.GetTabLines()[
3286cdf0e10cSrcweir 							rTbl.GetTabLines().Count() - 1 ];
3287cdf0e10cSrcweir 				pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aPara );
3288cdf0e10cSrcweir 
3289cdf0e10cSrcweir 				aPara.SetValues( sal_True );
3290cdf0e10cSrcweir 				pLn = pNew->GetTable().GetTabLines()[ 0 ];
3291cdf0e10cSrcweir 				pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aPara );
3292cdf0e10cSrcweir 
3293cdf0e10cSrcweir 				// Kopfzeile wiederholen abschalten
3294cdf0e10cSrcweir                 pNew->GetTable().SetRowsToRepeat( 0 );
3295cdf0e10cSrcweir 			}
3296cdf0e10cSrcweir 			break;
3297cdf0e10cSrcweir 
3298cdf0e10cSrcweir 			// setze die Attributierung der ersten Line an der neuen ersten
3299cdf0e10cSrcweir 		case HEADLINE_BOXATTRCOPY:
3300cdf0e10cSrcweir 		case HEADLINE_BOXATRCOLLCOPY:
3301cdf0e10cSrcweir 			{
3302cdf0e10cSrcweir 				SwHistory* pHst = 0;
3303cdf0e10cSrcweir 				if( HEADLINE_BOXATRCOLLCOPY == eHdlnMode && pUndo )
3304cdf0e10cSrcweir 					pHst = pUndo->GetHistory();
3305cdf0e10cSrcweir 
3306cdf0e10cSrcweir 				SwCollectTblLineBoxes aPara( sal_True, eHdlnMode, pHst );
3307cdf0e10cSrcweir 				SwTableLine* pLn = rTbl.GetTabLines()[ 0 ];
3308cdf0e10cSrcweir 				pLn->GetTabBoxes().ForEach( &lcl_Box_CollectBox, &aPara );
3309cdf0e10cSrcweir 
3310cdf0e10cSrcweir 				aPara.SetValues( sal_True );
3311cdf0e10cSrcweir 				pLn = pNew->GetTable().GetTabLines()[ 0 ];
3312cdf0e10cSrcweir 				pLn->GetTabBoxes().ForEach( &lcl_BoxSetSplitBoxFmts, &aPara );
3313cdf0e10cSrcweir 			}
3314cdf0e10cSrcweir 			break;
3315cdf0e10cSrcweir 
3316cdf0e10cSrcweir 		case HEADLINE_CNTNTCOPY:
3317cdf0e10cSrcweir 			rTbl.CopyHeadlineIntoTable( *pNew );
3318cdf0e10cSrcweir 			if( pUndo )
3319cdf0e10cSrcweir 				pUndo->SetTblNodeOffset( pNew->GetIndex() );
3320cdf0e10cSrcweir 			break;
3321cdf0e10cSrcweir 
3322cdf0e10cSrcweir 		case HEADLINE_NONE:
3323cdf0e10cSrcweir 			// Kopfzeile wiederholen abschalten
3324cdf0e10cSrcweir             pNew->GetTable().SetRowsToRepeat( 0 );
3325cdf0e10cSrcweir 			break;
3326cdf0e10cSrcweir 		}
3327cdf0e10cSrcweir 
3328cdf0e10cSrcweir 		// und Frms einfuegen.
3329cdf0e10cSrcweir 		SwNodeIndex aNdIdx( *pNew->EndOfSectionNode() );
3330cdf0e10cSrcweir 		GetNodes().GoNext( &aNdIdx );      // zum naechsten ContentNode
3331cdf0e10cSrcweir 		pNew->MakeFrms( &aNdIdx );
3332cdf0e10cSrcweir 
3333cdf0e10cSrcweir 		//Zwischen die Tabellen wird ein Absatz geschoben
3334cdf0e10cSrcweir 		GetNodes().MakeTxtNode( SwNodeIndex( *pNew ),
3335cdf0e10cSrcweir 								GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
3336cdf0e10cSrcweir 	}
3337cdf0e10cSrcweir 
3338cdf0e10cSrcweir 	//Layout updaten
3339cdf0e10cSrcweir     aFndBox.MakeFrms( rTbl );
3340cdf0e10cSrcweir 
3341cdf0e10cSrcweir     // TL_CHART2: need to inform chart of probably changed cell names
3342cdf0e10cSrcweir     UpdateCharts( rTbl.GetFrmFmt()->GetName() );
3343cdf0e10cSrcweir 
3344cdf0e10cSrcweir     SetFieldsDirty( true, NULL, 0 );
3345cdf0e10cSrcweir 
3346cdf0e10cSrcweir 	return 0 != pNew;
3347cdf0e10cSrcweir }
3348cdf0e10cSrcweir 
lcl_ChgTblSize(SwTable & rTbl)3349cdf0e10cSrcweir sal_Bool lcl_ChgTblSize( SwTable& rTbl )
3350cdf0e10cSrcweir {
3351cdf0e10cSrcweir 	// das Attribut darf nicht ueber das Modify an der
3352cdf0e10cSrcweir 	// Tabelle gesetzt werden, denn sonst werden alle
3353cdf0e10cSrcweir 	// Boxen wieder auf 0 zurueck gesetzt. Also locke das Format
3354cdf0e10cSrcweir 	SwFrmFmt* pFmt = rTbl.GetFrmFmt();
3355cdf0e10cSrcweir 	SwFmtFrmSize aTblMaxSz( pFmt->GetFrmSize() );
3356cdf0e10cSrcweir 
3357cdf0e10cSrcweir 	if( USHRT_MAX == aTblMaxSz.GetWidth() )
3358cdf0e10cSrcweir 		return sal_False;
3359cdf0e10cSrcweir 
3360cdf0e10cSrcweir 	sal_Bool bLocked = pFmt->IsModifyLocked();
3361cdf0e10cSrcweir 	pFmt->LockModify();
3362cdf0e10cSrcweir 
3363cdf0e10cSrcweir 	aTblMaxSz.SetWidth( 0 );
3364cdf0e10cSrcweir 
3365cdf0e10cSrcweir 	SwTableLines& rLns = rTbl.GetTabLines();
3366cdf0e10cSrcweir 	for( sal_uInt16 nLns = 0; nLns < rLns.Count(); ++nLns )
3367cdf0e10cSrcweir 	{
3368cdf0e10cSrcweir 		SwTwips nMaxLnWidth = 0;
3369cdf0e10cSrcweir 		SwTableBoxes& rBoxes = rLns[ nLns ]->GetTabBoxes();
3370cdf0e10cSrcweir 		for( sal_uInt16 nBox = 0; nBox < rBoxes.Count(); ++nBox )
3371cdf0e10cSrcweir 			nMaxLnWidth += rBoxes[nBox]->GetFrmFmt()->GetFrmSize().GetWidth();
3372cdf0e10cSrcweir 
3373cdf0e10cSrcweir 		if( nMaxLnWidth > aTblMaxSz.GetWidth() )
3374cdf0e10cSrcweir 			aTblMaxSz.SetWidth( nMaxLnWidth );
3375cdf0e10cSrcweir 	}
3376cdf0e10cSrcweir     pFmt->SetFmtAttr( aTblMaxSz );
3377cdf0e10cSrcweir 	if( !bLocked )			// und gegebenenfalls Lock wieder freigeben
3378cdf0e10cSrcweir 		pFmt->UnlockModify();
3379cdf0e10cSrcweir 
3380cdf0e10cSrcweir 	return sal_True;
3381cdf0e10cSrcweir }
3382cdf0e10cSrcweir 
3383cdf0e10cSrcweir class _SplitTable_Para
3384cdf0e10cSrcweir {
3385cdf0e10cSrcweir 	SvPtrarr aSrc, aDest;
3386cdf0e10cSrcweir 	SwTableNode* pNewTblNd;
3387cdf0e10cSrcweir 	SwTable& rOldTbl;
3388cdf0e10cSrcweir 
3389cdf0e10cSrcweir public:
_SplitTable_Para(SwTableNode * pNew,SwTable & rOld)3390cdf0e10cSrcweir 	_SplitTable_Para( SwTableNode* pNew, SwTable& rOld )
3391cdf0e10cSrcweir 		: aSrc( 16, 16 ), aDest( 16, 16 ), pNewTblNd( pNew ), rOldTbl( rOld )
3392cdf0e10cSrcweir 	{}
SrcFmt_GetPos(void * pFmt) const3393cdf0e10cSrcweir 	sal_uInt16 SrcFmt_GetPos( void* pFmt ) const
3394cdf0e10cSrcweir 			{ return aSrc.GetPos( pFmt ); }
3395cdf0e10cSrcweir 
DestFmt_Insert(void * pFmt)3396cdf0e10cSrcweir 	void DestFmt_Insert( void* pFmt )
3397cdf0e10cSrcweir 			{ aDest.Insert( pFmt, aDest.Count() ); }
3398cdf0e10cSrcweir 
SrcFmt_Insert(void * pFmt)3399cdf0e10cSrcweir 	void SrcFmt_Insert( void* pFmt )
3400cdf0e10cSrcweir 			{ aSrc.Insert( pFmt, aSrc.Count() ); }
3401cdf0e10cSrcweir 
DestFmt_Get(sal_uInt16 nPos) const3402cdf0e10cSrcweir 	SwFrmFmt* DestFmt_Get( sal_uInt16 nPos ) const
3403cdf0e10cSrcweir 			{ return (SwFrmFmt*)aDest[ nPos ]; }
3404cdf0e10cSrcweir 
ChgBox(SwTableBox * pBox)3405cdf0e10cSrcweir 	void ChgBox( SwTableBox* pBox )
3406cdf0e10cSrcweir 	{
3407cdf0e10cSrcweir 		rOldTbl.GetTabSortBoxes().Remove( pBox );
3408cdf0e10cSrcweir 		pNewTblNd->GetTable().GetTabSortBoxes().Insert( pBox );
3409cdf0e10cSrcweir 	}
3410cdf0e10cSrcweir };
3411cdf0e10cSrcweir 
3412cdf0e10cSrcweir 
3413cdf0e10cSrcweir sal_Bool lcl_SplitTable_CpyBox( const SwTableBox*& rpBox, void* pPara );
3414cdf0e10cSrcweir 
lcl_SplitTable_CpyLine(const SwTableLine * & rpLine,void * pPara)3415cdf0e10cSrcweir sal_Bool lcl_SplitTable_CpyLine( const SwTableLine*& rpLine, void* pPara )
3416cdf0e10cSrcweir {
3417cdf0e10cSrcweir 	SwTableLine* pLn = (SwTableLine*)rpLine;
3418cdf0e10cSrcweir 	_SplitTable_Para& rPara = *(_SplitTable_Para*)pPara;
3419cdf0e10cSrcweir 
3420cdf0e10cSrcweir 	SwFrmFmt *pSrcFmt = pLn->GetFrmFmt();
3421cdf0e10cSrcweir 	sal_uInt16 nPos = rPara.SrcFmt_GetPos( pSrcFmt );
3422cdf0e10cSrcweir 	if( USHRT_MAX == nPos )
3423cdf0e10cSrcweir 	{
3424cdf0e10cSrcweir 		rPara.DestFmt_Insert( pLn->ClaimFrmFmt() );
3425cdf0e10cSrcweir 		rPara.SrcFmt_Insert( pSrcFmt );
3426cdf0e10cSrcweir 	}
3427cdf0e10cSrcweir 	else
3428cdf0e10cSrcweir 		pLn->ChgFrmFmt( (SwTableLineFmt*)rPara.DestFmt_Get( nPos ) );
3429cdf0e10cSrcweir 
3430cdf0e10cSrcweir 	pLn->GetTabBoxes().ForEach( &lcl_SplitTable_CpyBox, pPara );
3431cdf0e10cSrcweir 	return sal_True;
3432cdf0e10cSrcweir }
3433cdf0e10cSrcweir 
lcl_SplitTable_CpyBox(const SwTableBox * & rpBox,void * pPara)3434cdf0e10cSrcweir sal_Bool lcl_SplitTable_CpyBox( const SwTableBox*& rpBox, void* pPara )
3435cdf0e10cSrcweir {
3436cdf0e10cSrcweir 	SwTableBox* pBox = (SwTableBox*)rpBox;
3437cdf0e10cSrcweir 	_SplitTable_Para& rPara = *(_SplitTable_Para*)pPara;
3438cdf0e10cSrcweir 
3439cdf0e10cSrcweir 	SwFrmFmt *pSrcFmt = pBox->GetFrmFmt();
3440cdf0e10cSrcweir 	sal_uInt16 nPos = rPara.SrcFmt_GetPos( pSrcFmt );
3441cdf0e10cSrcweir 	if( USHRT_MAX == nPos )
3442cdf0e10cSrcweir 	{
3443cdf0e10cSrcweir 		rPara.DestFmt_Insert( pBox->ClaimFrmFmt() );
3444cdf0e10cSrcweir 		rPara.SrcFmt_Insert( pSrcFmt );
3445cdf0e10cSrcweir 	}
3446cdf0e10cSrcweir 	else
3447cdf0e10cSrcweir 		pBox->ChgFrmFmt( (SwTableBoxFmt*)rPara.DestFmt_Get( nPos ) );
3448cdf0e10cSrcweir 
3449cdf0e10cSrcweir 	if( pBox->GetSttNd() )
3450cdf0e10cSrcweir 		rPara.ChgBox( pBox );
3451cdf0e10cSrcweir 	else
3452cdf0e10cSrcweir 		pBox->GetTabLines().ForEach( &lcl_SplitTable_CpyLine, pPara );
3453cdf0e10cSrcweir 	return sal_True;
3454cdf0e10cSrcweir }
3455cdf0e10cSrcweir 
SplitTable(const SwNodeIndex & rPos,sal_Bool bAfter,sal_Bool bCalcNewSize)3456cdf0e10cSrcweir SwTableNode* SwNodes::SplitTable( const SwNodeIndex& rPos, sal_Bool bAfter,
3457cdf0e10cSrcweir 									sal_Bool bCalcNewSize )
3458cdf0e10cSrcweir {
3459cdf0e10cSrcweir 	SwNode* pNd = &rPos.GetNode();
3460cdf0e10cSrcweir 	SwTableNode* pTNd = pNd->FindTableNode();
3461cdf0e10cSrcweir 	if( !pTNd || pNd->IsTableNode() )
3462cdf0e10cSrcweir 		return 0;
3463cdf0e10cSrcweir 
3464cdf0e10cSrcweir 	sal_uLong nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
3465cdf0e10cSrcweir 
3466cdf0e10cSrcweir 	// Suche die Grund-Line dieser Box:
3467cdf0e10cSrcweir 	SwTable& rTbl = pTNd->GetTable();
3468cdf0e10cSrcweir 	SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
3469cdf0e10cSrcweir 	if( !pBox )
3470cdf0e10cSrcweir 		return 0;
3471cdf0e10cSrcweir 
3472cdf0e10cSrcweir 	SwTableLine* pLine = pBox->GetUpper();
3473cdf0e10cSrcweir 	while( pLine->GetUpper() )
3474cdf0e10cSrcweir 		pLine = pLine->GetUpper()->GetUpper();
3475cdf0e10cSrcweir 
3476cdf0e10cSrcweir 	// in pLine steht jetzt die GrundLine.
3477cdf0e10cSrcweir 	sal_uInt16 nLinePos = rTbl.GetTabLines().C40_GETPOS( SwTableLine, pLine );
3478cdf0e10cSrcweir 	if( USHRT_MAX == nLinePos ||
3479cdf0e10cSrcweir 		( bAfter ? ++nLinePos >= rTbl.GetTabLines().Count() : !nLinePos ))
3480cdf0e10cSrcweir 		return 0;		// nicht gefunden oder letze Line !!
3481cdf0e10cSrcweir 
3482cdf0e10cSrcweir 	// Suche jetzt die 1. Box der nachfolgenden Line
3483cdf0e10cSrcweir 	SwTableLine* pNextLine = rTbl.GetTabLines()[ nLinePos ];
3484cdf0e10cSrcweir 	pBox = pNextLine->GetTabBoxes()[0];
3485cdf0e10cSrcweir 	while( !pBox->GetSttNd() )
3486cdf0e10cSrcweir 		pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
3487cdf0e10cSrcweir 
3488cdf0e10cSrcweir 	// dann fuege mal einen End- und TabelleNode ins Nodes-Array ein.
3489cdf0e10cSrcweir 	SwTableNode * pNewTblNd;
3490cdf0e10cSrcweir 	{
3491cdf0e10cSrcweir 		SwEndNode* pOldTblEndNd = (SwEndNode*)pTNd->EndOfSectionNode()->GetEndNode();
3492cdf0e10cSrcweir 		ASSERT( pOldTblEndNd, "wo ist der EndNode?" )
3493cdf0e10cSrcweir 
3494cdf0e10cSrcweir 		SwNodeIndex aIdx( *pBox->GetSttNd() );
3495cdf0e10cSrcweir 		new SwEndNode( aIdx, *pTNd );
3496cdf0e10cSrcweir 		pNewTblNd = new SwTableNode( aIdx );
3497cdf0e10cSrcweir         pNewTblNd->GetTable().SetTableModel( rTbl.IsNewModel() );
3498cdf0e10cSrcweir 
3499cdf0e10cSrcweir 		pOldTblEndNd->pStartOfSection = pNewTblNd;
3500cdf0e10cSrcweir 		pNewTblNd->pEndOfSection = pOldTblEndNd;
3501cdf0e10cSrcweir 
3502cdf0e10cSrcweir 		SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
3503cdf0e10cSrcweir 		do {
3504cdf0e10cSrcweir 			ASSERT( pBoxNd->IsStartNode(), "das muss ein StartNode sein!" );
3505cdf0e10cSrcweir 			pBoxNd->pStartOfSection = pNewTblNd;
3506cdf0e10cSrcweir 			pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
3507cdf0e10cSrcweir 		} while( pBoxNd != pOldTblEndNd );
3508cdf0e10cSrcweir 	}
3509cdf0e10cSrcweir 
3510cdf0e10cSrcweir 	{
3511cdf0e10cSrcweir         // die Lines ruebermoven...
3512cdf0e10cSrcweir 		SwTable& rNewTbl = pNewTblNd->GetTable();
3513cdf0e10cSrcweir 		rNewTbl.GetTabLines().Insert( &rTbl.GetTabLines(), 0, nLinePos );
3514cdf0e10cSrcweir         //
3515cdf0e10cSrcweir         // von hinten (unten-rechts) nach vorn (oben-links) alle Boxen
3516cdf0e10cSrcweir         // beim chart data provider austragen (das modified event wird dann
3517cdf0e10cSrcweir         // in der aufrufenden Funktion getriggert.
3518cdf0e10cSrcweir         // TL_CHART2:
3519cdf0e10cSrcweir         SwChartDataProvider *pPCD = rTbl.GetFrmFmt()->getIDocumentChartDataProviderAccess()->GetChartDataProvider();
3520cdf0e10cSrcweir         if( pPCD )
3521cdf0e10cSrcweir         {
3522cdf0e10cSrcweir             for (sal_uInt16 k = nLinePos;  k < rTbl.GetTabLines().Count();  ++k)
3523cdf0e10cSrcweir             {
3524cdf0e10cSrcweir                 sal_uInt16 nLineIdx = (rTbl.GetTabLines().Count() - 1) - k + nLinePos;
3525cdf0e10cSrcweir                 sal_uInt16 nBoxCnt = rTbl.GetTabLines()[ nLineIdx ]->GetTabBoxes().Count();
3526cdf0e10cSrcweir                 for (sal_uInt16 j = 0;  j < nBoxCnt;  ++j)
3527cdf0e10cSrcweir                 {
3528cdf0e10cSrcweir                     sal_uInt16 nIdx = nBoxCnt - 1 - j;
3529cdf0e10cSrcweir                     pPCD->DeleteBox( &rTbl, *rTbl.GetTabLines()[ nLineIdx ]->GetTabBoxes()[nIdx] );
3530cdf0e10cSrcweir                 }
3531cdf0e10cSrcweir             }
3532cdf0e10cSrcweir         }
3533cdf0e10cSrcweir         //
3534cdf0e10cSrcweir         // ...und loeschen
3535cdf0e10cSrcweir         sal_uInt16 nDeleted = rTbl.GetTabLines().Count() - nLinePos;
3536cdf0e10cSrcweir 		rTbl.GetTabLines().Remove( nLinePos, nDeleted );
3537cdf0e10cSrcweir 
3538cdf0e10cSrcweir 		// und die betr. Boxen verschieben. Dabei die Formate eindeutig
3539cdf0e10cSrcweir 		// machen und die StartNodes korrigieren
3540cdf0e10cSrcweir 		_SplitTable_Para aPara( pNewTblNd, rTbl );
3541cdf0e10cSrcweir 		rNewTbl.GetTabLines().ForEach( &lcl_SplitTable_CpyLine, &aPara );
3542cdf0e10cSrcweir         rTbl.CleanUpBottomRowSpan( nDeleted );
3543cdf0e10cSrcweir 	}
3544cdf0e10cSrcweir 
3545cdf0e10cSrcweir 	{
3546cdf0e10cSrcweir 		// Das Tabellen-FrmFormat kopieren
3547cdf0e10cSrcweir 		SwFrmFmt* pOldTblFmt = rTbl.GetFrmFmt();
3548cdf0e10cSrcweir 		SwFrmFmt* pNewTblFmt = pOldTblFmt->GetDoc()->MakeTblFrmFmt(
3549cdf0e10cSrcweir 								pOldTblFmt->GetDoc()->GetUniqueTblName(),
3550cdf0e10cSrcweir 								pOldTblFmt->GetDoc()->GetDfltFrmFmt() );
3551cdf0e10cSrcweir 
3552cdf0e10cSrcweir 		*pNewTblFmt = *pOldTblFmt;
3553cdf0e10cSrcweir         pNewTblNd->GetTable().RegisterToFormat( *pNewTblFmt );
3554cdf0e10cSrcweir 
3555cdf0e10cSrcweir 		// neue Size errechnen ? (lcl_ChgTblSize nur das 2. aufrufen, wenn es
3556cdf0e10cSrcweir 		// beim 1. schon geklappt hat; also absolute Groesse hat)
3557cdf0e10cSrcweir 		if( bCalcNewSize && lcl_ChgTblSize( rTbl ) )
3558cdf0e10cSrcweir 			lcl_ChgTblSize( pNewTblNd->GetTable() );
3559cdf0e10cSrcweir 	}
3560cdf0e10cSrcweir 
3561cdf0e10cSrcweir     // TL_CHART2: need to inform chart of probably changed cell names
3562cdf0e10cSrcweir     rTbl.UpdateCharts();
3563cdf0e10cSrcweir 
3564cdf0e10cSrcweir 	return pNewTblNd;		// das wars
3565cdf0e10cSrcweir }
3566cdf0e10cSrcweir 
3567cdf0e10cSrcweir // und die Umkehrung davon. rPos muss in der Tabelle stehen, die bestehen
3568cdf0e10cSrcweir // bleibt. Das Flag besagt ob die aktuelle mit der davor oder dahinter
3569cdf0e10cSrcweir // stehenden vereint wird.
MergeTable(const SwPosition & rPos,sal_Bool bWithPrev,sal_uInt16 nMode)3570cdf0e10cSrcweir sal_Bool SwDoc::MergeTable( const SwPosition& rPos, sal_Bool bWithPrev, sal_uInt16 nMode )
3571cdf0e10cSrcweir {
3572cdf0e10cSrcweir 	SwTableNode* pTblNd = rPos.nNode.GetNode().FindTableNode(), *pDelTblNd;
3573cdf0e10cSrcweir 	if( !pTblNd )
3574cdf0e10cSrcweir 		return sal_False;
3575cdf0e10cSrcweir 
3576cdf0e10cSrcweir 	SwNodes& rNds = GetNodes();
3577cdf0e10cSrcweir 	if( bWithPrev )
3578cdf0e10cSrcweir 		pDelTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
3579cdf0e10cSrcweir 	else
3580cdf0e10cSrcweir 		pDelTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
3581cdf0e10cSrcweir 	if( !pDelTblNd )
3582cdf0e10cSrcweir 		return sal_False;
3583cdf0e10cSrcweir 
3584cdf0e10cSrcweir 	if( pTblNd->GetTable().ISA( SwDDETable ) ||
3585cdf0e10cSrcweir 		pDelTblNd->GetTable().ISA( SwDDETable ))
3586cdf0e10cSrcweir 		return sal_False;
3587cdf0e10cSrcweir 
3588cdf0e10cSrcweir 	// MIB 9.7.97: HTML-Layout loeschen
3589cdf0e10cSrcweir 	pTblNd->GetTable().SetHTMLTableLayout( 0 );
3590cdf0e10cSrcweir 	pDelTblNd->GetTable().SetHTMLTableLayout( 0 );
3591cdf0e10cSrcweir 
3592cdf0e10cSrcweir 	// beide Tabellen vorhanden, also kanns losgehen
3593cdf0e10cSrcweir 	SwUndoMergeTbl* pUndo = 0;
3594cdf0e10cSrcweir 	SwHistory* pHistory = 0;
3595cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
3596cdf0e10cSrcweir     {
3597cdf0e10cSrcweir         pUndo = new SwUndoMergeTbl( *pTblNd, *pDelTblNd, bWithPrev, nMode );
3598cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
3599cdf0e10cSrcweir 		pHistory = new SwHistory;
3600cdf0e10cSrcweir 	}
3601cdf0e10cSrcweir 
3602cdf0e10cSrcweir 	// alle "Tabellenformeln" anpassen
3603cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
3604cdf0e10cSrcweir 	aMsgHnt.DATA.pDelTbl = &pDelTblNd->GetTable();
3605cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_MERGETBL;
3606cdf0e10cSrcweir 	aMsgHnt.pHistory = pHistory;
3607cdf0e10cSrcweir 	UpdateTblFlds( &aMsgHnt );
3608cdf0e10cSrcweir 
3609cdf0e10cSrcweir 	// das eigentliche Mergen
3610cdf0e10cSrcweir 	SwNodeIndex aIdx( bWithPrev ? *pTblNd : *pDelTblNd );
3611cdf0e10cSrcweir 	sal_Bool bRet = rNds.MergeTable( aIdx, !bWithPrev, nMode, pHistory );
3612cdf0e10cSrcweir 
3613cdf0e10cSrcweir 	if( pHistory )
3614cdf0e10cSrcweir 	{
3615cdf0e10cSrcweir 		if( pHistory->Count() )
3616cdf0e10cSrcweir 			pUndo->SaveFormula( *pHistory );
3617cdf0e10cSrcweir 		delete pHistory;
3618cdf0e10cSrcweir 	}
3619cdf0e10cSrcweir 	if( bRet )
3620cdf0e10cSrcweir 	{
3621cdf0e10cSrcweir 		SetModified();
3622cdf0e10cSrcweir 		SetFieldsDirty( true, NULL, 0 );
3623cdf0e10cSrcweir 	}
3624cdf0e10cSrcweir 	return bRet;
3625cdf0e10cSrcweir }
3626cdf0e10cSrcweir 
MergeTable(const SwNodeIndex & rPos,sal_Bool bWithPrev,sal_uInt16 nMode,SwHistory *)3627cdf0e10cSrcweir sal_Bool SwNodes::MergeTable( const SwNodeIndex& rPos, sal_Bool bWithPrev,
3628cdf0e10cSrcweir 							sal_uInt16 nMode, SwHistory* )
3629cdf0e10cSrcweir {
3630cdf0e10cSrcweir 	SwTableNode* pDelTblNd = rPos.GetNode().GetTableNode();
3631cdf0e10cSrcweir 	ASSERT( pDelTblNd, "wo ist der TableNode geblieben?" );
3632cdf0e10cSrcweir 
3633cdf0e10cSrcweir 	SwTableNode* pTblNd = (*this)[ rPos.GetIndex() - 1]->FindTableNode();
3634cdf0e10cSrcweir 	ASSERT( pTblNd, "wo ist der TableNode geblieben?" );
3635cdf0e10cSrcweir 
3636cdf0e10cSrcweir 	if( !pDelTblNd || !pTblNd )
3637cdf0e10cSrcweir 		return sal_False;
3638cdf0e10cSrcweir 
3639cdf0e10cSrcweir 	pDelTblNd->DelFrms();
3640cdf0e10cSrcweir 
3641cdf0e10cSrcweir 	SwTable& rDelTbl = pDelTblNd->GetTable();
3642cdf0e10cSrcweir 	SwTable& rTbl = pTblNd->GetTable();
3643cdf0e10cSrcweir 
3644cdf0e10cSrcweir 	//Lines fuer das Layout-Update herausuchen.
3645cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
3646cdf0e10cSrcweir     aFndBox.SetTableLines( rTbl );
3647cdf0e10cSrcweir     aFndBox.DelFrms( rTbl );
3648cdf0e10cSrcweir 
3649cdf0e10cSrcweir     // TL_CHART2: since chart currently does not want to get informed about
3650cdf0e10cSrcweir     // additional rows/cols there is no need for a modified event in the
3651cdf0e10cSrcweir     // remaining first table. Also, if it is required it  should be done
3652cdf0e10cSrcweir     // after the merging and not here...
3653cdf0e10cSrcweir     // pDoc->UpdateCharts( rTbl.GetFrmFmt()->GetName() );
3654cdf0e10cSrcweir 
3655cdf0e10cSrcweir 
3656cdf0e10cSrcweir     // TL_CHART2:
3657cdf0e10cSrcweir     // tell the charts about the table to be deleted and have them use their own data
3658cdf0e10cSrcweir     GetDoc()->CreateChartInternalDataProviders( &rDelTbl );
3659cdf0e10cSrcweir 
3660cdf0e10cSrcweir 	// die Breite der TabellenFormate abgleichen:
3661cdf0e10cSrcweir 	{
3662cdf0e10cSrcweir 		const SwFmtFrmSize& rTblSz = rTbl.GetFrmFmt()->GetFrmSize();
3663cdf0e10cSrcweir 		const SwFmtFrmSize& rDelTblSz = rDelTbl.GetFrmFmt()->GetFrmSize();
3664cdf0e10cSrcweir 		if( rTblSz != rDelTblSz )
3665cdf0e10cSrcweir 		{
3666cdf0e10cSrcweir 			// dann sollten die mal schleunigst korrigiert werden
3667cdf0e10cSrcweir 			if( bWithPrev )
3668cdf0e10cSrcweir                 rDelTbl.GetFrmFmt()->SetFmtAttr( rTblSz );
3669cdf0e10cSrcweir 			else
3670cdf0e10cSrcweir                 rTbl.GetFrmFmt()->SetFmtAttr( rDelTblSz );
3671cdf0e10cSrcweir 		}
3672cdf0e10cSrcweir 	}
3673cdf0e10cSrcweir 
3674cdf0e10cSrcweir 	if( !bWithPrev )
3675cdf0e10cSrcweir 	{
3676cdf0e10cSrcweir 		// dann mussen alle Attruibute der hinteren Tabelle auf die
3677cdf0e10cSrcweir 		// vordere uebertragen werden, weil die hintere ueber das loeschen
3678cdf0e10cSrcweir 		// des Node geloescht wird.
3679cdf0e10cSrcweir         rTbl.SetRowsToRepeat( rDelTbl.GetRowsToRepeat() );
3680cdf0e10cSrcweir 		rTbl.SetTblChgMode( rDelTbl.GetTblChgMode() );
3681cdf0e10cSrcweir 
3682cdf0e10cSrcweir 		rTbl.GetFrmFmt()->LockModify();
3683cdf0e10cSrcweir 		*rTbl.GetFrmFmt() = *rDelTbl.GetFrmFmt();
3684cdf0e10cSrcweir 		// auch den Namen umsetzen!
3685cdf0e10cSrcweir 		rTbl.GetFrmFmt()->SetName( rDelTbl.GetFrmFmt()->GetName() );
3686cdf0e10cSrcweir 		rTbl.GetFrmFmt()->UnlockModify();
3687cdf0e10cSrcweir 	}
3688cdf0e10cSrcweir 
3689cdf0e10cSrcweir 	// die Lines und Boxen ruebermoven
3690cdf0e10cSrcweir 	sal_uInt16 nOldSize = rTbl.GetTabLines().Count();
3691cdf0e10cSrcweir 	rTbl.GetTabLines().Insert( &rDelTbl.GetTabLines(), nOldSize );
3692cdf0e10cSrcweir 	rDelTbl.GetTabLines().Remove( 0, rDelTbl.GetTabLines().Count() );
3693cdf0e10cSrcweir 
3694cdf0e10cSrcweir 	rTbl.GetTabSortBoxes().Insert( &rDelTbl.GetTabSortBoxes() );
3695cdf0e10cSrcweir 	rDelTbl.GetTabSortBoxes().Remove( (sal_uInt16)0, rDelTbl.GetTabSortBoxes().Count() );
3696cdf0e10cSrcweir 
3697cdf0e10cSrcweir 	// die vordere Tabelle bleibt immer stehen, die hintere wird geloescht
3698cdf0e10cSrcweir 	SwEndNode* pTblEndNd = pDelTblNd->EndOfSectionNode();
3699cdf0e10cSrcweir 	pTblNd->pEndOfSection = pTblEndNd;
3700cdf0e10cSrcweir 
3701cdf0e10cSrcweir 	SwNodeIndex aIdx( *pDelTblNd, 1 );
3702cdf0e10cSrcweir 
3703cdf0e10cSrcweir 	SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
3704cdf0e10cSrcweir 	do {
3705cdf0e10cSrcweir 		ASSERT( pBoxNd->IsStartNode(), "das muss ein StartNode sein!" );
3706cdf0e10cSrcweir 		pBoxNd->pStartOfSection = pTblNd;
3707cdf0e10cSrcweir 		pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
3708cdf0e10cSrcweir 	} while( pBoxNd != pTblEndNd );
3709cdf0e10cSrcweir 	pBoxNd->pStartOfSection = pTblNd;
3710cdf0e10cSrcweir 
3711cdf0e10cSrcweir 	aIdx -= 2;
3712cdf0e10cSrcweir 	DelNodes( aIdx, 2 );
3713cdf0e10cSrcweir 
3714cdf0e10cSrcweir 	// jetzt an der 1. eingefuegten Line die bedingten Vorlagen umschubsen
3715cdf0e10cSrcweir 	const SwTableLine* pFirstLn = rTbl.GetTabLines()[ nOldSize ];
3716cdf0e10cSrcweir 	if( 1 == nMode )		//
3717cdf0e10cSrcweir 	{
3718cdf0e10cSrcweir 		// Header-Vorlagen in der Zeile setzen
3719cdf0e10cSrcweir 		// und ggfs. in der History speichern fuers Undo!!!
3720cdf0e10cSrcweir 	}
3721cdf0e10cSrcweir 	lcl_LineSetHeadCondColl( pFirstLn, 0 );
3722cdf0e10cSrcweir 
3723cdf0e10cSrcweir 	// und die Borders "aufrauemen"
3724cdf0e10cSrcweir 	if( nOldSize )
3725cdf0e10cSrcweir 	{
3726cdf0e10cSrcweir 		_SwGCLineBorder aPara( rTbl );
3727cdf0e10cSrcweir 		aPara.nLinePos = --nOldSize;
3728cdf0e10cSrcweir 		pFirstLn = rTbl.GetTabLines()[ nOldSize ];
3729cdf0e10cSrcweir 		lcl_GC_Line_Border( pFirstLn, &aPara );
3730cdf0e10cSrcweir 	}
3731cdf0e10cSrcweir 
3732cdf0e10cSrcweir 	//Layout updaten
3733cdf0e10cSrcweir     aFndBox.MakeFrms( rTbl );
3734cdf0e10cSrcweir 
3735cdf0e10cSrcweir     return sal_True;
3736cdf0e10cSrcweir }
3737cdf0e10cSrcweir 
3738cdf0e10cSrcweir // -------------------------------------------------------------------
3739cdf0e10cSrcweir 
3740cdf0e10cSrcweir 
3741cdf0e10cSrcweir // -- benutze die ForEach Methode vom PtrArray
3742cdf0e10cSrcweir struct _SetAFmtTabPara
3743cdf0e10cSrcweir {
3744cdf0e10cSrcweir 	SwTableAutoFmt& rTblFmt;
3745cdf0e10cSrcweir 	SwUndoTblAutoFmt* pUndo;
3746cdf0e10cSrcweir 	sal_uInt16 nEndBox, nCurBox;
3747cdf0e10cSrcweir 	sal_uInt8 nAFmtLine, nAFmtBox;
3748cdf0e10cSrcweir 
_SetAFmtTabPara_SetAFmtTabPara3749cdf0e10cSrcweir 	_SetAFmtTabPara( const SwTableAutoFmt& rNew )
3750cdf0e10cSrcweir 		: rTblFmt( (SwTableAutoFmt&)rNew ), pUndo( 0 ),
3751cdf0e10cSrcweir 		nEndBox( 0 ), nCurBox( 0 ), nAFmtLine( 0 ), nAFmtBox( 0 )
3752cdf0e10cSrcweir 	{}
3753cdf0e10cSrcweir };
3754cdf0e10cSrcweir 
3755cdf0e10cSrcweir // forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen
3756cdf0e10cSrcweir // koennen.
3757cdf0e10cSrcweir sal_Bool lcl_SetAFmtBox( const _FndBox*&, void *pPara );
3758cdf0e10cSrcweir sal_Bool lcl_SetAFmtLine( const _FndLine*&, void *pPara );
3759cdf0e10cSrcweir 
lcl_SetAFmtLine(const _FndLine * & rpLine,void * pPara)3760cdf0e10cSrcweir sal_Bool lcl_SetAFmtLine( const _FndLine*& rpLine, void *pPara )
3761cdf0e10cSrcweir {
3762cdf0e10cSrcweir 	((_FndLine*&)rpLine)->GetBoxes().ForEach( &lcl_SetAFmtBox, pPara );
3763cdf0e10cSrcweir 	return sal_True;
3764cdf0e10cSrcweir }
3765cdf0e10cSrcweir 
lcl_SetAFmtBox(const _FndBox * & rpBox,void * pPara)3766cdf0e10cSrcweir sal_Bool lcl_SetAFmtBox( const _FndBox*& rpBox, void *pPara )
3767cdf0e10cSrcweir {
3768cdf0e10cSrcweir 	_SetAFmtTabPara* pSetPara = (_SetAFmtTabPara*)pPara;
3769cdf0e10cSrcweir 
3770cdf0e10cSrcweir 	if( !rpBox->GetUpper()->GetUpper() )	// Box auf 1. Ebene ?
3771cdf0e10cSrcweir 	{
3772cdf0e10cSrcweir 		if( !pSetPara->nCurBox )
3773cdf0e10cSrcweir 			pSetPara->nAFmtBox = 0;
3774cdf0e10cSrcweir 		else if( pSetPara->nCurBox == pSetPara->nEndBox )
3775cdf0e10cSrcweir 			pSetPara->nAFmtBox = 3;
3776cdf0e10cSrcweir 		else
3777cdf0e10cSrcweir 			pSetPara->nAFmtBox = (sal_uInt8)(1 + ((pSetPara->nCurBox-1) & 1));
3778cdf0e10cSrcweir 	}
3779cdf0e10cSrcweir 
3780cdf0e10cSrcweir 	if( rpBox->GetBox()->GetSttNd() )
3781cdf0e10cSrcweir 	{
3782cdf0e10cSrcweir 		SwTableBox* pSetBox = (SwTableBox*)rpBox->GetBox();
3783cdf0e10cSrcweir 		SwDoc* pDoc = pSetBox->GetFrmFmt()->GetDoc();
3784cdf0e10cSrcweir         // --> OD 2008-02-25 #refactorlists#
3785cdf0e10cSrcweir //        SfxItemSet aCharSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 );
3786cdf0e10cSrcweir         SfxItemSet aCharSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
3787cdf0e10cSrcweir         // <--
3788cdf0e10cSrcweir 		SfxItemSet aBoxSet( pDoc->GetAttrPool(), aTableBoxSetRange );
3789cdf0e10cSrcweir 		sal_uInt8 nPos = pSetPara->nAFmtLine * 4 + pSetPara->nAFmtBox;
3790cdf0e10cSrcweir 		pSetPara->rTblFmt.UpdateToSet( nPos, aCharSet,
3791cdf0e10cSrcweir 										SwTableAutoFmt::UPDATE_CHAR, 0 );
3792cdf0e10cSrcweir 		pSetPara->rTblFmt.UpdateToSet( nPos, aBoxSet,
3793cdf0e10cSrcweir 										SwTableAutoFmt::UPDATE_BOX,
3794cdf0e10cSrcweir 										pDoc->GetNumberFormatter( sal_True ) );
3795cdf0e10cSrcweir 		if( aCharSet.Count() )
3796cdf0e10cSrcweir 		{
3797cdf0e10cSrcweir 			sal_uLong nSttNd = pSetBox->GetSttIdx()+1;
3798cdf0e10cSrcweir 			sal_uLong nEndNd = pSetBox->GetSttNd()->EndOfSectionIndex();
3799cdf0e10cSrcweir 			for( ; nSttNd < nEndNd; ++nSttNd )
3800cdf0e10cSrcweir 			{
3801cdf0e10cSrcweir 				SwCntntNode* pNd = pDoc->GetNodes()[ nSttNd ]->GetCntntNode();
3802cdf0e10cSrcweir 				if( pNd )
3803cdf0e10cSrcweir 					pNd->SetAttr( aCharSet );
3804cdf0e10cSrcweir 			}
3805cdf0e10cSrcweir 		}
3806cdf0e10cSrcweir 
3807cdf0e10cSrcweir 		if( aBoxSet.Count() )
3808cdf0e10cSrcweir 		{
3809cdf0e10cSrcweir 			if( pSetPara->pUndo &&
3810cdf0e10cSrcweir 				SFX_ITEM_SET == aBoxSet.GetItemState( RES_BOXATR_FORMAT ))
3811cdf0e10cSrcweir 				pSetPara->pUndo->SaveBoxCntnt( *pSetBox );
3812cdf0e10cSrcweir 
3813cdf0e10cSrcweir             pSetBox->ClaimFrmFmt()->SetFmtAttr( aBoxSet );
3814cdf0e10cSrcweir 		}
3815cdf0e10cSrcweir 	}
3816cdf0e10cSrcweir 	else
3817cdf0e10cSrcweir 		((_FndBox*&)rpBox)->GetLines().ForEach( &lcl_SetAFmtLine, pPara );
3818cdf0e10cSrcweir 
3819cdf0e10cSrcweir 	if( !rpBox->GetUpper()->GetUpper() )		// eine BaseLine
3820cdf0e10cSrcweir 		++pSetPara->nCurBox;
3821cdf0e10cSrcweir 	return sal_True;
3822cdf0e10cSrcweir }
3823cdf0e10cSrcweir 
3824cdf0e10cSrcweir 
3825cdf0e10cSrcweir 		// AutoFormat fuer die Tabelle/TabellenSelection
SetTableAutoFmt(const SwSelBoxes & rBoxes,const SwTableAutoFmt & rNew)3826cdf0e10cSrcweir sal_Bool SwDoc::SetTableAutoFmt( const SwSelBoxes& rBoxes, const SwTableAutoFmt& rNew )
3827cdf0e10cSrcweir {
3828cdf0e10cSrcweir 	ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
3829cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
3830cdf0e10cSrcweir 	if( !pTblNd )
3831cdf0e10cSrcweir 		return sal_False;
3832cdf0e10cSrcweir 
3833cdf0e10cSrcweir 	// suche alle Boxen / Lines
3834cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
3835cdf0e10cSrcweir 	{
3836cdf0e10cSrcweir 		_FndPara aPara( rBoxes, &aFndBox );
3837cdf0e10cSrcweir 		pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
3838cdf0e10cSrcweir 	}
3839cdf0e10cSrcweir 	if( !aFndBox.GetLines().Count() )
3840cdf0e10cSrcweir 		return sal_False;
3841cdf0e10cSrcweir 
3842cdf0e10cSrcweir 	pTblNd->GetTable().SetHTMLTableLayout( 0 );
3843cdf0e10cSrcweir 
3844cdf0e10cSrcweir 	_FndBox* pFndBox = &aFndBox;
3845cdf0e10cSrcweir 	while( 1 == pFndBox->GetLines().Count() &&
3846cdf0e10cSrcweir 			1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
3847cdf0e10cSrcweir 		pFndBox = pFndBox->GetLines()[0]->GetBoxes()[0];
3848cdf0e10cSrcweir 
3849cdf0e10cSrcweir 	if( !pFndBox->GetLines().Count() )		// eine zu weit? (nur 1 sel.Box)
3850cdf0e10cSrcweir 		pFndBox = pFndBox->GetUpper()->GetUpper();
3851cdf0e10cSrcweir 
3852cdf0e10cSrcweir 
3853cdf0e10cSrcweir 	// Undo abschalten, Attribute werden sich vorher gemerkt
3854cdf0e10cSrcweir 	SwUndoTblAutoFmt* pUndo = 0;
3855cdf0e10cSrcweir     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
3856cdf0e10cSrcweir     if (bUndo)
3857cdf0e10cSrcweir     {
3858cdf0e10cSrcweir         pUndo = new SwUndoTblAutoFmt( *pTblNd, rNew );
3859cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
3860cdf0e10cSrcweir         GetIDocumentUndoRedo().DoUndo(false);
3861cdf0e10cSrcweir     }
3862cdf0e10cSrcweir 
3863cdf0e10cSrcweir 	_SetAFmtTabPara aPara( rNew );
3864cdf0e10cSrcweir 	_FndLines& rFLns = pFndBox->GetLines();
3865cdf0e10cSrcweir 	_FndLine* pLine;
3866cdf0e10cSrcweir 
3867cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rFLns.Count(); ++n )
3868cdf0e10cSrcweir 	{
3869cdf0e10cSrcweir 		pLine = rFLns[n];
3870cdf0e10cSrcweir 
3871cdf0e10cSrcweir 		// Upper auf 0 setzen (Base-Line simulieren!)
3872cdf0e10cSrcweir 		_FndBox* pSaveBox = pLine->GetUpper();
3873cdf0e10cSrcweir 		pLine->SetUpper( 0 );
3874cdf0e10cSrcweir 
3875cdf0e10cSrcweir 		if( !n )
3876cdf0e10cSrcweir 			aPara.nAFmtLine = 0;
3877cdf0e10cSrcweir 		else if( n+1 == rFLns.Count() )
3878cdf0e10cSrcweir 			aPara.nAFmtLine = 3;
3879cdf0e10cSrcweir 		else
3880cdf0e10cSrcweir 			aPara.nAFmtLine = (sal_uInt8)(1 + ((n-1) & 1 ));
3881cdf0e10cSrcweir 
3882cdf0e10cSrcweir 		aPara.nAFmtBox = 0;
3883cdf0e10cSrcweir 		aPara.nCurBox = 0;
3884cdf0e10cSrcweir 		aPara.nEndBox = pLine->GetBoxes().Count()-1;
3885cdf0e10cSrcweir 		aPara.pUndo = pUndo;
3886cdf0e10cSrcweir 		pLine->GetBoxes().ForEach( &lcl_SetAFmtBox, &aPara );
3887cdf0e10cSrcweir 
3888cdf0e10cSrcweir 		pLine->SetUpper( pSaveBox );
3889cdf0e10cSrcweir 	}
3890cdf0e10cSrcweir 
3891cdf0e10cSrcweir 	if( pUndo )
3892cdf0e10cSrcweir     {
3893cdf0e10cSrcweir         GetIDocumentUndoRedo().DoUndo(bUndo);
3894cdf0e10cSrcweir     }
3895cdf0e10cSrcweir 
3896cdf0e10cSrcweir 	SetModified();
3897cdf0e10cSrcweir 	SetFieldsDirty( true, NULL, 0 );
3898cdf0e10cSrcweir 
3899cdf0e10cSrcweir 	return sal_True;
3900cdf0e10cSrcweir }
3901cdf0e10cSrcweir 
3902cdf0e10cSrcweir 
3903cdf0e10cSrcweir 		// Erfrage wie attributiert ist
GetTableAutoFmt(const SwSelBoxes & rBoxes,SwTableAutoFmt & rGet)3904cdf0e10cSrcweir sal_Bool SwDoc::GetTableAutoFmt( const SwSelBoxes& rBoxes, SwTableAutoFmt& rGet )
3905cdf0e10cSrcweir {
3906cdf0e10cSrcweir 	ASSERT( rBoxes.Count(), "keine gueltige Box-Liste" );
3907cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
3908cdf0e10cSrcweir 	if( !pTblNd )
3909cdf0e10cSrcweir 		return sal_False;
3910cdf0e10cSrcweir 
3911cdf0e10cSrcweir 	// suche alle Boxen / Lines
3912cdf0e10cSrcweir 	_FndBox aFndBox( 0, 0 );
3913cdf0e10cSrcweir 	{
3914cdf0e10cSrcweir 		_FndPara aPara( rBoxes, &aFndBox );
3915cdf0e10cSrcweir 		pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
3916cdf0e10cSrcweir 	}
3917cdf0e10cSrcweir 	if( !aFndBox.GetLines().Count() )
3918cdf0e10cSrcweir 		return sal_False;
3919cdf0e10cSrcweir 
3920cdf0e10cSrcweir 	_FndBox* pFndBox = &aFndBox;
3921cdf0e10cSrcweir 	while( 1 == pFndBox->GetLines().Count() &&
3922cdf0e10cSrcweir 			1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
3923cdf0e10cSrcweir 		pFndBox = pFndBox->GetLines()[0]->GetBoxes()[0];
3924cdf0e10cSrcweir 
3925cdf0e10cSrcweir 	if( !pFndBox->GetLines().Count() )		// eine zu weit? (nur 1 sel.Box)
3926cdf0e10cSrcweir 		pFndBox = pFndBox->GetUpper()->GetUpper();
3927cdf0e10cSrcweir 
3928cdf0e10cSrcweir 	_FndLines& rFLns = pFndBox->GetLines();
3929cdf0e10cSrcweir 
3930cdf0e10cSrcweir 	sal_uInt16 aLnArr[4];
3931cdf0e10cSrcweir 	aLnArr[0] = 0;
3932cdf0e10cSrcweir 	aLnArr[1] = 1 < rFLns.Count() ? 1 : 0;
3933cdf0e10cSrcweir 	aLnArr[2] = 2 < rFLns.Count() ? 2 : aLnArr[1];
3934cdf0e10cSrcweir 	aLnArr[3] = rFLns.Count() - 1;
3935cdf0e10cSrcweir 
3936cdf0e10cSrcweir 	for( sal_uInt8 nLine = 0; nLine < 4; ++nLine )
3937cdf0e10cSrcweir 	{
3938cdf0e10cSrcweir 		_FndLine& rLine = *rFLns[ aLnArr[ nLine ] ];
3939cdf0e10cSrcweir 
3940cdf0e10cSrcweir 		sal_uInt16 aBoxArr[4];
3941cdf0e10cSrcweir 		aBoxArr[0] = 0;
3942cdf0e10cSrcweir 		aBoxArr[1] = 1 < rLine.GetBoxes().Count() ? 1 : 0;
3943cdf0e10cSrcweir 		aBoxArr[2] = 2 < rLine.GetBoxes().Count() ? 2 : aBoxArr[1];
3944cdf0e10cSrcweir 		aBoxArr[3] = rLine.GetBoxes().Count() - 1;
3945cdf0e10cSrcweir 
3946cdf0e10cSrcweir 		for( sal_uInt8 nBox = 0; nBox < 4; ++nBox )
3947cdf0e10cSrcweir 		{
3948cdf0e10cSrcweir 			SwTableBox* pFBox = rLine.GetBoxes()[ aBoxArr[ nBox ] ]->GetBox();
3949cdf0e10cSrcweir 			// immer auf die 1. runterfallen
3950cdf0e10cSrcweir 			while( !pFBox->GetSttNd() )
3951cdf0e10cSrcweir 				pFBox = pFBox->GetTabLines()[0]->GetTabBoxes()[0];
3952cdf0e10cSrcweir 
3953cdf0e10cSrcweir 			sal_uInt8 nPos = nLine * 4 + nBox;
3954cdf0e10cSrcweir 			SwNodeIndex aIdx( *pFBox->GetSttNd(), 1 );
3955cdf0e10cSrcweir 			SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
3956cdf0e10cSrcweir 			if( !pCNd )
3957cdf0e10cSrcweir 				pCNd = GetNodes().GoNext( &aIdx );
3958cdf0e10cSrcweir 
3959cdf0e10cSrcweir 			if( pCNd )
3960cdf0e10cSrcweir 				rGet.UpdateFromSet( nPos, pCNd->GetSwAttrSet(),
3961cdf0e10cSrcweir 									SwTableAutoFmt::UPDATE_CHAR, 0 );
3962cdf0e10cSrcweir 			rGet.UpdateFromSet( nPos, pFBox->GetFrmFmt()->GetAttrSet(),
3963cdf0e10cSrcweir 								SwTableAutoFmt::UPDATE_BOX,
3964cdf0e10cSrcweir 								GetNumberFormatter( sal_True ) );
3965cdf0e10cSrcweir 		}
3966cdf0e10cSrcweir 	}
3967cdf0e10cSrcweir 
3968cdf0e10cSrcweir 	return sal_True;
3969cdf0e10cSrcweir }
3970cdf0e10cSrcweir 
GetUniqueTblName() const3971cdf0e10cSrcweir String SwDoc::GetUniqueTblName() const
3972cdf0e10cSrcweir {
3973cdf0e10cSrcweir 	ResId aId( STR_TABLE_DEFNAME, *pSwResMgr );
3974cdf0e10cSrcweir 	String aName( aId );
3975cdf0e10cSrcweir 	xub_StrLen nNmLen = aName.Len();
3976cdf0e10cSrcweir 
3977cdf0e10cSrcweir 	sal_uInt16 nNum, nTmp, nFlagSize = ( pTblFrmFmtTbl->Count() / 8 ) +2;
3978cdf0e10cSrcweir 	sal_uInt16 n;
3979cdf0e10cSrcweir 
3980cdf0e10cSrcweir 	sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
3981cdf0e10cSrcweir 	memset( pSetFlags, 0, nFlagSize );
3982cdf0e10cSrcweir 
3983cdf0e10cSrcweir 	for( n = 0; n < pTblFrmFmtTbl->Count(); ++n )
3984cdf0e10cSrcweir 	{
3985cdf0e10cSrcweir 		const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ];
3986cdf0e10cSrcweir 		if( !pFmt->IsDefault() && IsUsed( *pFmt )  &&
3987cdf0e10cSrcweir 			pFmt->GetName().Match( aName ) == nNmLen )
3988cdf0e10cSrcweir 		{
3989cdf0e10cSrcweir 			// Nummer bestimmen und das Flag setzen
3990cdf0e10cSrcweir 			nNum = static_cast<sal_uInt16>(pFmt->GetName().Copy( nNmLen ).ToInt32());
3991cdf0e10cSrcweir 			if( nNum-- && nNum < pTblFrmFmtTbl->Count() )
3992cdf0e10cSrcweir 				pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
3993cdf0e10cSrcweir 		}
3994cdf0e10cSrcweir 	}
3995cdf0e10cSrcweir 
3996cdf0e10cSrcweir 	// alle Nummern entsprechend geflag, also bestimme die richtige Nummer
3997cdf0e10cSrcweir 	nNum = pTblFrmFmtTbl->Count();
3998cdf0e10cSrcweir 	for( n = 0; n < nFlagSize; ++n )
3999cdf0e10cSrcweir 		if( 0xff != ( nTmp = pSetFlags[ n ] ))
4000cdf0e10cSrcweir 		{
4001cdf0e10cSrcweir 			// also die Nummer bestimmen
4002cdf0e10cSrcweir 			nNum = n * 8;
4003cdf0e10cSrcweir 			while( nTmp & 1 )
4004cdf0e10cSrcweir 				++nNum, nTmp >>= 1;
4005cdf0e10cSrcweir 			break;
4006cdf0e10cSrcweir 		}
4007cdf0e10cSrcweir 
4008cdf0e10cSrcweir 	delete [] pSetFlags;
4009cdf0e10cSrcweir 	return aName += String::CreateFromInt32( ++nNum );
4010cdf0e10cSrcweir }
4011cdf0e10cSrcweir 
FindTblFmtByName(const String & rName,sal_Bool bAll) const4012cdf0e10cSrcweir SwTableFmt* SwDoc::FindTblFmtByName( const String& rName, sal_Bool bAll ) const
4013cdf0e10cSrcweir {
4014cdf0e10cSrcweir 	const SwFmt* pRet = 0;
4015cdf0e10cSrcweir 	if( bAll )
4016cdf0e10cSrcweir 		pRet = FindFmtByName( (SvPtrarr&)*pTblFrmFmtTbl, rName );
4017cdf0e10cSrcweir 	else
4018cdf0e10cSrcweir 	{
4019cdf0e10cSrcweir 		// dann nur die, die im Doc gesetzt sind
4020cdf0e10cSrcweir 		for( sal_uInt16 n = 0; n < pTblFrmFmtTbl->Count(); ++n )
4021cdf0e10cSrcweir 		{
4022cdf0e10cSrcweir 			const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ];
4023cdf0e10cSrcweir 			if( !pFmt->IsDefault() && IsUsed( *pFmt ) &&
4024cdf0e10cSrcweir 				pFmt->GetName() == rName )
4025cdf0e10cSrcweir 			{
4026cdf0e10cSrcweir 				pRet = pFmt;
4027cdf0e10cSrcweir 				break;
4028cdf0e10cSrcweir 			}
4029cdf0e10cSrcweir 		}
4030cdf0e10cSrcweir 	}
4031cdf0e10cSrcweir 	return (SwTableFmt*)pRet;
4032cdf0e10cSrcweir }
4033cdf0e10cSrcweir 
SetColRowWidthHeight(SwTableBox & rAktBox,sal_uInt16 eType,SwTwips nAbsDiff,SwTwips nRelDiff)4034cdf0e10cSrcweir sal_Bool SwDoc::SetColRowWidthHeight( SwTableBox& rAktBox, sal_uInt16 eType,
4035cdf0e10cSrcweir 									SwTwips nAbsDiff, SwTwips nRelDiff )
4036cdf0e10cSrcweir {
4037cdf0e10cSrcweir 	SwTableNode* pTblNd = (SwTableNode*)rAktBox.GetSttNd()->FindTableNode();
4038cdf0e10cSrcweir 	SwUndo* pUndo = 0;
4039cdf0e10cSrcweir 
4040cdf0e10cSrcweir 	if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType && pTblNd->GetTable().ISA( SwDDETable ))
4041cdf0e10cSrcweir 		return sal_False;
4042cdf0e10cSrcweir 
4043cdf0e10cSrcweir 	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
4044cdf0e10cSrcweir 	aMsgHnt.eFlags = TBL_BOXPTR;
4045cdf0e10cSrcweir 	UpdateTblFlds( &aMsgHnt );
4046cdf0e10cSrcweir 
4047cdf0e10cSrcweir     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
4048cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
4049cdf0e10cSrcweir 	switch( eType & 0xff )
4050cdf0e10cSrcweir 	{
4051cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_COL_LEFT:
4052cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_COL_RIGHT:
4053cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_CELL_LEFT:
4054cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_CELL_RIGHT:
4055cdf0e10cSrcweir 		{
4056cdf0e10cSrcweir 			 bRet = pTblNd->GetTable().SetColWidth( rAktBox,
4057cdf0e10cSrcweir 								eType, nAbsDiff, nRelDiff,
4058cdf0e10cSrcweir                                 (bUndo) ? &pUndo : 0 );
4059cdf0e10cSrcweir         }
4060cdf0e10cSrcweir 		break;
4061cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_ROW_TOP:
4062cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
4063cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_CELL_TOP:
4064cdf0e10cSrcweir 	case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
4065cdf0e10cSrcweir 		bRet = pTblNd->GetTable().SetRowHeight( rAktBox,
4066cdf0e10cSrcweir 							eType, nAbsDiff, nRelDiff,
4067cdf0e10cSrcweir                             (bUndo) ? &pUndo : 0 );
4068cdf0e10cSrcweir 		break;
4069cdf0e10cSrcweir 	}
4070cdf0e10cSrcweir 
4071cdf0e10cSrcweir     GetIDocumentUndoRedo().DoUndo(bUndo); // SetColWidth can turn it off
4072cdf0e10cSrcweir 	if( pUndo )
4073cdf0e10cSrcweir     {
4074cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo( pUndo );
4075cdf0e10cSrcweir     }
4076cdf0e10cSrcweir 
4077cdf0e10cSrcweir 	if( bRet )
4078cdf0e10cSrcweir 	{
4079cdf0e10cSrcweir 		SetModified();
4080cdf0e10cSrcweir 		if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType )
4081cdf0e10cSrcweir 			SetFieldsDirty( true, NULL, 0 );
4082cdf0e10cSrcweir 	}
4083cdf0e10cSrcweir 	return bRet;
4084cdf0e10cSrcweir }
4085cdf0e10cSrcweir 
4086cdf0e10cSrcweir 
ChkBoxNumFmt(SwTableBox & rBox,sal_Bool bCallUpdate)4087cdf0e10cSrcweir void SwDoc::ChkBoxNumFmt( SwTableBox& rBox, sal_Bool bCallUpdate )
4088cdf0e10cSrcweir {
4089cdf0e10cSrcweir 	//JP 09.07.97: Optimierung: wenn die Box schon sagt, das es Text
4090cdf0e10cSrcweir 	//							sein soll, dann bleibt das auch Text!
4091cdf0e10cSrcweir 	const SfxPoolItem* pNumFmtItem = 0;
4092cdf0e10cSrcweir 	if( SFX_ITEM_SET == rBox.GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT,
4093cdf0e10cSrcweir 		sal_False, &pNumFmtItem ) && GetNumberFormatter()->IsTextFormat(
4094cdf0e10cSrcweir 			((SwTblBoxNumFormat*)pNumFmtItem)->GetValue() ))
4095cdf0e10cSrcweir 		return ;
4096cdf0e10cSrcweir 
4097cdf0e10cSrcweir 	SwUndoTblNumFmt* pUndo = 0;
4098cdf0e10cSrcweir 
4099cdf0e10cSrcweir 	sal_Bool bIsEmptyTxtNd, bChgd = sal_True;
4100cdf0e10cSrcweir 	sal_uInt32 nFmtIdx;
4101cdf0e10cSrcweir 	double fNumber;
4102cdf0e10cSrcweir 	if( rBox.HasNumCntnt( fNumber, nFmtIdx, bIsEmptyTxtNd ) )
4103cdf0e10cSrcweir 	{
4104cdf0e10cSrcweir 		if( !rBox.IsNumberChanged() )
4105cdf0e10cSrcweir 			bChgd = sal_False;
4106cdf0e10cSrcweir 		else
4107cdf0e10cSrcweir 		{
4108cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
4109cdf0e10cSrcweir             {
4110cdf0e10cSrcweir                 GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_AUTOFMT, NULL );
4111cdf0e10cSrcweir 				pUndo = new SwUndoTblNumFmt( rBox );
4112cdf0e10cSrcweir 				pUndo->SetNumFmt( nFmtIdx, fNumber );
4113cdf0e10cSrcweir 			}
4114cdf0e10cSrcweir 
4115cdf0e10cSrcweir 			SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
4116cdf0e10cSrcweir 			SfxItemSet aBoxSet( GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
4117cdf0e10cSrcweir 
4118cdf0e10cSrcweir 			sal_Bool bSetNumFmt = IsInsTblFormatNum(), bLockModify = sal_True;
4119cdf0e10cSrcweir 			if( bSetNumFmt )
4120cdf0e10cSrcweir 			{
4121cdf0e10cSrcweir 				if( !IsInsTblChangeNumFormat() )
4122cdf0e10cSrcweir 				{
4123cdf0e10cSrcweir 					if( !pNumFmtItem )
4124cdf0e10cSrcweir 						bSetNumFmt = sal_False;
4125cdf0e10cSrcweir 					else
4126cdf0e10cSrcweir 					{
4127cdf0e10cSrcweir 						sal_uLong nOldNumFmt = ((SwTblBoxNumFormat*)pNumFmtItem)->
4128cdf0e10cSrcweir 											GetValue();
4129cdf0e10cSrcweir 						SvNumberFormatter* pNumFmtr = GetNumberFormatter();
4130cdf0e10cSrcweir 
4131cdf0e10cSrcweir 						short nFmtType = pNumFmtr->GetType( nFmtIdx );
4132cdf0e10cSrcweir 						if( nFmtType == pNumFmtr->GetType( nOldNumFmt ) ||
4133cdf0e10cSrcweir 							NUMBERFORMAT_NUMBER == nFmtType )
4134cdf0e10cSrcweir 							// eingstelltes und vorgegebenes NumFormat
4135cdf0e10cSrcweir 							// stimmen ueberein -> altes Format beibehalten
4136cdf0e10cSrcweir 							nFmtIdx = nOldNumFmt;
4137cdf0e10cSrcweir 						else
4138cdf0e10cSrcweir 							// eingstelltes und vorgegebenes NumFormat
4139cdf0e10cSrcweir 							// stimmen nicht ueberein -> als Text einfuegen
4140cdf0e10cSrcweir 							bLockModify = bSetNumFmt = sal_False;
4141cdf0e10cSrcweir 					}
4142cdf0e10cSrcweir 				}
4143cdf0e10cSrcweir 
4144cdf0e10cSrcweir 				if( bSetNumFmt )
4145cdf0e10cSrcweir 				{
4146cdf0e10cSrcweir 					pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
4147cdf0e10cSrcweir 
4148cdf0e10cSrcweir 					aBoxSet.Put( SwTblBoxValue( fNumber ));
4149cdf0e10cSrcweir 					aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
4150cdf0e10cSrcweir 				}
4151cdf0e10cSrcweir 			}
4152cdf0e10cSrcweir 
4153cdf0e10cSrcweir 			// JP 28.04.98: Nur Formel zuruecksetzen reicht nicht.
4154cdf0e10cSrcweir 			//				Sorge dafuer, das der Text auch entsprechend
4155cdf0e10cSrcweir 			//				formatiert wird!
4156cdf0e10cSrcweir 
4157cdf0e10cSrcweir 			if( !bSetNumFmt && !bIsEmptyTxtNd && pNumFmtItem )
4158cdf0e10cSrcweir 			{
4159cdf0e10cSrcweir 				// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
4160cdf0e10cSrcweir 				//				Sorge dafuer, das der Text auch entsprechend
4161cdf0e10cSrcweir 				//				formatiert wird!
4162cdf0e10cSrcweir                 pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
4163cdf0e10cSrcweir 			}
4164cdf0e10cSrcweir 
4165cdf0e10cSrcweir 			if( bLockModify ) pBoxFmt->LockModify();
4166cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
4167cdf0e10cSrcweir 			if( bLockModify ) pBoxFmt->UnlockModify();
4168cdf0e10cSrcweir 
4169cdf0e10cSrcweir 			if( bSetNumFmt )
4170cdf0e10cSrcweir                 pBoxFmt->SetFmtAttr( aBoxSet );
4171cdf0e10cSrcweir 		}
4172cdf0e10cSrcweir 	}
4173cdf0e10cSrcweir 	else
4174cdf0e10cSrcweir 	{
4175cdf0e10cSrcweir 		// es ist keine Zahl
4176cdf0e10cSrcweir 		const SfxPoolItem* pValueItem = 0, *pFmtItem = 0;
4177cdf0e10cSrcweir 		SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
4178cdf0e10cSrcweir 		if( SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_FORMAT,
4179cdf0e10cSrcweir 				sal_False, &pFmtItem ) ||
4180cdf0e10cSrcweir 			SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_VALUE,
4181cdf0e10cSrcweir 				sal_False, &pValueItem ))
4182cdf0e10cSrcweir 		{
4183cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
4184cdf0e10cSrcweir             {
4185cdf0e10cSrcweir                 GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_AUTOFMT, NULL );
4186cdf0e10cSrcweir 				pUndo = new SwUndoTblNumFmt( rBox );
4187cdf0e10cSrcweir 			}
4188cdf0e10cSrcweir 
4189cdf0e10cSrcweir 			pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
4190cdf0e10cSrcweir 
4191cdf0e10cSrcweir 			// alle Zahlenformate entfernen
4192cdf0e10cSrcweir 			sal_uInt16 nWhich1 = RES_BOXATR_FORMULA;
4193cdf0e10cSrcweir 			if( !bIsEmptyTxtNd )
4194cdf0e10cSrcweir 				//JP 15.01.99: dieser Teil wurde doch schon oben abgeprueft!
4195cdf0e10cSrcweir 				/* && pFmtItem && !GetNumberFormatter()->
4196cdf0e10cSrcweir 				IsTextFormat( ((SwTblBoxNumFormat*)pFmtItem)->GetValue() ) )*/
4197cdf0e10cSrcweir 			{
4198cdf0e10cSrcweir 				nWhich1 = RES_BOXATR_FORMAT;
4199cdf0e10cSrcweir 
4200cdf0e10cSrcweir 				// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
4201cdf0e10cSrcweir 				//				Sorge dafuer, das der Text auch entsprechend
4202cdf0e10cSrcweir 				//				formatiert wird!
4203cdf0e10cSrcweir                 pBoxFmt->SetFmtAttr( *GetDfltAttr( nWhich1 ));
4204cdf0e10cSrcweir 			}
4205cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( nWhich1, RES_BOXATR_VALUE );
4206cdf0e10cSrcweir 		}
4207cdf0e10cSrcweir 		else
4208cdf0e10cSrcweir 			bChgd = sal_False;
4209cdf0e10cSrcweir 	}
4210cdf0e10cSrcweir 
4211cdf0e10cSrcweir 	if( bChgd )
4212cdf0e10cSrcweir 	{
4213cdf0e10cSrcweir 		if( pUndo )
4214cdf0e10cSrcweir 		{
4215cdf0e10cSrcweir 			pUndo->SetBox( rBox );
4216cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo(pUndo);
4217cdf0e10cSrcweir             GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
4218cdf0e10cSrcweir         }
4219cdf0e10cSrcweir 
4220cdf0e10cSrcweir 		const SwTableNode* pTblNd = rBox.GetSttNd()->FindTableNode();
4221cdf0e10cSrcweir 		if( bCallUpdate )
4222cdf0e10cSrcweir 		{
4223cdf0e10cSrcweir 			SwTableFmlUpdate aTblUpdate( &pTblNd->GetTable() );
4224cdf0e10cSrcweir 			UpdateTblFlds( &aTblUpdate );
4225cdf0e10cSrcweir 
4226cdf0e10cSrcweir 			// TL_CHART2: update charts (when cursor leaves cell and
4227cdf0e10cSrcweir 			// automatic update is enabled)
4228cdf0e10cSrcweir 			if (AUTOUPD_FIELD_AND_CHARTS == getFieldUpdateFlags(true))
4229cdf0e10cSrcweir 				pTblNd->GetTable().UpdateCharts();
4230cdf0e10cSrcweir 		}
4231cdf0e10cSrcweir 		SetModified();
4232cdf0e10cSrcweir 	}
4233cdf0e10cSrcweir }
4234cdf0e10cSrcweir 
SetTblBoxFormulaAttrs(SwTableBox & rBox,const SfxItemSet & rSet)4235cdf0e10cSrcweir void SwDoc::SetTblBoxFormulaAttrs( SwTableBox& rBox, const SfxItemSet& rSet )
4236cdf0e10cSrcweir {
4237cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
4238cdf0e10cSrcweir     {
4239cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo( new SwUndoTblNumFmt(rBox, &rSet) );
4240cdf0e10cSrcweir     }
4241cdf0e10cSrcweir 
4242cdf0e10cSrcweir 	SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
4243cdf0e10cSrcweir 	if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
4244cdf0e10cSrcweir 	{
4245cdf0e10cSrcweir 		pBoxFmt->LockModify();
4246cdf0e10cSrcweir         pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
4247cdf0e10cSrcweir 		pBoxFmt->UnlockModify();
4248cdf0e10cSrcweir 	}
4249cdf0e10cSrcweir 	else if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE ))
4250cdf0e10cSrcweir 	{
4251cdf0e10cSrcweir 		pBoxFmt->LockModify();
4252cdf0e10cSrcweir         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
4253cdf0e10cSrcweir 		pBoxFmt->UnlockModify();
4254cdf0e10cSrcweir 	}
4255cdf0e10cSrcweir     pBoxFmt->SetFmtAttr( rSet );
4256cdf0e10cSrcweir 	SetModified();
4257cdf0e10cSrcweir }
4258cdf0e10cSrcweir 
ClearBoxNumAttrs(const SwNodeIndex & rNode)4259cdf0e10cSrcweir void SwDoc::ClearBoxNumAttrs( const SwNodeIndex& rNode )
4260cdf0e10cSrcweir {
4261cdf0e10cSrcweir 	SwStartNode* pSttNd;
4262cdf0e10cSrcweir     if( 0 != ( pSttNd = rNode.GetNode().
4263cdf0e10cSrcweir 								FindSttNodeByType( SwTableBoxStartNode )) &&
4264cdf0e10cSrcweir 		2 == pSttNd->EndOfSectionIndex() - pSttNd->GetIndex() )
4265cdf0e10cSrcweir 	{
4266cdf0e10cSrcweir 		SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
4267cdf0e10cSrcweir 							GetTblBox( pSttNd->GetIndex() );
4268cdf0e10cSrcweir 
4269cdf0e10cSrcweir 		const SfxPoolItem* pFmtItem = 0;
4270cdf0e10cSrcweir 		const SfxItemSet& rSet = pBox->GetFrmFmt()->GetAttrSet();
4271cdf0e10cSrcweir 		if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT, sal_False, &pFmtItem ) ||
4272cdf0e10cSrcweir 			SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA, sal_False ) ||
4273cdf0e10cSrcweir 			SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE, sal_False ))
4274cdf0e10cSrcweir 		{
4275cdf0e10cSrcweir             if (GetIDocumentUndoRedo().DoesUndo())
4276cdf0e10cSrcweir             {
4277cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(new SwUndoTblNumFmt(*pBox));
4278cdf0e10cSrcweir             }
4279cdf0e10cSrcweir 
4280cdf0e10cSrcweir 			SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
4281cdf0e10cSrcweir 
4282cdf0e10cSrcweir 			//JP 01.09.97: TextFormate bleiben erhalten!
4283cdf0e10cSrcweir 			sal_uInt16 nWhich1 = RES_BOXATR_FORMAT;
4284cdf0e10cSrcweir 			if( pFmtItem && GetNumberFormatter()->IsTextFormat(
4285cdf0e10cSrcweir 					((SwTblBoxNumFormat*)pFmtItem)->GetValue() ))
4286cdf0e10cSrcweir 				nWhich1 = RES_BOXATR_FORMULA;
4287cdf0e10cSrcweir 			else
4288cdf0e10cSrcweir 				// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
4289cdf0e10cSrcweir 				//				Sorge dafuer, das der Text auch entsprechend
4290cdf0e10cSrcweir 				//				formatiert wird!
4291cdf0e10cSrcweir                 pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
4292cdf0e10cSrcweir 
4293cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( nWhich1, RES_BOXATR_VALUE );
4294cdf0e10cSrcweir 			SetModified();
4295cdf0e10cSrcweir 		}
4296cdf0e10cSrcweir 	}
4297cdf0e10cSrcweir }
4298cdf0e10cSrcweir 
4299cdf0e10cSrcweir // kopiert eine Tabelle aus dem selben oder einem anderen Doc in sich
4300cdf0e10cSrcweir // selbst. Dabei wird eine neue Tabelle angelegt oder eine bestehende
4301cdf0e10cSrcweir // mit dem Inhalt gefuellt; wobei entweder der Inhalt ab einer Box oder
4302cdf0e10cSrcweir // in eine bestehende TblSelektion gefuellt wird.
4303cdf0e10cSrcweir // Gerufen wird es von: edglss.cxx/fecopy.cxx
4304cdf0e10cSrcweir 
InsCopyOfTbl(SwPosition & rInsPos,const SwSelBoxes & rBoxes,const SwTable * pCpyTbl,sal_Bool bCpyName,sal_Bool bCorrPos)4305cdf0e10cSrcweir sal_Bool SwDoc::InsCopyOfTbl( SwPosition& rInsPos, const SwSelBoxes& rBoxes,
4306cdf0e10cSrcweir 						const SwTable* pCpyTbl, sal_Bool bCpyName, sal_Bool bCorrPos )
4307cdf0e10cSrcweir {
4308cdf0e10cSrcweir 	sal_Bool bRet;
4309cdf0e10cSrcweir 
4310cdf0e10cSrcweir 	const SwTableNode* pSrcTblNd = pCpyTbl
4311cdf0e10cSrcweir 			? pCpyTbl->GetTableNode()
4312cdf0e10cSrcweir 			: rBoxes[ 0 ]->GetSttNd()->FindTableNode();
4313cdf0e10cSrcweir 
4314cdf0e10cSrcweir     SwTableNode * pInsTblNd = rInsPos.nNode.GetNode().FindTableNode();
4315cdf0e10cSrcweir 
4316cdf0e10cSrcweir     bool const bUndo( GetIDocumentUndoRedo().DoesUndo() );
4317cdf0e10cSrcweir 	if( !pCpyTbl && !pInsTblNd )
4318cdf0e10cSrcweir 	{
4319cdf0e10cSrcweir 		SwUndoCpyTbl* pUndo = 0;
4320cdf0e10cSrcweir         if (bUndo)
4321cdf0e10cSrcweir         {
4322cdf0e10cSrcweir             GetIDocumentUndoRedo().ClearRedo();
4323cdf0e10cSrcweir 			pUndo = new SwUndoCpyTbl;
4324cdf0e10cSrcweir         }
4325cdf0e10cSrcweir 
4326cdf0e10cSrcweir         {
4327cdf0e10cSrcweir             ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
4328cdf0e10cSrcweir             bRet = pSrcTblNd->GetTable().MakeCopy( this, rInsPos, rBoxes,
4329cdf0e10cSrcweir 												sal_True, bCpyName );
4330cdf0e10cSrcweir         }
4331cdf0e10cSrcweir 
4332cdf0e10cSrcweir 		if( pUndo )
4333cdf0e10cSrcweir 		{
4334cdf0e10cSrcweir 			if( !bRet )
4335cdf0e10cSrcweir             {
4336cdf0e10cSrcweir 				delete pUndo;
4337cdf0e10cSrcweir                 pUndo = 0;
4338cdf0e10cSrcweir             }
4339cdf0e10cSrcweir 			else
4340cdf0e10cSrcweir 			{
4341cdf0e10cSrcweir 				pInsTblNd = GetNodes()[ rInsPos.nNode.GetIndex() - 1 ]->FindTableNode();
4342cdf0e10cSrcweir 
4343cdf0e10cSrcweir 				pUndo->SetTableSttIdx( pInsTblNd->GetIndex() );
4344cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo( pUndo );
4345cdf0e10cSrcweir             }
4346cdf0e10cSrcweir 		}
4347cdf0e10cSrcweir 	}
4348cdf0e10cSrcweir 	else
4349cdf0e10cSrcweir 	{
4350cdf0e10cSrcweir         RedlineMode_t eOld = GetRedlineMode();
4351cdf0e10cSrcweir         if( IsRedlineOn() )
4352cdf0e10cSrcweir 	  SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON |
4353cdf0e10cSrcweir 								  nsRedlineMode_t::REDLINE_SHOW_INSERT |
4354cdf0e10cSrcweir 								  nsRedlineMode_t::REDLINE_SHOW_DELETE));
4355cdf0e10cSrcweir 
4356cdf0e10cSrcweir 		SwUndoTblCpyTbl* pUndo = 0;
4357cdf0e10cSrcweir         if (bUndo)
4358cdf0e10cSrcweir         {
4359cdf0e10cSrcweir             GetIDocumentUndoRedo().ClearRedo();
4360cdf0e10cSrcweir 			pUndo = new SwUndoTblCpyTbl;
4361cdf0e10cSrcweir             GetIDocumentUndoRedo().DoUndo(false);
4362cdf0e10cSrcweir         }
4363cdf0e10cSrcweir 
4364cdf0e10cSrcweir 		SwDoc* pCpyDoc = (SwDoc*)pSrcTblNd->GetDoc();
4365cdf0e10cSrcweir 		sal_Bool bDelCpyDoc = pCpyDoc == this;
4366cdf0e10cSrcweir 
4367cdf0e10cSrcweir 		if( bDelCpyDoc )
4368cdf0e10cSrcweir 		{
4369cdf0e10cSrcweir 			// kopiere die Tabelle erstmal in ein temp. Doc
4370cdf0e10cSrcweir 			pCpyDoc = new SwDoc;
4371cdf0e10cSrcweir             pCpyDoc->acquire();
4372cdf0e10cSrcweir 
4373cdf0e10cSrcweir 			SwPosition aPos( SwNodeIndex( pCpyDoc->GetNodes().GetEndOfContent() ));
4374cdf0e10cSrcweir 			if( !pSrcTblNd->GetTable().MakeCopy( pCpyDoc, aPos, rBoxes, sal_True, sal_True ))
4375cdf0e10cSrcweir 			{
4376cdf0e10cSrcweir                 if( pCpyDoc->release() == 0 )
4377cdf0e10cSrcweir                     delete pCpyDoc;
4378cdf0e10cSrcweir 
4379cdf0e10cSrcweir 				if( pUndo )
4380cdf0e10cSrcweir                 {
4381cdf0e10cSrcweir                     GetIDocumentUndoRedo().DoUndo(bUndo);
4382cdf0e10cSrcweir 					delete pUndo;
4383cdf0e10cSrcweir                     pUndo = 0;
4384cdf0e10cSrcweir 				}
4385cdf0e10cSrcweir 				return sal_False;
4386cdf0e10cSrcweir 			}
4387cdf0e10cSrcweir 			aPos.nNode -= 1;		// auf den EndNode der Tabelle
4388cdf0e10cSrcweir 			pSrcTblNd = aPos.nNode.GetNode().FindTableNode();
4389cdf0e10cSrcweir 		}
4390cdf0e10cSrcweir 
4391cdf0e10cSrcweir 		const SwStartNode* pSttNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
4392cdf0e10cSrcweir 
4393cdf0e10cSrcweir 		rInsPos.nContent.Assign( 0, 0 );
4394cdf0e10cSrcweir 
4395cdf0e10cSrcweir 		// no complex into complex, but copy into or from new model is welcome
4396cdf0e10cSrcweir 		if( ( !pSrcTblNd->GetTable().IsTblComplex() || pInsTblNd->GetTable().IsNewModel() )
4397cdf0e10cSrcweir             && ( bDelCpyDoc || rBoxes.Count() ) )
4398cdf0e10cSrcweir 		{
4399cdf0e10cSrcweir 			// dann die Tabelle "relativ" kopieren
4400cdf0e10cSrcweir 			const SwSelBoxes* pBoxes;
4401cdf0e10cSrcweir 			SwSelBoxes aBoxes;
4402cdf0e10cSrcweir 
4403cdf0e10cSrcweir 			if( bDelCpyDoc )
4404cdf0e10cSrcweir 			{
4405cdf0e10cSrcweir 				SwTableBox* pBox = pInsTblNd->GetTable().GetTblBox(
4406cdf0e10cSrcweir 										pSttNd->GetIndex() );
4407cdf0e10cSrcweir 				ASSERT( pBox, "Box steht nicht in dieser Tabelle" );
4408cdf0e10cSrcweir 				aBoxes.Insert( pBox );
4409cdf0e10cSrcweir 				pBoxes = &aBoxes;
4410cdf0e10cSrcweir 			}
4411cdf0e10cSrcweir 			else
4412cdf0e10cSrcweir 				pBoxes = &rBoxes;
4413cdf0e10cSrcweir 
4414cdf0e10cSrcweir 			// kopiere die Tabelle in die selktierten Zellen.
4415cdf0e10cSrcweir 			bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
4416cdf0e10cSrcweir 														*pBoxes, pUndo );
4417cdf0e10cSrcweir 		}
4418cdf0e10cSrcweir 		else
4419cdf0e10cSrcweir 		{
4420cdf0e10cSrcweir 			SwNodeIndex aNdIdx( *pSttNd, 1 );
4421cdf0e10cSrcweir 			bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
4422cdf0e10cSrcweir 													aNdIdx, pUndo );
4423cdf0e10cSrcweir 		}
4424cdf0e10cSrcweir 
4425cdf0e10cSrcweir 		if( bDelCpyDoc )
4426cdf0e10cSrcweir         {
4427cdf0e10cSrcweir             if( pCpyDoc->release() == 0 )
4428cdf0e10cSrcweir                 delete pCpyDoc;
4429cdf0e10cSrcweir         }
4430cdf0e10cSrcweir 
4431cdf0e10cSrcweir 		if( pUndo )
4432cdf0e10cSrcweir 		{
4433cdf0e10cSrcweir 			// falls die Tabelle nicht kopiert werden konnte, das Undo-Object
4434cdf0e10cSrcweir 			// wieder loeschen
4435cdf0e10cSrcweir             GetIDocumentUndoRedo().DoUndo(bUndo);
4436cdf0e10cSrcweir 			if( !bRet && pUndo->IsEmpty() )
4437cdf0e10cSrcweir 				delete pUndo;
4438cdf0e10cSrcweir             else
4439cdf0e10cSrcweir             {
4440cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo(pUndo);
4441cdf0e10cSrcweir             }
4442cdf0e10cSrcweir         }
4443cdf0e10cSrcweir 
4444cdf0e10cSrcweir 		if( bCorrPos )
4445cdf0e10cSrcweir 		{
4446cdf0e10cSrcweir 			rInsPos.nNode = *pSttNd;
4447cdf0e10cSrcweir 			rInsPos.nContent.Assign( GetNodes().GoNext( &rInsPos.nNode ), 0 );
4448cdf0e10cSrcweir 		}
4449cdf0e10cSrcweir         SetRedlineMode( eOld );
4450cdf0e10cSrcweir 	}
4451cdf0e10cSrcweir 
4452cdf0e10cSrcweir 	if( bRet )
4453cdf0e10cSrcweir 	{
4454cdf0e10cSrcweir 		SetModified();
4455cdf0e10cSrcweir 		SetFieldsDirty( true, NULL, 0 );
4456cdf0e10cSrcweir 	}
4457cdf0e10cSrcweir 	return bRet;
4458cdf0e10cSrcweir }
4459cdf0e10cSrcweir 
4460cdf0e10cSrcweir 
4461cdf0e10cSrcweir 
_UnProtectTblCells(SwTable & rTbl)4462cdf0e10cSrcweir sal_Bool SwDoc::_UnProtectTblCells( SwTable& rTbl )
4463cdf0e10cSrcweir {
4464cdf0e10cSrcweir 	sal_Bool bChgd = sal_False;
4465cdf0e10cSrcweir     SwUndoAttrTbl *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
4466cdf0e10cSrcweir         ?   new SwUndoAttrTbl( *rTbl.GetTableNode() )
4467cdf0e10cSrcweir         :   0;
4468cdf0e10cSrcweir 
4469cdf0e10cSrcweir 	SwTableSortBoxes& rSrtBox = rTbl.GetTabSortBoxes();
4470cdf0e10cSrcweir 	for( sal_uInt16 i = rSrtBox.Count(); i; )
4471cdf0e10cSrcweir 	{
4472cdf0e10cSrcweir 		SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
4473cdf0e10cSrcweir 		if( pBoxFmt->GetProtect().IsCntntProtected() )
4474cdf0e10cSrcweir 		{
4475cdf0e10cSrcweir             pBoxFmt->ResetFmtAttr( RES_PROTECT );
4476cdf0e10cSrcweir 			bChgd = sal_True;
4477cdf0e10cSrcweir 		}
4478cdf0e10cSrcweir 	}
4479cdf0e10cSrcweir 
4480cdf0e10cSrcweir 	if( pUndo )
4481cdf0e10cSrcweir 	{
4482cdf0e10cSrcweir 		if( bChgd )
4483cdf0e10cSrcweir         {
4484cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pUndo );
4485cdf0e10cSrcweir         }
4486cdf0e10cSrcweir         else
4487cdf0e10cSrcweir 			delete pUndo;
4488cdf0e10cSrcweir 	}
4489cdf0e10cSrcweir 	return bChgd;
4490cdf0e10cSrcweir }
4491cdf0e10cSrcweir 
4492cdf0e10cSrcweir 
UnProtectCells(const String & rName)4493cdf0e10cSrcweir sal_Bool SwDoc::UnProtectCells( const String& rName )
4494cdf0e10cSrcweir {
4495cdf0e10cSrcweir 	sal_Bool bChgd = sal_False;
4496cdf0e10cSrcweir 	SwTableFmt* pFmt = FindTblFmtByName( rName );
4497cdf0e10cSrcweir 	if( pFmt )
4498cdf0e10cSrcweir 	{
4499cdf0e10cSrcweir 		bChgd = _UnProtectTblCells( *SwTable::FindTable( pFmt ) );
4500cdf0e10cSrcweir 		if( bChgd )
4501cdf0e10cSrcweir 			SetModified();
4502cdf0e10cSrcweir 	}
4503cdf0e10cSrcweir 
4504cdf0e10cSrcweir 	return bChgd;
4505cdf0e10cSrcweir }
4506cdf0e10cSrcweir 
UnProtectCells(const SwSelBoxes & rBoxes)4507cdf0e10cSrcweir sal_Bool SwDoc::UnProtectCells( const SwSelBoxes& rBoxes )
4508cdf0e10cSrcweir {
4509cdf0e10cSrcweir 	sal_Bool bChgd = sal_False;
4510cdf0e10cSrcweir 	if( rBoxes.Count() )
4511cdf0e10cSrcweir     {
4512cdf0e10cSrcweir         SwUndoAttrTbl *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
4513cdf0e10cSrcweir 				? new SwUndoAttrTbl( *rBoxes[0]->GetSttNd()->FindTableNode() )
4514cdf0e10cSrcweir 				: 0;
4515cdf0e10cSrcweir 
4516cdf0e10cSrcweir 		SvPtrarr aFmts( 16 ), aNewFmts( 16 );
4517cdf0e10cSrcweir 		for( sal_uInt16 i = rBoxes.Count(); i; )
4518cdf0e10cSrcweir 		{
4519cdf0e10cSrcweir 			SwTableBox* pBox = rBoxes[ --i ];
4520cdf0e10cSrcweir 			SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
4521cdf0e10cSrcweir 			if( pBoxFmt->GetProtect().IsCntntProtected() )
4522cdf0e10cSrcweir 			{
4523cdf0e10cSrcweir 				sal_uInt16 nFnd = aFmts.GetPos( pBoxFmt );
4524cdf0e10cSrcweir 				if( USHRT_MAX != nFnd )
4525cdf0e10cSrcweir 					pBox->ChgFrmFmt( (SwTableBoxFmt*)aNewFmts[ nFnd ] );
4526cdf0e10cSrcweir 				else
4527cdf0e10cSrcweir 				{
4528cdf0e10cSrcweir 					aFmts.Insert( pBoxFmt, aFmts.Count() );
4529cdf0e10cSrcweir 					pBoxFmt = pBox->ClaimFrmFmt();
4530cdf0e10cSrcweir                     pBoxFmt->ResetFmtAttr( RES_PROTECT );
4531cdf0e10cSrcweir 					aNewFmts.Insert( pBoxFmt, aNewFmts.Count() );
4532cdf0e10cSrcweir 				}
4533cdf0e10cSrcweir 				bChgd = sal_True;
4534cdf0e10cSrcweir 			}
4535cdf0e10cSrcweir 		}
4536cdf0e10cSrcweir 
4537cdf0e10cSrcweir 		if( pUndo )
4538cdf0e10cSrcweir 		{
4539cdf0e10cSrcweir 			if( bChgd )
4540cdf0e10cSrcweir             {
4541cdf0e10cSrcweir                 GetIDocumentUndoRedo().AppendUndo( pUndo );
4542cdf0e10cSrcweir             }
4543cdf0e10cSrcweir             else
4544cdf0e10cSrcweir 				delete pUndo;
4545cdf0e10cSrcweir 		}
4546cdf0e10cSrcweir 	}
4547cdf0e10cSrcweir 	return bChgd;
4548cdf0e10cSrcweir }
4549cdf0e10cSrcweir 
UnProtectTbls(const SwPaM & rPam)4550cdf0e10cSrcweir sal_Bool SwDoc::UnProtectTbls( const SwPaM& rPam )
4551cdf0e10cSrcweir {
4552cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
4553cdf0e10cSrcweir 
4554cdf0e10cSrcweir 	sal_Bool bChgd = sal_False, bHasSel = rPam.HasMark() ||
4555cdf0e10cSrcweir 									rPam.GetNext() != (SwPaM*)&rPam;
4556cdf0e10cSrcweir 	SwFrmFmts& rFmts = *GetTblFrmFmts();
4557cdf0e10cSrcweir 	SwTable* pTbl;
4558cdf0e10cSrcweir 	const SwTableNode* pTblNd;
4559cdf0e10cSrcweir 	for( sal_uInt16 n = rFmts.Count(); n ; )
4560cdf0e10cSrcweir 		if( 0 != (pTbl = SwTable::FindTable( rFmts[ --n ] )) &&
4561cdf0e10cSrcweir 			0 != (pTblNd = pTbl->GetTableNode() ) &&
4562cdf0e10cSrcweir 			pTblNd->GetNodes().IsDocNodes() )
4563cdf0e10cSrcweir 		{
4564cdf0e10cSrcweir 			sal_uLong nTblIdx = pTblNd->GetIndex();
4565cdf0e10cSrcweir 
4566cdf0e10cSrcweir 			// dann ueberpruefe ob Tabelle in der Selection liegt
4567cdf0e10cSrcweir 			if( bHasSel )
4568cdf0e10cSrcweir 			{
4569cdf0e10cSrcweir 				int bFound = sal_False;
4570cdf0e10cSrcweir 				SwPaM* pTmp = (SwPaM*)&rPam;
4571cdf0e10cSrcweir 				do {
4572cdf0e10cSrcweir 					const SwPosition *pStt = pTmp->Start(),
4573cdf0e10cSrcweir 									*pEnd = pTmp->End();
4574cdf0e10cSrcweir 					bFound = pStt->nNode.GetIndex() < nTblIdx &&
4575cdf0e10cSrcweir 							nTblIdx < pEnd->nNode.GetIndex();
4576cdf0e10cSrcweir 
4577cdf0e10cSrcweir 				} while( !bFound && &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) );
4578cdf0e10cSrcweir 				if( !bFound )
4579cdf0e10cSrcweir 					continue;		// weitersuchen
4580cdf0e10cSrcweir 			}
4581cdf0e10cSrcweir 
4582cdf0e10cSrcweir 			// dann mal den Schutz aufheben
4583cdf0e10cSrcweir 			bChgd |= _UnProtectTblCells( *pTbl );
4584cdf0e10cSrcweir 		}
4585cdf0e10cSrcweir 
4586cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
4587cdf0e10cSrcweir 	if( bChgd )
4588cdf0e10cSrcweir 		SetModified();
4589cdf0e10cSrcweir 
4590cdf0e10cSrcweir 	return bChgd;
4591cdf0e10cSrcweir }
4592cdf0e10cSrcweir 
HasTblAnyProtection(const SwPosition * pPos,const String * pTblName,sal_Bool * pFullTblProtection)4593cdf0e10cSrcweir sal_Bool SwDoc::HasTblAnyProtection( const SwPosition* pPos,
4594cdf0e10cSrcweir 								 const String* pTblName,
4595cdf0e10cSrcweir 								 sal_Bool* pFullTblProtection )
4596cdf0e10cSrcweir {
4597cdf0e10cSrcweir 	sal_Bool bHasProtection = sal_False;
4598cdf0e10cSrcweir 	SwTable* pTbl = 0;
4599cdf0e10cSrcweir 	if( pTblName )
4600cdf0e10cSrcweir 		pTbl = SwTable::FindTable( FindTblFmtByName( *pTblName ) );
4601cdf0e10cSrcweir 	else if( pPos )
4602cdf0e10cSrcweir 	{
4603cdf0e10cSrcweir 		SwTableNode* pTblNd = pPos->nNode.GetNode().FindTableNode();
4604cdf0e10cSrcweir 		if( pTblNd )
4605cdf0e10cSrcweir 			pTbl = &pTblNd->GetTable();
4606cdf0e10cSrcweir 	}
4607cdf0e10cSrcweir 
4608cdf0e10cSrcweir 	if( pTbl )
4609cdf0e10cSrcweir 	{
4610cdf0e10cSrcweir 		SwTableSortBoxes& rSrtBox = pTbl->GetTabSortBoxes();
4611cdf0e10cSrcweir 		for( sal_uInt16 i = rSrtBox.Count(); i; )
4612cdf0e10cSrcweir 		{
4613cdf0e10cSrcweir 			SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
4614cdf0e10cSrcweir 			if( pBoxFmt->GetProtect().IsCntntProtected() )
4615cdf0e10cSrcweir 			{
4616cdf0e10cSrcweir 				if( !bHasProtection )
4617cdf0e10cSrcweir 				{
4618cdf0e10cSrcweir 					bHasProtection = sal_True;
4619cdf0e10cSrcweir 					if( !pFullTblProtection )
4620cdf0e10cSrcweir 						break;
4621cdf0e10cSrcweir 					*pFullTblProtection = sal_True;
4622cdf0e10cSrcweir 				}
4623cdf0e10cSrcweir 			}
4624cdf0e10cSrcweir 			else if( bHasProtection && pFullTblProtection )
4625cdf0e10cSrcweir 			{
4626cdf0e10cSrcweir 				*pFullTblProtection = sal_False;
4627cdf0e10cSrcweir 				break;
4628cdf0e10cSrcweir 			}
4629cdf0e10cSrcweir 		}
4630cdf0e10cSrcweir 	}
4631cdf0e10cSrcweir 	return bHasProtection;
4632cdf0e10cSrcweir }
4633cdf0e10cSrcweir 
4634cdf0e10cSrcweir #ifdef DEL_TABLE_REDLINES
lcl_DelRedlines(const SwTableNode & rNd,sal_Bool bCheckForOwnRedline)4635cdf0e10cSrcweir lcl_DelRedlines::lcl_DelRedlines( const SwTableNode& rNd,
4636cdf0e10cSrcweir 									sal_Bool bCheckForOwnRedline )
4637cdf0e10cSrcweir 	: pDoc( (SwDoc*)rNd.GetNodes().GetDoc() )
4638cdf0e10cSrcweir {
4639cdf0e10cSrcweir     pDoc->StartUndo(UNDO_EMPTY, NULL);
4640cdf0e10cSrcweir 	const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
4641cdf0e10cSrcweir 	if( !pDoc->IsIgnoreRedline() && rTbl.Count() )
4642cdf0e10cSrcweir 	{
4643cdf0e10cSrcweir 		sal_Bool bDelete = sal_True;
4644cdf0e10cSrcweir 		if( bCheckForOwnRedline )
4645cdf0e10cSrcweir 		{
4646cdf0e10cSrcweir 			sal_uInt16 nRedlPos = pDoc->GetRedlinePos( rNd, USHRT_MAX );
4647cdf0e10cSrcweir 			sal_uInt32 nSttNd = rNd.GetIndex(),
4648cdf0e10cSrcweir 					   nEndNd = rNd.EndOfSectionIndex();
4649cdf0e10cSrcweir 
4650cdf0e10cSrcweir 			for ( ; nRedlPos < rTbl.Count(); ++nRedlPos )
4651cdf0e10cSrcweir 			{
4652cdf0e10cSrcweir 				const SwRedline* pRedline = rTbl[ nRedlPos ];
4653cdf0e10cSrcweir 				const SwPosition* pStt = pRedline->Start(),
4654cdf0e10cSrcweir 						  		* pEnd = pStt == pRedline->GetPoint()
4655cdf0e10cSrcweir 						  							? pRedline->GetMark()
4656cdf0e10cSrcweir 													: pRedline->GetPoint();
4657cdf0e10cSrcweir 				if( pStt->nNode <= nSttNd )
4658cdf0e10cSrcweir 				{
4659cdf0e10cSrcweir 					if( pEnd->nNode >= nEndNd &&
4660cdf0e10cSrcweir 						pRedline->GetAuthor() == pDoc->GetRedlineAuthor() )
4661cdf0e10cSrcweir 					{
4662cdf0e10cSrcweir 						bDelete = sal_False;
4663cdf0e10cSrcweir 						break;
4664cdf0e10cSrcweir 					}
4665cdf0e10cSrcweir 				}
4666cdf0e10cSrcweir 				else
4667cdf0e10cSrcweir 					break;
4668cdf0e10cSrcweir 			}
4669cdf0e10cSrcweir 		}
4670cdf0e10cSrcweir 		if( bDelete )
4671cdf0e10cSrcweir 		{
4672cdf0e10cSrcweir 			SwPaM aPam(*rNd.EndOfSectionNode(), rNd);
4673cdf0e10cSrcweir 			pDoc->AcceptRedline( aPam, true );
4674cdf0e10cSrcweir 		}
4675cdf0e10cSrcweir 	}
4676cdf0e10cSrcweir }
4677cdf0e10cSrcweir #endif
4678cdf0e10cSrcweir 
4679cdf0e10cSrcweir 
4680