xref: /aoo41x/main/sw/source/core/crsr/trvltbl.cxx (revision efeef26f)
1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
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.
19*efeef26fSAndrew Rist  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir #include <hintids.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <vcl/svapp.hxx>
29cdf0e10cSrcweir #include <editeng/protitem.hxx>
30cdf0e10cSrcweir #include <crsrsh.hxx>
31cdf0e10cSrcweir #include <doc.hxx>
32cdf0e10cSrcweir #include <cntfrm.hxx>
33cdf0e10cSrcweir #include <editsh.hxx>		//EndAllAction gibts nur an der EditShell
34cdf0e10cSrcweir #include <pam.hxx>
35cdf0e10cSrcweir #include <swtable.hxx>
36cdf0e10cSrcweir #include <docary.hxx>
37cdf0e10cSrcweir #include <frmatr.hxx>
38cdf0e10cSrcweir #include <frmfmt.hxx>
39cdf0e10cSrcweir #include <viscrs.hxx>
40cdf0e10cSrcweir #include <callnk.hxx>
41cdf0e10cSrcweir #include <tabfrm.hxx>
42cdf0e10cSrcweir #include <ndtxt.hxx>
43cdf0e10cSrcweir #include <shellres.hxx>
44cdf0e10cSrcweir #include <cellatr.hxx>
45cdf0e10cSrcweir #include <cellfrm.hxx>
46cdf0e10cSrcweir #include <rowfrm.hxx>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
49cdf0e10cSrcweir // setze Crsr in die naechsten/vorherigen Celle
GoNextCell(sal_Bool bAppendLine)50cdf0e10cSrcweir sal_Bool SwCrsrShell::GoNextCell( sal_Bool bAppendLine )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
53cdf0e10cSrcweir     const SwTableNode* pTblNd = 0;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 	if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() ))
56cdf0e10cSrcweir 	{
57cdf0e10cSrcweir 		SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
58cdf0e10cSrcweir 		SwCallLink aLk( *this );		// Crsr-Moves ueberwachen,
59cdf0e10cSrcweir 		bRet = sal_True;
60cdf0e10cSrcweir 
61cdf0e10cSrcweir         // Check if we have to move the cursor to a covered cell before
62cdf0e10cSrcweir         // proceeding:
63cdf0e10cSrcweir         const SwNode* pTableBoxStartNode = pCrsr->GetNode()->FindTableBoxStartNode();
64cdf0e10cSrcweir         const SwTableBox* pTableBox = 0;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir         if ( pCrsr->GetCrsrRowSpanOffset() )
67cdf0e10cSrcweir         {
68cdf0e10cSrcweir             pTableBox = pTableBoxStartNode->GetTblBox();
69cdf0e10cSrcweir             if ( pTableBox->getRowSpan() > 1 )
70cdf0e10cSrcweir             {
71cdf0e10cSrcweir                 if ( !pTblNd )
72cdf0e10cSrcweir                     pTblNd = IsCrsrInTbl();
73cdf0e10cSrcweir                 pTableBox = & pTableBox->FindEndOfRowSpan( pTblNd->GetTable(),
74cdf0e10cSrcweir                                                            (sal_uInt16)(pTableBox->getRowSpan() + pCrsr->GetCrsrRowSpanOffset() ) );
75cdf0e10cSrcweir                 pTableBoxStartNode = pTableBox->GetSttNd();
76cdf0e10cSrcweir             }
77cdf0e10cSrcweir         }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir         SwNodeIndex  aCellStt( *pTableBoxStartNode->EndOfSectionNode(), 1 );
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         // folgt nach dem EndNode der Cell ein weiterer StartNode, dann
82cdf0e10cSrcweir 		// gibt es auch eine naechste Celle
83cdf0e10cSrcweir 
84cdf0e10cSrcweir         if( !aCellStt.GetNode().IsStartNode() )
85cdf0e10cSrcweir 		{
86cdf0e10cSrcweir 			if( pCrsr->HasMark() ||	!bAppendLine )
87cdf0e10cSrcweir 				bRet = sal_False;
88cdf0e10cSrcweir 			else
89cdf0e10cSrcweir 			{
90cdf0e10cSrcweir 				// auf besonderen Wunsch: keine Line mehr vorhanden, dann
91cdf0e10cSrcweir 				// mache doch eine neue:
92cdf0e10cSrcweir                 if ( !pTableBox )
93cdf0e10cSrcweir                     pTableBox = pTblNd->GetTable().GetTblBox(
94cdf0e10cSrcweir 								    pCrsr->GetPoint()->nNode.GetNode().
95cdf0e10cSrcweir 								    StartOfSectionIndex() );
96cdf0e10cSrcweir 
97cdf0e10cSrcweir                 ASSERT( pTableBox, "Box steht nicht in dieser Tabelle" );
98cdf0e10cSrcweir 				SwSelBoxes aBoxes;
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 				//Das Dokument veraendert sich evtl. ohne Action wuerden die Sichten
101cdf0e10cSrcweir 				//nichts mitbekommen.
102cdf0e10cSrcweir 				((SwEditShell*)this)->StartAllAction();
103cdf0e10cSrcweir 				bRet = pDoc->InsertRow( pTblNd->GetTable().
104cdf0e10cSrcweir 									SelLineFromBox( pTableBox, aBoxes, sal_False ));
105cdf0e10cSrcweir 				((SwEditShell*)this)->EndAllAction();
106cdf0e10cSrcweir 			}
107cdf0e10cSrcweir 		}
108cdf0e10cSrcweir 		if( bRet && 0 != ( bRet = pCrsr->GoNextCell() ))
109cdf0e10cSrcweir 			UpdateCrsr();				  // und den akt. Updaten
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir 	return bRet;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 
GoPrevCell()115cdf0e10cSrcweir sal_Bool SwCrsrShell::GoPrevCell()
116cdf0e10cSrcweir {
117cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
118cdf0e10cSrcweir 	const SwTableNode* pTblNd;
119cdf0e10cSrcweir 	if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() ))
120cdf0e10cSrcweir 	{
121cdf0e10cSrcweir 		SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
122cdf0e10cSrcweir 		SwCallLink aLk( *this );		// Crsr-Moves ueberwachen,
123cdf0e10cSrcweir 		bRet = pCrsr->GoPrevCell();
124cdf0e10cSrcweir 		if( bRet )
125cdf0e10cSrcweir 			UpdateCrsr();				  // und den akt. Updaten
126cdf0e10cSrcweir 	}
127cdf0e10cSrcweir 	return bRet;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
lcl_FindMostUpperCellFrm(const SwFrm * pFrm)130cdf0e10cSrcweir const SwFrm* lcl_FindMostUpperCellFrm( const SwFrm* pFrm )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     while ( pFrm &&
133cdf0e10cSrcweir             ( !pFrm->IsCellFrm() ||
134cdf0e10cSrcweir               !pFrm->GetUpper()->GetUpper()->IsTabFrm() ||
135cdf0e10cSrcweir                pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
136cdf0e10cSrcweir     {
137cdf0e10cSrcweir         pFrm = pFrm->GetUpper();
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir     return pFrm;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
_SelTblRowOrCol(bool bRow,bool bRowSimple)142cdf0e10cSrcweir sal_Bool SwCrsrShell::_SelTblRowOrCol( bool bRow, bool bRowSimple )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir 	// pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
145cdf0e10cSrcweir 	SwFrm *pFrm = GetCurrFrm();
146cdf0e10cSrcweir 	if( !pFrm->IsInTab() )
147cdf0e10cSrcweir 		return sal_False;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir     const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
150cdf0e10cSrcweir     const SwTabFrm* pMasterTabFrm = pTabFrm->IsFollow() ? pTabFrm->FindMaster( true ) : pTabFrm;
151cdf0e10cSrcweir     const SwTable* pTable = pTabFrm->GetTable();
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 	SET_CURR_SHELL( this );
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     const SwTableBox* pStt = 0;
156cdf0e10cSrcweir     const SwTableBox* pEnd = 0;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     // lasse ueber das Layout die Boxen suchen
159cdf0e10cSrcweir     SwSelBoxes aBoxes;
160cdf0e10cSrcweir     SwTblSearchType eType = bRow ? nsSwTblSearchType::TBLSEARCH_ROW : nsSwTblSearchType::TBLSEARCH_COL;
161cdf0e10cSrcweir     const bool bCheckProtected = !IsReadOnlyAvailable();
162cdf0e10cSrcweir 
163cdf0e10cSrcweir     if( bCheckProtected )
164cdf0e10cSrcweir         eType = (SwTblSearchType)(eType | nsSwTblSearchType::TBLSEARCH_PROTECT);
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     if ( !bRowSimple )
167cdf0e10cSrcweir     {
168cdf0e10cSrcweir         GetTblSel( *this, aBoxes, eType );
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         if( !aBoxes.Count() )
171cdf0e10cSrcweir             return sal_False;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir         pStt = aBoxes[0];
174cdf0e10cSrcweir         pEnd = aBoxes[aBoxes.Count() - 1];
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     // --> FME 2004-07-30 #i32329# Enhanced table selection
177cdf0e10cSrcweir     else if ( pTable->IsNewModel() )
178cdf0e10cSrcweir     {
179cdf0e10cSrcweir     	const SwShellCrsr *pCrsr = _GetCrsr();
180cdf0e10cSrcweir         SwTable::SearchType eSearchType = bRow ? SwTable::SEARCH_ROW : SwTable::SEARCH_COL;
181cdf0e10cSrcweir         pTable->CreateSelection( *pCrsr, aBoxes, eSearchType, bCheckProtected );
182cdf0e10cSrcweir         if( !aBoxes.Count() )
183cdf0e10cSrcweir             return sal_False;
184cdf0e10cSrcweir 
185cdf0e10cSrcweir         pStt = aBoxes[0];
186cdf0e10cSrcweir         pEnd = aBoxes[aBoxes.Count() - 1];
187cdf0e10cSrcweir     }
188cdf0e10cSrcweir     else
189cdf0e10cSrcweir     {
190cdf0e10cSrcweir     	const SwShellCrsr *pCrsr = _GetCrsr();
191cdf0e10cSrcweir 		const SwFrm* pStartFrm = pFrm;
192cdf0e10cSrcweir         const SwCntntNode *pCNd = pCrsr->GetCntntNode( sal_False );
193cdf0e10cSrcweir         const SwFrm* pEndFrm   = pCNd ? pCNd->getLayoutFrm( GetLayout(), &pCrsr->GetMkPos() ) : 0;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         if ( bRow )
196cdf0e10cSrcweir         {
197cdf0e10cSrcweir             pStartFrm = lcl_FindMostUpperCellFrm( pStartFrm );
198cdf0e10cSrcweir             pEndFrm   = lcl_FindMostUpperCellFrm( pEndFrm   );
199cdf0e10cSrcweir         }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir         if ( !pStartFrm || !pEndFrm )
202cdf0e10cSrcweir             return sal_False;
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         const bool bVert = pFrm->ImplFindTabFrm()->IsVertical();
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         // If we select upwards it is sufficient to set pStt and pEnd
207cdf0e10cSrcweir         // to the first resp. last box of the selection obtained from
208cdf0e10cSrcweir         // GetTblSel. However, selecting downwards requires the frames
209cdf0e10cSrcweir         // located at the corners of the selection. This does not work
210cdf0e10cSrcweir         // for column selections in vertical tables:
211cdf0e10cSrcweir         const bool bSelectUp = ( bVert && !bRow ) ||
212cdf0e10cSrcweir                                 *pCrsr->GetPoint() <= *pCrsr->GetMark();
213cdf0e10cSrcweir         SwCellFrms aCells;
214cdf0e10cSrcweir         GetTblSel( static_cast<const SwCellFrm*>(pStartFrm),
215cdf0e10cSrcweir                    static_cast<const SwCellFrm*>(pEndFrm),
216cdf0e10cSrcweir                    aBoxes, bSelectUp ? 0 : &aCells, eType );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir         if( !aBoxes.Count() || ( !bSelectUp && 4 != aCells.Count() ) )
219cdf0e10cSrcweir             return sal_False;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir         if ( bSelectUp )
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir             pStt = aBoxes[0];
224cdf0e10cSrcweir             pEnd = aBoxes[aBoxes.Count() - 1];
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir         else
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             pStt = aCells[ bVert ? (bRow ? 0 : 3) : (bRow ? 2 : 1) ]->GetTabBox();  // will become point of table cursor
229cdf0e10cSrcweir             pEnd = aCells[ bVert ? (bRow ? 3 : 0) : (bRow ? 1 : 2) ]->GetTabBox();  // will become mark of table cursor
230cdf0e10cSrcweir         }
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir     // <--
233cdf0e10cSrcweir 
234cdf0e10cSrcweir     // noch kein Tabellen-Cursor vorhanden, dann erzeuge einen
235cdf0e10cSrcweir 	if( !pTblCrsr )
236cdf0e10cSrcweir 	{
237cdf0e10cSrcweir 		pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
238cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
239cdf0e10cSrcweir 		pCurCrsr->SwSelPaintRects::Hide();
240cdf0e10cSrcweir 	}
241cdf0e10cSrcweir 
242cdf0e10cSrcweir     pTblCrsr->DeleteMark();
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     // dann setze mal Anfang und Ende der Spalte
245cdf0e10cSrcweir     pTblCrsr->GetPoint()->nNode = *pEnd->GetSttNd();
246cdf0e10cSrcweir     pTblCrsr->Move( fnMoveForward, fnGoCntnt );
247cdf0e10cSrcweir 	pTblCrsr->SetMark();
248cdf0e10cSrcweir     pTblCrsr->GetPoint()->nNode = *pStt->GetSttNd()->EndOfSectionNode();
249cdf0e10cSrcweir     pTblCrsr->Move( fnMoveBackward, fnGoCntnt );
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     // set PtPos 'close' to the reference table, otherwise we might get problems with the
252cdf0e10cSrcweir     // repeated headlines check in UpdateCrsr():
253cdf0e10cSrcweir     if ( !bRow )
254cdf0e10cSrcweir         pTblCrsr->GetPtPos() = pMasterTabFrm->IsVertical() ? pMasterTabFrm->Frm().TopRight() : pMasterTabFrm->Frm().TopLeft();
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 	UpdateCrsr();				  // und den akt. Updaten
257cdf0e10cSrcweir 	return sal_True;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
SelTbl()260cdf0e10cSrcweir sal_Bool SwCrsrShell::SelTbl()
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
263cdf0e10cSrcweir     SwFrm *pFrm = GetCurrFrm();
264cdf0e10cSrcweir     if( !pFrm->IsInTab() )
265cdf0e10cSrcweir         return sal_False;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     const SwTabFrm *pTblFrm = pFrm->ImplFindTabFrm();
268cdf0e10cSrcweir     const SwTabFrm* pMasterTabFrm = pTblFrm->IsFollow() ? pTblFrm->FindMaster( true ) : pTblFrm;
269cdf0e10cSrcweir     const SwTableNode* pTblNd = pTblFrm->GetTable()->GetTableNode();
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     SET_CURR_SHELL( this );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     if( !pTblCrsr )
274cdf0e10cSrcweir     {
275cdf0e10cSrcweir         pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
276cdf0e10cSrcweir         pCurCrsr->DeleteMark();
277cdf0e10cSrcweir         pCurCrsr->SwSelPaintRects::Hide();
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     pTblCrsr->DeleteMark();
281cdf0e10cSrcweir     pTblCrsr->GetPoint()->nNode = *pTblNd;
282cdf0e10cSrcweir     pTblCrsr->Move( fnMoveForward, fnGoCntnt );
283cdf0e10cSrcweir     pTblCrsr->SetMark();
284cdf0e10cSrcweir     // set MkPos 'close' to the master table, otherwise we might get problems with the
285cdf0e10cSrcweir     // repeated headlines check in UpdateCrsr():
286cdf0e10cSrcweir     pTblCrsr->GetMkPos() = pMasterTabFrm->IsVertical() ? pMasterTabFrm->Frm().TopRight() : pMasterTabFrm->Frm().TopLeft();
287cdf0e10cSrcweir     pTblCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
288cdf0e10cSrcweir     pTblCrsr->Move( fnMoveBackward, fnGoCntnt );
289cdf0e10cSrcweir     UpdateCrsr();                 // und den akt. Updaten
290cdf0e10cSrcweir     return sal_True;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 
SelTblBox()294cdf0e10cSrcweir sal_Bool SwCrsrShell::SelTblBox()
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     // if we're in a table, create a table cursor, and select the cell
297cdf0e10cSrcweir     // that the current cursor's point resides in
298cdf0e10cSrcweir 
299cdf0e10cSrcweir     // search for start node of our table box. If not found, exit realy
300cdf0e10cSrcweir     const SwStartNode* pStartNode =
301cdf0e10cSrcweir         pCurCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
302cdf0e10cSrcweir 
303cdf0e10cSrcweir #ifdef DBG_UTIL
304cdf0e10cSrcweir     // the old code checks whether we're in a table by asking the
305cdf0e10cSrcweir     // frame. This should yield the same result as searching for the
306cdf0e10cSrcweir     // table box start node, right?
307cdf0e10cSrcweir 	SwFrm *pFrm = GetCurrFrm();
308cdf0e10cSrcweir 	DBG_ASSERT( !pFrm->IsInTab() == !(pStartNode != NULL),
309cdf0e10cSrcweir                 "Schroedinger's table: We're in a box, and also we aren't." );
310cdf0e10cSrcweir #endif
311cdf0e10cSrcweir 
312cdf0e10cSrcweir     if( pStartNode == NULL )
313cdf0e10cSrcweir         return sal_False;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 	SET_CURR_SHELL( this );
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     // create a table cursor, if there isn't one already
319cdf0e10cSrcweir 	if( !pTblCrsr )
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
322cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
323cdf0e10cSrcweir 		pCurCrsr->SwSelPaintRects::Hide();
324cdf0e10cSrcweir 	}
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     // select the complete box with our shiny new pTblCrsr
327cdf0e10cSrcweir     // 1. delete mark, and move point to first content node in box
328cdf0e10cSrcweir     // 2. set mark, and move point to last content node in box
329cdf0e10cSrcweir     // 3. exchange
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	pTblCrsr->DeleteMark();
332cdf0e10cSrcweir     *(pTblCrsr->GetPoint()) = SwPosition( *pStartNode );
333cdf0e10cSrcweir     pTblCrsr->Move( fnMoveForward, fnGoNode );
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     pTblCrsr->SetMark();
336cdf0e10cSrcweir     *(pTblCrsr->GetPoint()) = SwPosition( *(pStartNode->EndOfSectionNode()) );
337cdf0e10cSrcweir     pTblCrsr->Move( fnMoveBackward, fnGoNode );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     pTblCrsr->Exchange();
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     // with some luck, UpdateCrsr() will now update everything that
342cdf0e10cSrcweir     // needs updateing
343cdf0e10cSrcweir 	UpdateCrsr();
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 	return sal_True;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir // return the next non-protected cell inside a table
349cdf0e10cSrcweir //      rIdx    - is on a table node
350cdf0e10cSrcweir //  return:
351cdf0e10cSrcweir //      true  - Idx points to content in a suitable cell
352cdf0e10cSrcweir //      false - could not find a suitable cell
lcl_FindNextCell(SwNodeIndex & rIdx,sal_Bool bInReadOnly)353cdf0e10cSrcweir bool lcl_FindNextCell( SwNodeIndex& rIdx, sal_Bool bInReadOnly )
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     // ueberpruefe geschuetzte Zellen
356cdf0e10cSrcweir     SwNodeIndex aTmp( rIdx, 2 );            // TableNode + StartNode
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     // the resulting cell should be in that table:
359cdf0e10cSrcweir     const SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
360cdf0e10cSrcweir 
361cdf0e10cSrcweir     if ( !pTblNd )
362cdf0e10cSrcweir     {
363cdf0e10cSrcweir         ASSERT( false, "lcl_FindNextCell not celled with table start node!" )
364cdf0e10cSrcweir         return false;
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir     const SwNode* pTableEndNode = pTblNd->EndOfSectionNode();
368cdf0e10cSrcweir 
369cdf0e10cSrcweir     SwNodes& rNds = aTmp.GetNode().GetNodes();
370cdf0e10cSrcweir     SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode();
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     // no content node => go to next content node
373cdf0e10cSrcweir     if( !pCNd )
374cdf0e10cSrcweir         pCNd = rNds.GoNext( &aTmp );
375cdf0e10cSrcweir 
376cdf0e10cSrcweir     // robust
377cdf0e10cSrcweir     if ( !pCNd )
378cdf0e10cSrcweir         return false;
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     SwCntntFrm* pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
381cdf0e10cSrcweir 
382cdf0e10cSrcweir     if ( 0 == pFrm || pCNd->FindTableNode() != pTblNd ||
383cdf0e10cSrcweir         (!bInReadOnly && pFrm->IsProtected() ) )
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         // we are not located inside a 'valid' cell. We have to continue searching...
386cdf0e10cSrcweir 
387cdf0e10cSrcweir         // skip behind current section. This might be the end of the table cell
388cdf0e10cSrcweir         // or behind a inner section or or or...
389cdf0e10cSrcweir         aTmp.Assign( *pCNd->EndOfSectionNode(), 1 );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         // loop to find a suitable cell...
392cdf0e10cSrcweir         for( ;; )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             SwNode* pNd = &aTmp.GetNode();
395cdf0e10cSrcweir 
396cdf0e10cSrcweir             // we break this loop if we reached the end of the table.
397cdf0e10cSrcweir             // to make this code even more robust, we also break if we are
398cdf0e10cSrcweir             // already behind the table end node:
399cdf0e10cSrcweir             if( pNd == pTableEndNode || /*robust: */ pNd->GetIndex() > pTableEndNode->GetIndex() )
400cdf0e10cSrcweir                 return false;
401cdf0e10cSrcweir 
402cdf0e10cSrcweir             // ok, get the next content node:
403cdf0e10cSrcweir             pCNd = aTmp.GetNode().GetCntntNode();
404cdf0e10cSrcweir             if( 0 == pCNd )
405cdf0e10cSrcweir                 pCNd = rNds.GoNext( &aTmp );
406cdf0e10cSrcweir 
407cdf0e10cSrcweir             // robust:
408cdf0e10cSrcweir             if ( !pCNd )
409cdf0e10cSrcweir                 return false;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir             // check if we have found a suitable table cell:
412cdf0e10cSrcweir             pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
413cdf0e10cSrcweir 
414cdf0e10cSrcweir             if ( 0 != pFrm && pCNd->FindTableNode() == pTblNd &&
415cdf0e10cSrcweir                 (bInReadOnly || !pFrm->IsProtected() ) )
416cdf0e10cSrcweir             {
417cdf0e10cSrcweir                 // finally, we have found a suitable table cell => set index and return
418cdf0e10cSrcweir                 rIdx = *pCNd;
419cdf0e10cSrcweir                 return true;
420cdf0e10cSrcweir             }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir             // continue behind the current section:
423cdf0e10cSrcweir             aTmp.Assign( *pCNd->EndOfSectionNode(), +1 );
424cdf0e10cSrcweir         }
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir     rIdx = *pCNd;
428cdf0e10cSrcweir     return true;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir // comments see lcl_FindNextCell
lcl_FindPrevCell(SwNodeIndex & rIdx,sal_Bool bInReadOnly)432cdf0e10cSrcweir bool lcl_FindPrevCell( SwNodeIndex& rIdx, sal_Bool bInReadOnly  )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir     SwNodeIndex aTmp( rIdx, -2 );       // TableNode + EndNode
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     const SwNode* pTableEndNode = &rIdx.GetNode();
437cdf0e10cSrcweir     const SwTableNode* pTblNd = pTableEndNode->StartOfSectionNode()->GetTableNode();
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     if ( !pTblNd )
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         ASSERT( false, "lcl_FindPrevCell not celled with table start node!" )
442cdf0e10cSrcweir         return false;
443cdf0e10cSrcweir     }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     SwNodes& rNds = aTmp.GetNode().GetNodes();
446cdf0e10cSrcweir 	SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode();
447cdf0e10cSrcweir 
448cdf0e10cSrcweir     if( !pCNd )
449cdf0e10cSrcweir         pCNd = rNds.GoPrevious( &aTmp );
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     if ( !pCNd )
452cdf0e10cSrcweir         return false;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir     SwCntntFrm* pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     if( 0 == pFrm || pCNd->FindTableNode() != pTblNd ||
457cdf0e10cSrcweir 		(!bInReadOnly && pFrm->IsProtected() ))
458cdf0e10cSrcweir 	{
459cdf0e10cSrcweir         // skip before current section
460cdf0e10cSrcweir 		aTmp.Assign( *pCNd->StartOfSectionNode(), -1 );
461cdf0e10cSrcweir         for( ;; )
462cdf0e10cSrcweir 		{
463cdf0e10cSrcweir             SwNode* pNd = &aTmp.GetNode();
464cdf0e10cSrcweir 
465cdf0e10cSrcweir             if( pNd == pTblNd || pNd->GetIndex() < pTblNd->GetIndex() )
466cdf0e10cSrcweir                 return false;
467cdf0e10cSrcweir 
468cdf0e10cSrcweir             pCNd = aTmp.GetNode().GetCntntNode();
469cdf0e10cSrcweir             if( 0 == pCNd )
470cdf0e10cSrcweir 				pCNd = rNds.GoPrevious( &aTmp );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir             if ( !pCNd )
473cdf0e10cSrcweir                 return false;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir             pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
476cdf0e10cSrcweir 
477cdf0e10cSrcweir             if( 0 != pFrm && pCNd->FindTableNode() == pTblNd &&
478cdf0e10cSrcweir                 (bInReadOnly || !pFrm->IsProtected() ) )
479cdf0e10cSrcweir 			{
480cdf0e10cSrcweir                 rIdx = *pCNd;
481cdf0e10cSrcweir                 return true;      // Ok, nicht geschuetzt
482cdf0e10cSrcweir 			}
483cdf0e10cSrcweir 			aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 );
484cdf0e10cSrcweir 		}
485cdf0e10cSrcweir 	}
486cdf0e10cSrcweir 
487cdf0e10cSrcweir     rIdx = *pCNd;
488cdf0e10cSrcweir     return true;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 
GotoPrevTable(SwPaM & rCurCrsr,SwPosTable fnPosTbl,sal_Bool bInReadOnly)492cdf0e10cSrcweir sal_Bool GotoPrevTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
493cdf0e10cSrcweir 						sal_Bool bInReadOnly )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir 	SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 	SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
498cdf0e10cSrcweir 	if( pTblNd )
499cdf0e10cSrcweir     {
500cdf0e10cSrcweir         // #i26532#: If we are inside a table, we may not go backward
501cdf0e10cSrcweir         // to the table start node, because we would miss any tables
502cdf0e10cSrcweir         // inside this table.
503cdf0e10cSrcweir     	SwTableNode* pInnerTblNd = 0;
504cdf0e10cSrcweir         SwNodeIndex aTmpIdx( aIdx );
505cdf0e10cSrcweir         while( aTmpIdx.GetIndex() &&
506cdf0e10cSrcweir                 0 == ( pInnerTblNd = aTmpIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
507cdf0e10cSrcweir 		    aTmpIdx--;
508cdf0e10cSrcweir 
509cdf0e10cSrcweir         if( pInnerTblNd == pTblNd )
510cdf0e10cSrcweir     		aIdx.Assign( *pTblNd, - 1 );
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 	do {
514cdf0e10cSrcweir 		while( aIdx.GetIndex() &&
515cdf0e10cSrcweir             0 == ( pTblNd = aIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
516cdf0e10cSrcweir 			aIdx--;
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 		if( pTblNd )		// gibt einen weiteren TableNode ?
519cdf0e10cSrcweir 		{
520cdf0e10cSrcweir 			if( fnPosTbl == fnMoveForward )			// an Anfang ?
521cdf0e10cSrcweir 			{
522cdf0e10cSrcweir 				aIdx = *aIdx.GetNode().StartOfSectionNode();
523cdf0e10cSrcweir                 if( !lcl_FindNextCell( aIdx, bInReadOnly ))
524cdf0e10cSrcweir 				{
525cdf0e10cSrcweir 					// Tabelle ueberspringen
526cdf0e10cSrcweir 					aIdx.Assign( *pTblNd, -1 );
527cdf0e10cSrcweir 					continue;
528cdf0e10cSrcweir 				}
529cdf0e10cSrcweir 			}
530cdf0e10cSrcweir 			else
531cdf0e10cSrcweir 			{
532cdf0e10cSrcweir 				// ueberpruefe geschuetzte Zellen
533cdf0e10cSrcweir                 if( !lcl_FindNextCell( aIdx, bInReadOnly ))
534cdf0e10cSrcweir 				{
535cdf0e10cSrcweir 					// Tabelle ueberspringen
536cdf0e10cSrcweir 					aIdx.Assign( *pTblNd, -1 );
537cdf0e10cSrcweir 					continue;
538cdf0e10cSrcweir 				}
539cdf0e10cSrcweir 			}
540cdf0e10cSrcweir 
541cdf0e10cSrcweir             SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode();
542cdf0e10cSrcweir             if ( pTxtNode )
543cdf0e10cSrcweir             {
544cdf0e10cSrcweir                 rCurCrsr.GetPoint()->nNode = *pTxtNode;
545cdf0e10cSrcweir                 rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
546cdf0e10cSrcweir                                                       pTxtNode->Len() :
547cdf0e10cSrcweir                                                       0 );
548cdf0e10cSrcweir             }
549cdf0e10cSrcweir 			return sal_True;
550cdf0e10cSrcweir 		}
551cdf0e10cSrcweir 	} while( pTblNd );
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 	return sal_False;
554cdf0e10cSrcweir }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir 
GotoNextTable(SwPaM & rCurCrsr,SwPosTable fnPosTbl,sal_Bool bInReadOnly)557cdf0e10cSrcweir sal_Bool GotoNextTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
558cdf0e10cSrcweir 						sal_Bool bInReadOnly )
559cdf0e10cSrcweir {
560cdf0e10cSrcweir 	SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
561cdf0e10cSrcweir 	SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 	if( pTblNd )
564cdf0e10cSrcweir 		aIdx.Assign( *pTblNd->EndOfSectionNode(), 1 );
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 	sal_uLong nLastNd = rCurCrsr.GetDoc()->GetNodes().Count() - 1;
567cdf0e10cSrcweir 	do {
568cdf0e10cSrcweir 		while( aIdx.GetIndex() < nLastNd &&
569cdf0e10cSrcweir 				0 == ( pTblNd = aIdx.GetNode().GetTableNode()) )
570cdf0e10cSrcweir 			aIdx++;
571cdf0e10cSrcweir 		if( pTblNd )		// gibt einen weiteren TableNode ?
572cdf0e10cSrcweir 		{
573cdf0e10cSrcweir 			if( fnPosTbl == fnMoveForward )			// an Anfang ?
574cdf0e10cSrcweir 			{
575cdf0e10cSrcweir                 if( !lcl_FindNextCell( aIdx, bInReadOnly ))
576cdf0e10cSrcweir 				{
577cdf0e10cSrcweir 					// Tabelle ueberspringen
578cdf0e10cSrcweir 					aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 );
579cdf0e10cSrcweir 					continue;
580cdf0e10cSrcweir 				}
581cdf0e10cSrcweir 			}
582cdf0e10cSrcweir 			else
583cdf0e10cSrcweir 			{
584cdf0e10cSrcweir 				aIdx = *aIdx.GetNode().EndOfSectionNode();
585cdf0e10cSrcweir 				// ueberpruefe geschuetzte Zellen
586cdf0e10cSrcweir                 if( !lcl_FindNextCell( aIdx, bInReadOnly ))
587cdf0e10cSrcweir 				{
588cdf0e10cSrcweir 					// Tabelle ueberspringen
589cdf0e10cSrcweir 					aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 );
590cdf0e10cSrcweir 					continue;
591cdf0e10cSrcweir 				}
592cdf0e10cSrcweir 			}
593cdf0e10cSrcweir 
594cdf0e10cSrcweir             SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode();
595cdf0e10cSrcweir             if ( pTxtNode )
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 rCurCrsr.GetPoint()->nNode = *pTxtNode;
598cdf0e10cSrcweir                 rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
599cdf0e10cSrcweir                                                       pTxtNode->Len() :
600cdf0e10cSrcweir                                                       0 );
601cdf0e10cSrcweir             }
602cdf0e10cSrcweir 			return sal_True;
603cdf0e10cSrcweir 		}
604cdf0e10cSrcweir 	} while( pTblNd );
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 	return sal_False;
607cdf0e10cSrcweir }
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 
GotoCurrTable(SwPaM & rCurCrsr,SwPosTable fnPosTbl,sal_Bool bInReadOnly)610cdf0e10cSrcweir sal_Bool GotoCurrTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
611cdf0e10cSrcweir 						sal_Bool bInReadOnly )
612cdf0e10cSrcweir {
613cdf0e10cSrcweir 	SwTableNode* pTblNd = rCurCrsr.GetPoint()->nNode.GetNode().FindTableNode();
614cdf0e10cSrcweir 	if( !pTblNd )
615cdf0e10cSrcweir 		return sal_False;
616cdf0e10cSrcweir 
617cdf0e10cSrcweir     SwTxtNode* pTxtNode = 0;
618cdf0e10cSrcweir 	if( fnPosTbl == fnMoveBackward )	// ans Ende der Tabelle
619cdf0e10cSrcweir 	{
620cdf0e10cSrcweir 		SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() );
621cdf0e10cSrcweir         if( !lcl_FindPrevCell( aIdx, bInReadOnly ))
622cdf0e10cSrcweir 			return sal_False;
623cdf0e10cSrcweir         pTxtNode = aIdx.GetNode().GetTxtNode();
624cdf0e10cSrcweir 	}
625cdf0e10cSrcweir 	else
626cdf0e10cSrcweir 	{
627cdf0e10cSrcweir 		SwNodeIndex aIdx( *pTblNd );
628cdf0e10cSrcweir         if( !lcl_FindNextCell( aIdx, bInReadOnly ))
629cdf0e10cSrcweir 			return sal_False;
630cdf0e10cSrcweir         pTxtNode = aIdx.GetNode().GetTxtNode();
631cdf0e10cSrcweir 	}
632cdf0e10cSrcweir 
633cdf0e10cSrcweir     if ( pTxtNode )
634cdf0e10cSrcweir     {
635cdf0e10cSrcweir         rCurCrsr.GetPoint()->nNode = *pTxtNode;
636cdf0e10cSrcweir         rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
637cdf0e10cSrcweir                                                         pTxtNode->Len() :
638cdf0e10cSrcweir                                                         0 );
639cdf0e10cSrcweir     }
640cdf0e10cSrcweir 
641cdf0e10cSrcweir     return sal_True;
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir 
MoveTable(SwWhichTable fnWhichTbl,SwPosTable fnPosTbl)645cdf0e10cSrcweir sal_Bool SwCursor::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl )
646cdf0e10cSrcweir {
647cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
648cdf0e10cSrcweir     SwTableCursor* pTblCrsr = dynamic_cast<SwTableCursor*>(this);
649cdf0e10cSrcweir 
650cdf0e10cSrcweir 	if( pTblCrsr || !HasMark() )	// nur wenn kein Mark oder ein TblCrsr
651cdf0e10cSrcweir 	{
652cdf0e10cSrcweir 		SwCrsrSaveState aSaveState( *this );
653cdf0e10cSrcweir 		bRet = (*fnWhichTbl)( *this, fnPosTbl, IsReadOnlyAvailable() ) &&
654cdf0e10cSrcweir                 !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
655cdf0e10cSrcweir                            nsSwCursorSelOverFlags::SELOVER_TOGGLE );
656cdf0e10cSrcweir 	}
657cdf0e10cSrcweir 	return bRet;
658cdf0e10cSrcweir }
659cdf0e10cSrcweir 
MoveTable(SwWhichTable fnWhichTbl,SwPosTable fnPosTbl)660cdf0e10cSrcweir sal_Bool SwCrsrShell::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl )
661cdf0e10cSrcweir {
662cdf0e10cSrcweir 	SwCallLink aLk( *this );		// Crsr-Moves ueberwachen, evt. Link callen
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 	SwShellCrsr* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
665cdf0e10cSrcweir 	sal_Bool bCheckPos, bRet;
666cdf0e10cSrcweir     sal_uLong nPtNd = 0;
667cdf0e10cSrcweir     xub_StrLen nPtCnt = 0;
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 	if( !pTblCrsr && pCurCrsr->HasMark() )		// wenn Mark und kein TblCrsr,
670cdf0e10cSrcweir 	{
671cdf0e10cSrcweir 		// dann auf jedenfall in den Tabellen-Modus schalten
672cdf0e10cSrcweir 		pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
673cdf0e10cSrcweir 		pCurCrsr->DeleteMark();
674cdf0e10cSrcweir 		pCurCrsr->SwSelPaintRects::Hide();
675cdf0e10cSrcweir 		pTblCrsr->SetMark();
676cdf0e10cSrcweir 		pCrsr = pTblCrsr;
677cdf0e10cSrcweir 		bCheckPos = sal_False;
678cdf0e10cSrcweir 	}
679cdf0e10cSrcweir 	else
680cdf0e10cSrcweir 	{
681cdf0e10cSrcweir 		bCheckPos = sal_True;
682cdf0e10cSrcweir 		nPtNd = pCrsr->GetPoint()->nNode.GetIndex();
683cdf0e10cSrcweir 		nPtCnt = pCrsr->GetPoint()->nContent.GetIndex();
684cdf0e10cSrcweir 	}
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 	bRet = pCrsr->MoveTable( fnWhichTbl, fnPosTbl );
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 	if( bRet )
689cdf0e10cSrcweir 	{
690cdf0e10cSrcweir 		//JP 28.10.97: Bug 45028 - die "oberste" Position setzen fuer
691cdf0e10cSrcweir 		//				wiederholte Kopfzeilen
692cdf0e10cSrcweir 		pCrsr->GetPtPos() = Point();
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 		UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
695cdf0e10cSrcweir 
696cdf0e10cSrcweir 		if( bCheckPos &&
697cdf0e10cSrcweir 			pCrsr->GetPoint()->nNode.GetIndex() == nPtNd &&
698cdf0e10cSrcweir 			pCrsr->GetPoint()->nContent.GetIndex() == nPtCnt )
699cdf0e10cSrcweir 			bRet = sal_False;
700cdf0e10cSrcweir 	}
701cdf0e10cSrcweir 	return bRet;
702cdf0e10cSrcweir }
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 
IsTblComplex() const705cdf0e10cSrcweir sal_Bool SwCrsrShell::IsTblComplex() const
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	SwFrm *pFrm = GetCurrFrm( sal_False );
708cdf0e10cSrcweir 	if ( pFrm && pFrm->IsInTab() )
709cdf0e10cSrcweir 		return pFrm->FindTabFrm()->GetTable()->IsTblComplex();
710cdf0e10cSrcweir 	return sal_False;
711cdf0e10cSrcweir }
712cdf0e10cSrcweir 
713cdf0e10cSrcweir 
IsTblComplexForChart()714cdf0e10cSrcweir sal_Bool SwCrsrShell::IsTblComplexForChart()
715cdf0e10cSrcweir {
716cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
717cdf0e10cSrcweir 
718cdf0e10cSrcweir     StartAction();	// IsTblComplexForChart() may trigger table formatting
719cdf0e10cSrcweir                     // we better do that inside an action
720cdf0e10cSrcweir 
721cdf0e10cSrcweir 	const SwTableNode* pTNd = pCurCrsr->GetPoint()->nNode.GetNode().FindTableNode();
722cdf0e10cSrcweir 	if( pTNd )
723cdf0e10cSrcweir 	{
724cdf0e10cSrcweir 		// wir stehen in der Tabelle, dann teste mal, ob die Tabelle oder die
725cdf0e10cSrcweir 		// Selektion ausgeglichen ist.
726cdf0e10cSrcweir 		String sSel;
727cdf0e10cSrcweir 		if( pTblCrsr )
728cdf0e10cSrcweir 			sSel = GetBoxNms();
729cdf0e10cSrcweir 		bRet = pTNd->GetTable().IsTblComplexForChart( sSel );
730cdf0e10cSrcweir 	}
731cdf0e10cSrcweir 
732cdf0e10cSrcweir 	EndAction();
733cdf0e10cSrcweir 
734cdf0e10cSrcweir 	return bRet;
735cdf0e10cSrcweir }
736cdf0e10cSrcweir 
GetBoxNms() const737cdf0e10cSrcweir String SwCrsrShell::GetBoxNms() const
738cdf0e10cSrcweir {
739cdf0e10cSrcweir 	String sNm;
740cdf0e10cSrcweir 	const SwPosition* pPos;
741cdf0e10cSrcweir 	SwFrm* pFrm;
742cdf0e10cSrcweir 
743cdf0e10cSrcweir 	if( IsTableMode() )
744cdf0e10cSrcweir 	{
745cdf0e10cSrcweir         SwCntntNode *pCNd = pTblCrsr->Start()->nNode.GetNode().GetCntntNode();
746cdf0e10cSrcweir 		pFrm = pCNd ? pCNd->getLayoutFrm( GetLayout() ) : 0;
747cdf0e10cSrcweir         if( !pFrm )
748cdf0e10cSrcweir             return sNm;
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 		do {
751cdf0e10cSrcweir 			pFrm = pFrm->GetUpper();
752cdf0e10cSrcweir 		} while ( pFrm && !pFrm->IsCellFrm() );
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 		ASSERT( pFrm, "kein Frame zur Box" );
755cdf0e10cSrcweir 		sNm = ((SwCellFrm*)pFrm)->GetTabBox()->GetName();
756cdf0e10cSrcweir 		sNm += ':';
757cdf0e10cSrcweir 		pPos = pTblCrsr->End();
758cdf0e10cSrcweir 	}
759cdf0e10cSrcweir 	else
760cdf0e10cSrcweir 	{
761cdf0e10cSrcweir 		const SwTableNode* pTblNd = IsCrsrInTbl();
762cdf0e10cSrcweir 		if( !pTblNd )
763cdf0e10cSrcweir 			return sNm;
764cdf0e10cSrcweir 		pPos = GetCrsr()->GetPoint();
765cdf0e10cSrcweir 	}
766cdf0e10cSrcweir 
767cdf0e10cSrcweir     SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode();
768cdf0e10cSrcweir 	pFrm = pCNd ? pCNd->getLayoutFrm( GetLayout() ) : 0;
769cdf0e10cSrcweir 
770cdf0e10cSrcweir     if( pFrm )
771cdf0e10cSrcweir     {
772cdf0e10cSrcweir         do {
773cdf0e10cSrcweir             pFrm = pFrm->GetUpper();
774cdf0e10cSrcweir         } while ( pFrm && !pFrm->IsCellFrm() );
775cdf0e10cSrcweir 
776cdf0e10cSrcweir         if( pFrm )
777cdf0e10cSrcweir             sNm += ((SwCellFrm*)pFrm)->GetTabBox()->GetName();
778cdf0e10cSrcweir     }
779cdf0e10cSrcweir 	return sNm;
780cdf0e10cSrcweir }
781cdf0e10cSrcweir 
782cdf0e10cSrcweir 
GotoTable(const String & rName)783cdf0e10cSrcweir sal_Bool SwCrsrShell::GotoTable( const String& rName )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir 	SwCallLink aLk( *this );		// Crsr-Moves ueberwachen,
786cdf0e10cSrcweir 	sal_Bool bRet = !pTblCrsr && pCurCrsr->GotoTable( rName );
787cdf0e10cSrcweir 	if( bRet )
788cdf0e10cSrcweir 	{
789cdf0e10cSrcweir 		pCurCrsr->GetPtPos() = Point();
790cdf0e10cSrcweir 		UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
791cdf0e10cSrcweir 					SwCrsrShell::READONLY ); // und den akt. Updaten
792cdf0e10cSrcweir 	}
793cdf0e10cSrcweir 	return bRet;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir 
796cdf0e10cSrcweir 
CheckTblBoxCntnt(const SwPosition * pPos)797cdf0e10cSrcweir sal_Bool SwCrsrShell::CheckTblBoxCntnt( const SwPosition* pPos )
798cdf0e10cSrcweir {
799cdf0e10cSrcweir 	if( !pBoxIdx || !pBoxPtr || IsSelTblCells() || !IsAutoUpdateCells() )
800cdf0e10cSrcweir 		return sal_False;
801cdf0e10cSrcweir 
802cdf0e10cSrcweir 	// ueberpruefe, ob der Box Inhalt mit dem angegebenen Format der Box
803cdf0e10cSrcweir 	// ueber einstimmt. Wenn nicht, setze neu
804cdf0e10cSrcweir 	SwTableBox* pChkBox = 0;
805cdf0e10cSrcweir 	SwStartNode* pSttNd = 0;
806cdf0e10cSrcweir 	if( !pPos )
807cdf0e10cSrcweir 	{
808cdf0e10cSrcweir 		// gesicherte Position heraus holen.
809cdf0e10cSrcweir 		if( pBoxIdx && pBoxPtr &&
810cdf0e10cSrcweir 			0 != ( pSttNd = pBoxIdx->GetNode().GetStartNode() ) &&
811cdf0e10cSrcweir 			SwTableBoxStartNode == pSttNd->GetStartNodeType() &&
812cdf0e10cSrcweir 			pBoxPtr == pSttNd->FindTableNode()->GetTable().
813cdf0e10cSrcweir 						GetTblBox( pBoxIdx->GetIndex() ) )
814cdf0e10cSrcweir 			pChkBox = pBoxPtr;
815cdf0e10cSrcweir 	}
816cdf0e10cSrcweir 	else if( 0 != ( pSttNd = pPos->nNode.GetNode().
817cdf0e10cSrcweir 								FindSttNodeByType( SwTableBoxStartNode )) )
818cdf0e10cSrcweir 	{
819cdf0e10cSrcweir 		pChkBox = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() );
820cdf0e10cSrcweir 	}
821cdf0e10cSrcweir 
822cdf0e10cSrcweir 
823cdf0e10cSrcweir 	// Box mehr als 1 Absatz?
824cdf0e10cSrcweir 	if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() )
825cdf0e10cSrcweir 		pChkBox = 0;
826cdf0e10cSrcweir 
827cdf0e10cSrcweir 	// jetzt sollten wir mal die Pointer zerstoeren, bevor eine erneute
828cdf0e10cSrcweir 	// Actionklammerung kommt.
829cdf0e10cSrcweir 	if( !pPos && !pChkBox )
830cdf0e10cSrcweir 		ClearTblBoxCntnt();
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 	// liegt der Cursor nicht mehr in dem Bereich ?
833cdf0e10cSrcweir 	if( pChkBox && !pPos &&
834cdf0e10cSrcweir 		( pCurCrsr->HasMark() || pCurCrsr->GetNext() != pCurCrsr ||
835cdf0e10cSrcweir 		  pSttNd->GetIndex() + 1 == pCurCrsr->GetPoint()->nNode.GetIndex() ))
836cdf0e10cSrcweir 		pChkBox = 0;
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 	//JP 12.01.99: hat sich der Inhalt der Box ueberhaupt veraendert?
839cdf0e10cSrcweir 	// Ist wichtig, wenn z.B. Undo nicht den richtigen Inhalt wieder
840cdf0e10cSrcweir 	// herstellen konnte.
841cdf0e10cSrcweir 	if( pChkBox )
842cdf0e10cSrcweir 	{
843cdf0e10cSrcweir 		const SwTxtNode* pNd = GetDoc()->GetNodes()[
844cdf0e10cSrcweir 									pSttNd->GetIndex() + 1 ]->GetTxtNode();
845cdf0e10cSrcweir 		if( !pNd ||
846cdf0e10cSrcweir 			( pNd->GetTxt() == ViewShell::GetShellRes()->aCalc_Error &&
847cdf0e10cSrcweir 			  SFX_ITEM_SET == pChkBox->GetFrmFmt()->
848cdf0e10cSrcweir 							GetItemState( RES_BOXATR_FORMULA )) )
849cdf0e10cSrcweir 			pChkBox = 0;
850cdf0e10cSrcweir 	}
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 	if( pChkBox )
853cdf0e10cSrcweir 	{
854cdf0e10cSrcweir 		// jetzt sollten wir mal die Pointer zerstoeren, bevor ein weiterer
855cdf0e10cSrcweir 		// aufruf kommt.
856cdf0e10cSrcweir 		ClearTblBoxCntnt();
857cdf0e10cSrcweir 		StartAction();
858cdf0e10cSrcweir 		GetDoc()->ChkBoxNumFmt( *pChkBox, sal_True );
859cdf0e10cSrcweir 		EndAction();
860cdf0e10cSrcweir 	}
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 	return 0 != pChkBox;
863cdf0e10cSrcweir }
864cdf0e10cSrcweir 
865cdf0e10cSrcweir 
SaveTblBoxCntnt(const SwPosition * pPos)866cdf0e10cSrcweir void SwCrsrShell::SaveTblBoxCntnt( const SwPosition* pPos )
867cdf0e10cSrcweir {
868cdf0e10cSrcweir 	if( IsSelTblCells() || !IsAutoUpdateCells() )
869cdf0e10cSrcweir 		return ;
870cdf0e10cSrcweir 
871cdf0e10cSrcweir 	if( !pPos )
872cdf0e10cSrcweir 		pPos = pCurCrsr->GetPoint();
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 	SwStartNode* pSttNd = pPos->nNode.GetNode().FindSttNodeByType( SwTableBoxStartNode );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir 	sal_Bool bCheckBox = sal_False;
877cdf0e10cSrcweir 	if( pSttNd && pBoxIdx )
878cdf0e10cSrcweir 	{
879cdf0e10cSrcweir 		if( pSttNd == &pBoxIdx->GetNode() )
880cdf0e10cSrcweir 			pSttNd = 0;		// die haben wir schon
881cdf0e10cSrcweir 		else
882cdf0e10cSrcweir 			bCheckBox = sal_True;
883cdf0e10cSrcweir 	}
884cdf0e10cSrcweir 	else
885cdf0e10cSrcweir 		bCheckBox = 0 != pBoxIdx;
886cdf0e10cSrcweir 
887cdf0e10cSrcweir 	if( bCheckBox )
888cdf0e10cSrcweir 	{
889cdf0e10cSrcweir 		// pBoxIdx Checken
890cdf0e10cSrcweir 		SwPosition aPos( *pBoxIdx );
891cdf0e10cSrcweir 		CheckTblBoxCntnt( &aPos );
892cdf0e10cSrcweir 	}
893cdf0e10cSrcweir 
894cdf0e10cSrcweir 	if( pSttNd )
895cdf0e10cSrcweir 	{
896cdf0e10cSrcweir 		pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() );
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 		if( pBoxIdx )
899cdf0e10cSrcweir 			*pBoxIdx = *pSttNd;
900cdf0e10cSrcweir 		else
901cdf0e10cSrcweir 			pBoxIdx = new SwNodeIndex( *pSttNd );
902cdf0e10cSrcweir 	}
903cdf0e10cSrcweir }
904cdf0e10cSrcweir 
905cdf0e10cSrcweir 
ClearTblBoxCntnt()906cdf0e10cSrcweir void SwCrsrShell::ClearTblBoxCntnt()
907cdf0e10cSrcweir {
908cdf0e10cSrcweir 	delete pBoxIdx, pBoxIdx = 0;
909cdf0e10cSrcweir 	pBoxPtr = 0;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir 
EndAllTblBoxEdit()912cdf0e10cSrcweir sal_Bool SwCrsrShell::EndAllTblBoxEdit()
913cdf0e10cSrcweir {
914cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
915cdf0e10cSrcweir 	ViewShell *pSh = this;
916cdf0e10cSrcweir 	do {
917cdf0e10cSrcweir 		if( pSh->IsA( TYPE( SwCrsrShell ) ) )
918cdf0e10cSrcweir 			bRet |= ((SwCrsrShell*)pSh)->CheckTblBoxCntnt(
919cdf0e10cSrcweir 						((SwCrsrShell*)pSh)->pCurCrsr->GetPoint() );
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 	} while( this != (pSh = (ViewShell *)pSh->GetNext()) );
922cdf0e10cSrcweir 	return bRet;
923cdf0e10cSrcweir }
924cdf0e10cSrcweir 
925cdf0e10cSrcweir 
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 
928