Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <hintids.hxx>
30 : :
31 : : #include <vcl/svapp.hxx>
32 : : #include <editeng/protitem.hxx>
33 : : #include <crsrsh.hxx>
34 : : #include <doc.hxx>
35 : : #include <cntfrm.hxx>
36 : : #include <editsh.hxx>
37 : : #include <pam.hxx>
38 : : #include <swtable.hxx>
39 : : #include <docary.hxx>
40 : : #include <frmatr.hxx>
41 : : #include <frmfmt.hxx>
42 : : #include <viscrs.hxx>
43 : : #include <callnk.hxx>
44 : : #include <tabfrm.hxx>
45 : : #include <ndtxt.hxx>
46 : : #include <shellres.hxx>
47 : : #include <cellatr.hxx>
48 : : #include <cellfrm.hxx>
49 : : #include <rowfrm.hxx>
50 : :
51 : : /// set cursor into next/previous cell
52 : 0 : sal_Bool SwCrsrShell::GoNextCell( sal_Bool bAppendLine )
53 : : {
54 : 0 : sal_Bool bRet = sal_False;
55 : 0 : const SwTableNode* pTblNd = 0;
56 : :
57 [ # # ][ # # ]: 0 : if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() ))
[ # # ]
58 : : {
59 [ # # ][ # # ]: 0 : SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
60 [ # # ]: 0 : SwCallLink aLk( *this ); // watch Crsr-Moves
61 : 0 : bRet = sal_True;
62 : :
63 : : // Check if we have to move the cursor to a covered cell before
64 : : // proceeding:
65 [ # # ]: 0 : const SwNode* pTableBoxStartNode = pCrsr->GetNode()->FindTableBoxStartNode();
66 : 0 : const SwTableBox* pTableBox = 0;
67 : :
68 [ # # ]: 0 : if ( pCrsr->GetCrsrRowSpanOffset() )
69 : : {
70 [ # # ]: 0 : pTableBox = pTableBoxStartNode->GetTblBox();
71 [ # # ][ # # ]: 0 : if ( pTableBox->getRowSpan() > 1 )
72 : : {
73 [ # # ]: 0 : if ( !pTblNd )
74 [ # # ]: 0 : pTblNd = IsCrsrInTbl();
75 : 0 : pTableBox = & pTableBox->FindEndOfRowSpan( pTblNd->GetTable(),
76 [ # # ][ # # ]: 0 : (sal_uInt16)(pTableBox->getRowSpan() + pCrsr->GetCrsrRowSpanOffset() ) );
77 : 0 : pTableBoxStartNode = pTableBox->GetSttNd();
78 : : }
79 : : }
80 : :
81 [ # # ]: 0 : SwNodeIndex aCellStt( *pTableBoxStartNode->EndOfSectionNode(), 1 );
82 : :
83 : : // if there is another StartNode after the EndNode of a cell then
84 : : // there is another cell
85 [ # # ]: 0 : if( !aCellStt.GetNode().IsStartNode() )
86 : : {
87 [ # # ][ # # ]: 0 : if( pCrsr->HasMark() || !bAppendLine )
[ # # ]
88 : 0 : bRet = sal_False;
89 : : else
90 : : {
91 : : // if there is no list anymore then create new one
92 [ # # ]: 0 : if ( !pTableBox )
93 : 0 : pTableBox = pTblNd->GetTable().GetTblBox(
94 : 0 : pCrsr->GetPoint()->nNode.GetNode().
95 [ # # ]: 0 : StartOfSectionIndex() );
96 : :
97 : : OSL_ENSURE( pTableBox, "Box is not in this table" );
98 [ # # ]: 0 : SwSelBoxes aBoxes;
99 : :
100 : : // the document might change; w/o Action views would not be notified
101 [ # # ]: 0 : ((SwEditShell*)this)->StartAllAction();
102 : 0 : bRet = pDoc->InsertRow( pTblNd->GetTable().
103 [ # # ][ # # ]: 0 : SelLineFromBox( pTableBox, aBoxes, sal_False ));
104 [ # # ]: 0 : ((SwEditShell*)this)->EndAllAction();
105 : : }
106 : : }
107 [ # # ][ # # ]: 0 : if( bRet && 0 != ( bRet = pCrsr->GoNextCell() ))
[ # # ][ # # ]
108 [ # # ][ # # ]: 0 : UpdateCrsr();
[ # # ]
109 : : }
110 : 0 : return bRet;
111 : : }
112 : :
113 : :
114 : 0 : sal_Bool SwCrsrShell::GoPrevCell()
115 : : {
116 : 0 : sal_Bool bRet = sal_False;
117 [ # # ][ # # ]: 0 : if( IsTableMode() || IsCrsrInTbl() )
[ # # ]
118 : : {
119 [ # # ][ # # ]: 0 : SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
120 [ # # ]: 0 : SwCallLink aLk( *this ); // watch Crsr-Moves
121 [ # # ]: 0 : bRet = pCrsr->GoPrevCell();
122 [ # # ]: 0 : if( bRet )
123 [ # # ][ # # ]: 0 : UpdateCrsr(); // update current cursor
124 : : }
125 : 0 : return bRet;
126 : : }
127 : :
128 : 0 : const SwFrm* lcl_FindMostUpperCellFrm( const SwFrm* pFrm )
129 : : {
130 [ # # # # : 0 : while ( pFrm &&
# # # # ]
[ # # ]
131 : 0 : ( !pFrm->IsCellFrm() ||
132 : 0 : !pFrm->GetUpper()->GetUpper()->IsTabFrm() ||
133 : 0 : pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
134 : : {
135 : 0 : pFrm = pFrm->GetUpper();
136 : : }
137 : 0 : return pFrm;
138 : : }
139 : :
140 : 0 : sal_Bool SwCrsrShell::_SelTblRowOrCol( bool bRow, bool bRowSimple )
141 : : {
142 : : // check if the current cursor's SPoint/Mark are in a table
143 [ # # ]: 0 : SwFrm *pFrm = GetCurrFrm();
144 [ # # ][ # # ]: 0 : if( !pFrm->IsInTab() )
145 : 0 : return sal_False;
146 : :
147 [ # # ]: 0 : const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
148 [ # # ][ # # ]: 0 : const SwTabFrm* pMasterTabFrm = pTabFrm->IsFollow() ? pTabFrm->FindMaster( true ) : pTabFrm;
149 : 0 : const SwTable* pTable = pTabFrm->GetTable();
150 : :
151 [ # # ]: 0 : SET_CURR_SHELL( this );
152 : :
153 : 0 : const SwTableBox* pStt = 0;
154 : 0 : const SwTableBox* pEnd = 0;
155 : :
156 : : // search box based on layout
157 [ # # ]: 0 : SwSelBoxes aBoxes;
158 [ # # ]: 0 : SwTblSearchType eType = bRow ? nsSwTblSearchType::TBLSEARCH_ROW : nsSwTblSearchType::TBLSEARCH_COL;
159 : 0 : const bool bCheckProtected = !IsReadOnlyAvailable();
160 : :
161 [ # # ]: 0 : if( bCheckProtected )
162 : 0 : eType = (SwTblSearchType)(eType | nsSwTblSearchType::TBLSEARCH_PROTECT);
163 : :
164 [ # # ]: 0 : if ( !bRowSimple )
165 : : {
166 [ # # ]: 0 : GetTblSel( *this, aBoxes, eType );
167 : :
168 [ # # ]: 0 : if( aBoxes.empty() )
169 : 0 : return sal_False;
170 : :
171 [ # # ]: 0 : pStt = aBoxes[0];
172 [ # # ]: 0 : pEnd = aBoxes.back();
173 : : }
174 : : // #i32329# Enhanced table selection
175 [ # # ]: 0 : else if ( pTable->IsNewModel() )
176 : : {
177 : 0 : const SwShellCrsr *pCrsr = _GetCrsr();
178 [ # # ]: 0 : SwTable::SearchType eSearchType = bRow ? SwTable::SEARCH_ROW : SwTable::SEARCH_COL;
179 [ # # ]: 0 : pTable->CreateSelection( *pCrsr, aBoxes, eSearchType, bCheckProtected );
180 [ # # ]: 0 : if( aBoxes.empty() )
181 : 0 : return sal_False;
182 : :
183 [ # # ]: 0 : pStt = aBoxes[0];
184 [ # # ]: 0 : pEnd = aBoxes.back();
185 : : }
186 : : else
187 : : {
188 : 0 : const SwShellCrsr *pCrsr = _GetCrsr();
189 : 0 : const SwFrm* pStartFrm = pFrm;
190 : 0 : const SwCntntNode *pCNd = pCrsr->GetCntntNode( sal_False );
191 [ # # ][ # # ]: 0 : const SwFrm* pEndFrm = pCNd ? pCNd->getLayoutFrm( GetLayout(), &pCrsr->GetMkPos() ) : 0;
[ # # ]
192 : :
193 [ # # ]: 0 : if ( bRow )
194 : : {
195 [ # # ]: 0 : pStartFrm = lcl_FindMostUpperCellFrm( pStartFrm );
196 [ # # ]: 0 : pEndFrm = lcl_FindMostUpperCellFrm( pEndFrm );
197 : : }
198 : :
199 [ # # ][ # # ]: 0 : if ( !pStartFrm || !pEndFrm )
200 : 0 : return sal_False;
201 : :
202 [ # # ][ # # ]: 0 : const bool bVert = pFrm->ImplFindTabFrm()->IsVertical();
203 : :
204 : : // If we select upwards it is sufficient to set pStt and pEnd
205 : : // to the first resp. last box of the selection obtained from
206 : : // GetTblSel. However, selecting downwards requires the frames
207 : : // located at the corners of the selection. This does not work
208 : : // for column selections in vertical tables:
209 : 0 : const bool bSelectUp = ( bVert && !bRow ) ||
210 [ # # ][ # # ]: 0 : *pCrsr->GetPoint() <= *pCrsr->GetMark();
[ # # ][ # # ]
211 [ # # ]: 0 : SwCellFrms aCells;
212 : : GetTblSel( static_cast<const SwCellFrm*>(pStartFrm),
213 : : static_cast<const SwCellFrm*>(pEndFrm),
214 [ # # ][ # # ]: 0 : aBoxes, bSelectUp ? 0 : &aCells, eType );
215 : :
216 [ # # ][ # # ]: 0 : if( aBoxes.empty() || ( !bSelectUp && 4 != aCells.size() ) )
[ # # ][ # # ]
217 : 0 : return sal_False;
218 : :
219 [ # # ]: 0 : if ( bSelectUp )
220 : : {
221 [ # # ]: 0 : pStt = aBoxes[0];
222 [ # # ]: 0 : pEnd = aBoxes.back();
223 : : }
224 : : else
225 : : {
226 : : // will become point of table cursor
227 [ # # ][ # # ]: 0 : pStt = aCells[ bVert ? (bRow ? 0 : 3) : (bRow ? 2 : 1) ]->GetTabBox();
[ # # ][ # # ]
228 : : // will become mark of table cursor
229 [ # # ][ # # ]: 0 : pEnd = aCells[ bVert ? (bRow ? 3 : 0) : (bRow ? 1 : 2) ]->GetTabBox();
[ # # ][ # # ]
230 [ # # ]: 0 : }
231 : : }
232 : :
233 : : // if no table cursor exists, create one
234 [ # # ]: 0 : if( !pTblCrsr )
235 : : {
236 [ # # ][ # # ]: 0 : pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
237 [ # # ]: 0 : pCurCrsr->DeleteMark();
238 [ # # ]: 0 : pCurCrsr->SwSelPaintRects::Hide();
239 : : }
240 : :
241 [ # # ]: 0 : pTblCrsr->DeleteMark();
242 : :
243 : : // set start and end of a column
244 [ # # ]: 0 : pTblCrsr->GetPoint()->nNode = *pEnd->GetSttNd();
245 [ # # ]: 0 : pTblCrsr->Move( fnMoveForward, fnGoCntnt );
246 [ # # ]: 0 : pTblCrsr->SetMark();
247 [ # # ]: 0 : pTblCrsr->GetPoint()->nNode = *pStt->GetSttNd()->EndOfSectionNode();
248 [ # # ]: 0 : pTblCrsr->Move( fnMoveBackward, fnGoCntnt );
249 : :
250 : : // set PtPos 'close' to the reference table, otherwise we might get problems
251 : : // with the repeated headlines check in UpdateCrsr():
252 [ # # ]: 0 : if ( !bRow )
253 [ # # ]: 0 : pTblCrsr->GetPtPos() = pMasterTabFrm->IsVertical()
254 : 0 : ? pMasterTabFrm->Frm().TopRight()
255 [ # # # # ]: 0 : : pMasterTabFrm->Frm().TopLeft();
[ # # ]
256 : :
257 [ # # ]: 0 : UpdateCrsr();
258 [ # # ]: 0 : return sal_True;
259 : : }
260 : :
261 : 0 : sal_Bool SwCrsrShell::SelTbl()
262 : : {
263 : : // check if the current cursor's SPoint/Mark are in a table
264 [ # # ]: 0 : SwFrm *pFrm = GetCurrFrm();
265 [ # # ][ # # ]: 0 : if( !pFrm->IsInTab() )
266 : 0 : return sal_False;
267 : :
268 [ # # ]: 0 : const SwTabFrm *pTblFrm = pFrm->ImplFindTabFrm();
269 [ # # ][ # # ]: 0 : const SwTabFrm* pMasterTabFrm = pTblFrm->IsFollow() ? pTblFrm->FindMaster( true ) : pTblFrm;
270 [ # # ]: 0 : const SwTableNode* pTblNd = pTblFrm->GetTable()->GetTableNode();
271 : :
272 [ # # ]: 0 : SET_CURR_SHELL( this );
273 : :
274 [ # # ]: 0 : if( !pTblCrsr )
275 : : {
276 [ # # ][ # # ]: 0 : pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
277 [ # # ]: 0 : pCurCrsr->DeleteMark();
278 [ # # ]: 0 : pCurCrsr->SwSelPaintRects::Hide();
279 : : }
280 : :
281 [ # # ]: 0 : pTblCrsr->DeleteMark();
282 [ # # ]: 0 : pTblCrsr->GetPoint()->nNode = *pTblNd;
283 [ # # ]: 0 : pTblCrsr->Move( fnMoveForward, fnGoCntnt );
284 [ # # ]: 0 : pTblCrsr->SetMark();
285 : : // set MkPos 'close' to the master table, otherwise we might get problems
286 : : // with the repeated headlines check in UpdateCrsr():
287 [ # # ][ # # ]: 0 : pTblCrsr->GetMkPos() = pMasterTabFrm->IsVertical() ? pMasterTabFrm->Frm().TopRight() : pMasterTabFrm->Frm().TopLeft();
[ # # ][ # # ]
288 [ # # ]: 0 : pTblCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
289 [ # # ]: 0 : pTblCrsr->Move( fnMoveBackward, fnGoCntnt );
290 [ # # ]: 0 : UpdateCrsr();
291 [ # # ]: 0 : return sal_True;
292 : : }
293 : :
294 : :
295 : 0 : sal_Bool SwCrsrShell::SelTblBox()
296 : : {
297 : : // if we're in a table, create a table cursor, and select the cell
298 : : // that the current cursor's point resides in
299 : :
300 : : // search for start node of our table box. If not found, exit realy
301 : : const SwStartNode* pStartNode =
302 [ # # ]: 0 : pCurCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
303 : :
304 : : #if OSL_DEBUG_LEVEL > 0
305 : : // the old code checks whether we're in a table by asking the
306 : : // frame. This should yield the same result as searching for the
307 : : // table box start node, right?
308 : : SwFrm *pFrm = GetCurrFrm();
309 : : OSL_ENSURE( !pFrm->IsInTab() == !(pStartNode != NULL),
310 : : "Schroedinger's table: We're in a box, and also we aren't." );
311 : : #endif
312 : :
313 [ # # ]: 0 : if( pStartNode == NULL )
314 : 0 : return sal_False;
315 : :
316 : :
317 [ # # ]: 0 : SET_CURR_SHELL( this );
318 : :
319 : : // create a table cursor, if there isn't one already
320 [ # # ]: 0 : if( !pTblCrsr )
321 : : {
322 [ # # ][ # # ]: 0 : pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
323 [ # # ]: 0 : pCurCrsr->DeleteMark();
324 [ # # ]: 0 : pCurCrsr->SwSelPaintRects::Hide();
325 : : }
326 : :
327 : : // select the complete box with our shiny new pTblCrsr
328 : : // 1. delete mark, and move point to first content node in box
329 : :
330 [ # # ]: 0 : pTblCrsr->DeleteMark();
331 [ # # ][ # # ]: 0 : *(pTblCrsr->GetPoint()) = SwPosition( *pStartNode );
[ # # ]
332 [ # # ]: 0 : pTblCrsr->Move( fnMoveForward, fnGoNode );
333 : :
334 : : // 2. set mark, and move point to last content node in box
335 [ # # ]: 0 : pTblCrsr->SetMark();
336 [ # # ][ # # ]: 0 : *(pTblCrsr->GetPoint()) = SwPosition( *(pStartNode->EndOfSectionNode()) );
[ # # ]
337 [ # # ]: 0 : pTblCrsr->Move( fnMoveBackward, fnGoNode );
338 : :
339 : : // 3. exchange
340 : 0 : pTblCrsr->Exchange();
341 : :
342 : : // with some luck, UpdateCrsr() will now update everything that
343 : : // needs updateing
344 [ # # ]: 0 : UpdateCrsr();
345 : :
346 [ # # ]: 0 : return sal_True;
347 : : }
348 : :
349 : : // TODO: provide documentation
350 : : /** get the next non-protected cell inside a table
351 : :
352 : : @param[in,out] rIdx is on a table node
353 : : @param bInReadOnly ???
354 : :
355 : : @return <false> if no suitable cell could be found, otherwise <rIdx> points
356 : : to content in a suitable cell and <true> is returned.
357 : : */
358 : 8 : bool lcl_FindNextCell( SwNodeIndex& rIdx, sal_Bool bInReadOnly )
359 : : {
360 : : // check protected cells
361 [ + - ]: 8 : SwNodeIndex aTmp( rIdx, 2 ); // TableNode + StartNode
362 : :
363 : : // the resulting cell should be in that table:
364 : 8 : const SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
365 : :
366 [ - + ]: 8 : if ( !pTblNd )
367 : : {
368 : : OSL_FAIL( "lcl_FindNextCell not celled with table start node!" );
369 : 0 : return false;
370 : : }
371 : :
372 : 8 : const SwNode* pTableEndNode = pTblNd->EndOfSectionNode();
373 : :
374 : 8 : SwNodes& rNds = aTmp.GetNode().GetNodes();
375 : 8 : SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode();
376 : :
377 : : // no content node => go to next content node
378 [ - + ]: 8 : if( !pCNd )
379 [ # # ]: 0 : pCNd = rNds.GoNext( &aTmp );
380 : :
381 : : // robust
382 [ - + ]: 8 : if ( !pCNd )
383 : 0 : return false;
384 : :
385 [ + - ][ + - ]: 8 : SwCntntFrm* pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
386 : :
387 [ + - ][ + - ]: 8 : if ( 0 == pFrm || pCNd->FindTableNode() != pTblNd ||
[ + - ][ - + ]
[ # # ][ - + ]
388 [ # # ]: 0 : (!bInReadOnly && pFrm->IsProtected() ) )
389 : : {
390 : : // we are not located inside a 'valid' cell. We have to continue searching...
391 : :
392 : : // skip behind current section. This might be the end of the table cell
393 : : // or behind a inner section or or or...
394 [ # # ]: 0 : aTmp.Assign( *pCNd->EndOfSectionNode(), 1 );
395 : :
396 : : // loop to find a suitable cell...
397 : 0 : for( ;; )
398 : : {
399 : 0 : SwNode* pNd = &aTmp.GetNode();
400 : :
401 : : // we break this loop if we reached the end of the table.
402 : : // to make this code even more robust, we also break if we are
403 : : // already behind the table end node:
404 [ # # ][ # # ]: 0 : if( pNd == pTableEndNode || /*robust: */ pNd->GetIndex() > pTableEndNode->GetIndex() )
[ # # ]
405 : 0 : return false;
406 : :
407 : : // ok, get the next content node:
408 : 0 : pCNd = aTmp.GetNode().GetCntntNode();
409 [ # # ]: 0 : if( 0 == pCNd )
410 [ # # ]: 0 : pCNd = rNds.GoNext( &aTmp );
411 : :
412 : : // robust:
413 [ # # ]: 0 : if ( !pCNd )
414 : 0 : return false;
415 : :
416 : : // check if we have found a suitable table cell:
417 [ # # ][ # # ]: 0 : pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
418 : :
419 [ # # ][ # # ]: 0 : if ( 0 != pFrm && pCNd->FindTableNode() == pTblNd &&
[ # # ][ # # ]
[ # # ][ # # ]
420 [ # # ]: 0 : (bInReadOnly || !pFrm->IsProtected() ) )
421 : : {
422 : : // finally, we have found a suitable table cell => set index and return
423 [ # # ]: 0 : rIdx = *pCNd;
424 : 0 : return true;
425 : : }
426 : :
427 : : // continue behind the current section:
428 [ # # ]: 0 : aTmp.Assign( *pCNd->EndOfSectionNode(), +1 );
429 : : }
430 : : }
431 : :
432 [ + - ]: 8 : rIdx = *pCNd;
433 [ + - ]: 8 : return true;
434 : : }
435 : :
436 : : /// see lcl_FindNextCell()
437 : 18 : bool lcl_FindPrevCell( SwNodeIndex& rIdx, sal_Bool bInReadOnly )
438 : : {
439 [ + - ]: 18 : SwNodeIndex aTmp( rIdx, -2 ); // TableNode + EndNode
440 : :
441 : 18 : const SwNode* pTableEndNode = &rIdx.GetNode();
442 : 18 : const SwTableNode* pTblNd = pTableEndNode->StartOfSectionNode()->GetTableNode();
443 : :
444 [ - + ]: 18 : if ( !pTblNd )
445 : : {
446 : : OSL_FAIL( "lcl_FindPrevCell not celled with table start node!" );
447 : 0 : return false;
448 : : }
449 : :
450 : 18 : SwNodes& rNds = aTmp.GetNode().GetNodes();
451 : 18 : SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode();
452 : :
453 [ - + ]: 18 : if( !pCNd )
454 [ # # ]: 0 : pCNd = rNds.GoPrevious( &aTmp );
455 : :
456 [ - + ]: 18 : if ( !pCNd )
457 : 0 : return false;
458 : :
459 [ + - ][ + - ]: 18 : SwCntntFrm* pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
460 : :
461 [ + - ][ + - ]: 18 : if( 0 == pFrm || pCNd->FindTableNode() != pTblNd ||
[ + - ][ - + ]
[ # # ][ - + ]
462 [ # # ]: 0 : (!bInReadOnly && pFrm->IsProtected() ))
463 : : {
464 : : // skip before current section
465 [ # # ]: 0 : aTmp.Assign( *pCNd->StartOfSectionNode(), -1 );
466 : 0 : for( ;; )
467 : : {
468 : 0 : SwNode* pNd = &aTmp.GetNode();
469 : :
470 [ # # ][ # # ]: 0 : if( pNd == pTblNd || pNd->GetIndex() < pTblNd->GetIndex() )
[ # # ]
471 : 0 : return false;
472 : :
473 : 0 : pCNd = aTmp.GetNode().GetCntntNode();
474 [ # # ]: 0 : if( 0 == pCNd )
475 [ # # ]: 0 : pCNd = rNds.GoPrevious( &aTmp );
476 : :
477 [ # # ]: 0 : if ( !pCNd )
478 : 0 : return false;
479 : :
480 [ # # ][ # # ]: 0 : pFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() );
481 : :
482 [ # # ][ # # ]: 0 : if( 0 != pFrm && pCNd->FindTableNode() == pTblNd &&
[ # # ][ # # ]
[ # # ][ # # ]
483 [ # # ]: 0 : (bInReadOnly || !pFrm->IsProtected() ) )
484 : : {
485 [ # # ]: 0 : rIdx = *pCNd;
486 : 0 : return true; // ok, not protected
487 : : }
488 [ # # ]: 0 : aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 );
489 : : }
490 : : }
491 : :
492 [ + - ]: 18 : rIdx = *pCNd;
493 [ + - ]: 18 : return true;
494 : : }
495 : :
496 : :
497 : 0 : sal_Bool GotoPrevTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
498 : : sal_Bool bInReadOnly )
499 : : {
500 [ # # ]: 0 : SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
501 : :
502 [ # # ]: 0 : SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
503 [ # # ]: 0 : if( pTblNd )
504 : : {
505 : : // #i26532#: If we are inside a table, we may not go backward to the
506 : : // table start node, because we would miss any tables inside this table.
507 : 0 : SwTableNode* pInnerTblNd = 0;
508 [ # # ]: 0 : SwNodeIndex aTmpIdx( aIdx );
509 [ # # # # ]: 0 : while( aTmpIdx.GetIndex() &&
[ # # ]
510 : 0 : 0 == ( pInnerTblNd = aTmpIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
511 [ # # ]: 0 : aTmpIdx--;
512 : :
513 [ # # ]: 0 : if( pInnerTblNd == pTblNd )
514 [ # # ][ # # ]: 0 : aIdx.Assign( *pTblNd, - 1 );
515 : : }
516 : :
517 [ # # ]: 0 : do {
518 [ # # # # ]: 0 : while( aIdx.GetIndex() &&
[ # # ]
519 : 0 : 0 == ( pTblNd = aIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
520 [ # # ]: 0 : aIdx--;
521 : :
522 [ # # ]: 0 : if( pTblNd ) // any further table node?
523 : : {
524 [ # # ]: 0 : if( fnPosTbl == fnMoveForward ) // at the beginning?
525 : : {
526 [ # # ]: 0 : aIdx = *aIdx.GetNode().StartOfSectionNode();
527 [ # # ][ # # ]: 0 : if( !lcl_FindNextCell( aIdx, bInReadOnly ))
528 : : {
529 : : // skip table
530 [ # # ]: 0 : aIdx.Assign( *pTblNd, -1 );
531 : 0 : continue;
532 : : }
533 : : }
534 : : else
535 : : {
536 : : // check protected cells
537 [ # # ][ # # ]: 0 : if( !lcl_FindNextCell( aIdx, bInReadOnly ))
538 : : {
539 : : // skip table
540 [ # # ]: 0 : aIdx.Assign( *pTblNd, -1 );
541 : 0 : continue;
542 : : }
543 : : }
544 : :
545 : 0 : SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode();
546 [ # # ]: 0 : if ( pTxtNode )
547 : : {
548 [ # # ]: 0 : rCurCrsr.GetPoint()->nNode = *pTxtNode;
549 : 0 : rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
550 [ # # ]: 0 : pTxtNode->Len() :
551 [ # # ][ # # ]: 0 : 0 );
[ # # ]
552 : : }
553 : 0 : return sal_True;
554 : : }
555 : : } while( pTblNd );
556 : :
557 [ # # ]: 0 : return sal_False;
558 : : }
559 : :
560 : :
561 : 0 : sal_Bool GotoNextTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
562 : : sal_Bool bInReadOnly )
563 : : {
564 [ # # ]: 0 : SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode );
565 [ # # ]: 0 : SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
566 : :
567 [ # # ]: 0 : if( pTblNd )
568 [ # # ]: 0 : aIdx.Assign( *pTblNd->EndOfSectionNode(), 1 );
569 : :
570 [ # # ]: 0 : sal_uLong nLastNd = rCurCrsr.GetDoc()->GetNodes().Count() - 1;
571 [ # # ]: 0 : do {
572 [ # # # # ]: 0 : while( aIdx.GetIndex() < nLastNd &&
[ # # ]
573 : 0 : 0 == ( pTblNd = aIdx.GetNode().GetTableNode()) )
574 [ # # ]: 0 : aIdx++;
575 [ # # ]: 0 : if( pTblNd ) // any further table node?
576 : : {
577 [ # # ]: 0 : if( fnPosTbl == fnMoveForward ) // at the beginning?
578 : : {
579 [ # # ][ # # ]: 0 : if( !lcl_FindNextCell( aIdx, bInReadOnly ))
580 : : {
581 : : // skip table
582 [ # # ]: 0 : aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 );
583 : 0 : continue;
584 : : }
585 : : }
586 : : else
587 : : {
588 [ # # ]: 0 : aIdx = *aIdx.GetNode().EndOfSectionNode();
589 : : // check protected cells
590 [ # # ][ # # ]: 0 : if( !lcl_FindNextCell( aIdx, bInReadOnly ))
591 : : {
592 : : // skip table
593 [ # # ]: 0 : aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 );
594 : 0 : continue;
595 : : }
596 : : }
597 : :
598 : 0 : SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode();
599 [ # # ]: 0 : if ( pTxtNode )
600 : : {
601 [ # # ]: 0 : rCurCrsr.GetPoint()->nNode = *pTxtNode;
602 : 0 : rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
603 [ # # ]: 0 : pTxtNode->Len() :
604 [ # # ][ # # ]: 0 : 0 );
[ # # ]
605 : : }
606 : 0 : return sal_True;
607 : : }
608 : : } while( pTblNd );
609 : :
610 [ # # ]: 0 : return sal_False;
611 : : }
612 : :
613 : :
614 : 26 : sal_Bool GotoCurrTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl,
615 : : sal_Bool bInReadOnly )
616 : : {
617 : 26 : SwTableNode* pTblNd = rCurCrsr.GetPoint()->nNode.GetNode().FindTableNode();
618 [ - + ]: 26 : if( !pTblNd )
619 : 0 : return sal_False;
620 : :
621 : 26 : SwTxtNode* pTxtNode = 0;
622 [ + + ]: 26 : if( fnPosTbl == fnMoveBackward ) // to the end of the table
623 : : {
624 [ + - ]: 18 : SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() );
625 [ + - ][ - + ]: 18 : if( !lcl_FindPrevCell( aIdx, bInReadOnly ))
626 : 0 : return sal_False;
627 [ + - ][ + - ]: 18 : pTxtNode = aIdx.GetNode().GetTxtNode();
628 : : }
629 : : else
630 : : {
631 [ + - ]: 8 : SwNodeIndex aIdx( *pTblNd );
632 [ + - ][ - + ]: 8 : if( !lcl_FindNextCell( aIdx, bInReadOnly ))
633 : 0 : return sal_False;
634 [ + - ][ + - ]: 8 : pTxtNode = aIdx.GetNode().GetTxtNode();
635 : : }
636 : :
637 [ + - ]: 26 : if ( pTxtNode )
638 : : {
639 : 26 : rCurCrsr.GetPoint()->nNode = *pTxtNode;
640 : 26 : rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ?
641 : 18 : pTxtNode->Len() :
642 [ + - ][ + + ]: 70 : 0 );
643 : : }
644 : :
645 : 26 : return sal_True;
646 : : }
647 : :
648 : :
649 : 26 : sal_Bool SwCursor::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl )
650 : : {
651 : 26 : sal_Bool bRet = sal_False;
652 [ - + ]: 26 : SwTableCursor* pTblCrsr = dynamic_cast<SwTableCursor*>(this);
653 : :
654 [ - + ][ # # ]: 26 : if( pTblCrsr || !HasMark() )
[ + - ]
655 : : {
656 [ + - ]: 26 : SwCrsrSaveState aSaveState( *this );
657 [ + - ][ + - ]: 26 : bRet = (*fnWhichTbl)( *this, fnPosTbl, IsReadOnlyAvailable() ) &&
658 : : !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
659 [ + - ][ + - ]: 26 : nsSwCursorSelOverFlags::SELOVER_TOGGLE );
[ + - ][ + - ]
660 : : }
661 : 26 : return bRet;
662 : : }
663 : :
664 : 4 : sal_Bool SwCrsrShell::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl )
665 : : {
666 [ + - ]: 4 : SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
667 : :
668 [ - + ][ # # ]: 4 : SwShellCrsr* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr;
669 : : sal_Bool bCheckPos, bRet;
670 : 4 : sal_uLong nPtNd = 0;
671 : 4 : xub_StrLen nPtCnt = 0;
672 : :
673 [ + - ][ + - ]: 4 : if ( !pTblCrsr && pCurCrsr->HasMark() )
[ + - ]
674 : : {
675 : : // switch to table mode
676 [ + - ][ + - ]: 4 : pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() );
677 [ + - ]: 4 : pCurCrsr->DeleteMark();
678 [ + - ]: 4 : pCurCrsr->SwSelPaintRects::Hide();
679 [ + - ]: 4 : pTblCrsr->SetMark();
680 [ + - ]: 4 : pCrsr = pTblCrsr;
681 : 4 : bCheckPos = sal_False;
682 : : }
683 : : else
684 : : {
685 : 0 : bCheckPos = sal_True;
686 : 0 : nPtNd = pCrsr->GetPoint()->nNode.GetIndex();
687 : 0 : nPtCnt = pCrsr->GetPoint()->nContent.GetIndex();
688 : : }
689 : :
690 [ + - ]: 4 : bRet = pCrsr->MoveTable( fnWhichTbl, fnPosTbl );
691 : :
692 [ + - ]: 4 : if( bRet )
693 : : {
694 : : // #i45028# - set "top" position for repeated headline rows
695 : 4 : pCrsr->GetPtPos() = Point();
696 : :
697 [ + - ]: 4 : UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
698 : :
699 [ - + # # : 4 : if( bCheckPos &&
# # ][ - + ]
700 : 0 : pCrsr->GetPoint()->nNode.GetIndex() == nPtNd &&
701 : 0 : pCrsr->GetPoint()->nContent.GetIndex() == nPtCnt )
702 : 0 : bRet = sal_False;
703 : : }
704 [ + - ]: 4 : return bRet;
705 : : }
706 : :
707 : :
708 : 0 : sal_Bool SwCrsrShell::IsTblComplex() const
709 : : {
710 : 0 : SwFrm *pFrm = GetCurrFrm( sal_False );
711 [ # # ][ # # ]: 0 : if ( pFrm && pFrm->IsInTab() )
[ # # ]
712 : 0 : return pFrm->FindTabFrm()->GetTable()->IsTblComplex();
713 : 0 : return sal_False;
714 : : }
715 : :
716 : :
717 : 0 : sal_Bool SwCrsrShell::IsTblComplexForChart()
718 : : {
719 : 0 : sal_Bool bRet = sal_False;
720 : :
721 : : // Here we may trigger table formatting so we better do that inside an action
722 : 0 : StartAction();
723 : 0 : const SwTableNode* pTNd = pCurCrsr->GetPoint()->nNode.GetNode().FindTableNode();
724 [ # # ]: 0 : if( pTNd )
725 : : {
726 : : // in a table; check if table or section is balanced
727 [ # # ]: 0 : String sSel;
728 [ # # ]: 0 : if( pTblCrsr )
729 [ # # ][ # # ]: 0 : sSel = GetBoxNms();
[ # # ]
730 [ # # ][ # # ]: 0 : bRet = pTNd->GetTable().IsTblComplexForChart( sSel );
731 : : }
732 : :
733 : 0 : EndAction();
734 : :
735 : 0 : return bRet;
736 : : }
737 : :
738 : 7 : String SwCrsrShell::GetBoxNms() const
739 : : {
740 : 7 : String sNm;
741 : : const SwPosition* pPos;
742 : : SwFrm* pFrm;
743 : :
744 [ + + ]: 7 : if( IsTableMode() )
745 : : {
746 [ + - ]: 4 : SwCntntNode *pCNd = pTblCrsr->Start()->nNode.GetNode().GetCntntNode();
747 [ + - ][ + - ]: 4 : pFrm = pCNd ? pCNd->getLayoutFrm( GetLayout() ) : 0;
[ + - ]
748 [ - + ]: 4 : if( !pFrm )
749 : 0 : return sNm;
750 : :
751 [ - + ]: 8 : do {
[ + - - + ]
752 : 4 : pFrm = pFrm->GetUpper();
753 : 4 : } while ( pFrm && !pFrm->IsCellFrm() );
754 : :
755 : : OSL_ENSURE( pFrm, "no frame for this box" );
756 : :
757 [ - + ]: 4 : if( !pFrm )
758 : 0 : return sNm;
759 : :
760 [ + - ][ + - ]: 4 : sNm = ((SwCellFrm*)pFrm)->GetTabBox()->GetName();
[ + - ]
761 [ + - ]: 4 : sNm += ':';
762 [ + - ]: 4 : pPos = pTblCrsr->End();
763 : : }
764 : : else
765 : : {
766 [ + - ]: 3 : const SwTableNode* pTblNd = IsCrsrInTbl();
767 [ - + ]: 3 : if( !pTblNd )
768 : 0 : return sNm;
769 [ + - ]: 3 : pPos = GetCrsr()->GetPoint();
770 : : }
771 : :
772 : 7 : SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode();
773 [ + - ][ + - ]: 7 : pFrm = pCNd ? pCNd->getLayoutFrm( GetLayout() ) : 0;
[ + - ]
774 : :
775 [ + - ]: 7 : if( pFrm )
776 : : {
777 [ - + ]: 14 : do {
[ + - - + ]
778 : 7 : pFrm = pFrm->GetUpper();
779 : 7 : } while ( pFrm && !pFrm->IsCellFrm() );
780 : :
781 [ + - ]: 7 : if( pFrm )
782 [ + - ][ + - ]: 7 : sNm += ((SwCellFrm*)pFrm)->GetTabBox()->GetName();
[ + - ]
783 : : }
784 : 7 : return sNm;
785 : : }
786 : :
787 : :
788 : 2 : sal_Bool SwCrsrShell::GotoTable( const String& rName )
789 : : {
790 [ + - ]: 2 : SwCallLink aLk( *this ); // watch Crsr-Moves
791 [ + - ][ + - ]: 2 : sal_Bool bRet = !pTblCrsr && pCurCrsr->GotoTable( rName );
[ + - ]
792 [ + - ]: 2 : if( bRet )
793 : : {
794 : 2 : pCurCrsr->GetPtPos() = Point();
795 : : UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE |
796 [ + - ]: 2 : SwCrsrShell::READONLY );
797 : : }
798 [ + - ]: 2 : return bRet;
799 : : }
800 : :
801 : :
802 : 34306 : sal_Bool SwCrsrShell::CheckTblBoxCntnt( const SwPosition* pPos )
803 : : {
804 [ - + ][ # # ]: 34306 : if( !pBoxIdx || !pBoxPtr || IsSelTblCells() || !IsAutoUpdateCells() )
[ # # ][ # # ]
[ + - ]
805 : 34306 : return sal_False;
806 : :
807 : : // check if box content is consistent with given box format, reset if not
808 : 0 : SwTableBox* pChkBox = 0;
809 : 0 : SwStartNode* pSttNd = 0;
810 [ # # ]: 0 : if( !pPos )
811 : : {
812 : : // get stored position
813 [ # # ][ # # : 0 : if( pBoxIdx && pBoxPtr &&
# # # # #
# ][ # # ]
814 : 0 : 0 != ( pSttNd = pBoxIdx->GetNode().GetStartNode() ) &&
815 : 0 : SwTableBoxStartNode == pSttNd->GetStartNodeType() &&
816 : 0 : pBoxPtr == pSttNd->FindTableNode()->GetTable().
817 : 0 : GetTblBox( pBoxIdx->GetIndex() ) )
818 : 0 : pChkBox = pBoxPtr;
819 : : }
820 [ # # ]: 0 : else if( 0 != ( pSttNd = pPos->nNode.GetNode().
821 : : FindSttNodeByType( SwTableBoxStartNode )) )
822 : : {
823 : 0 : pChkBox = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() );
824 : : }
825 : :
826 : : // box has more than one paragraph
827 [ # # ][ # # ]: 0 : if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() )
[ # # ]
828 : 0 : pChkBox = 0;
829 : :
830 : : // destroy pointer before next action starts
831 [ # # ][ # # ]: 0 : if( !pPos && !pChkBox )
832 : 0 : ClearTblBoxCntnt();
833 : :
834 : : // cursor not anymore in this section?
835 [ # # ][ # # : 0 : if( pChkBox && !pPos &&
# # # # ]
[ # # # # ]
[ # # ]
836 : 0 : ( pCurCrsr->HasMark() || pCurCrsr->GetNext() != pCurCrsr ||
837 : 0 : pSttNd->GetIndex() + 1 == pCurCrsr->GetPoint()->nNode.GetIndex() ))
838 : 0 : pChkBox = 0;
839 : :
840 : : // Did the content of a box change at all? This is important if e.g. Undo
841 : : // could not restore the content properly.
842 [ # # ]: 0 : if( pChkBox )
843 : : {
844 : 0 : const SwTxtNode* pNd = GetDoc()->GetNodes()[
845 : 0 : pSttNd->GetIndex() + 1 ]->GetTxtNode();
846 [ # # ][ # # : 0 : if( !pNd ||
# # # # ]
847 : 0 : ( pNd->GetTxt() == ViewShell::GetShellRes()->aCalc_Error &&
848 : 0 : SFX_ITEM_SET == pChkBox->GetFrmFmt()->
849 : 0 : GetItemState( RES_BOXATR_FORMULA )) )
850 : 0 : pChkBox = 0;
851 : : }
852 : :
853 [ # # ]: 0 : if( pChkBox )
854 : : {
855 : : // destroy pointer before next action starts
856 : 0 : ClearTblBoxCntnt();
857 : 0 : StartAction();
858 : 0 : GetDoc()->ChkBoxNumFmt( *pChkBox, sal_True );
859 : 0 : EndAction();
860 : : }
861 : :
862 : 34306 : return 0 != pChkBox;
863 : : }
864 : :
865 : :
866 : 20 : void SwCrsrShell::SaveTblBoxCntnt( const SwPosition* pPos )
867 : : {
868 [ + - ][ - + ]: 20 : if( IsSelTblCells() || !IsAutoUpdateCells() )
[ - + ]
869 : 20 : return ;
870 : :
871 [ + + ]: 20 : if( !pPos )
872 : 8 : pPos = pCurCrsr->GetPoint();
873 : :
874 : 20 : SwStartNode* pSttNd = pPos->nNode.GetNode().FindSttNodeByType( SwTableBoxStartNode );
875 : :
876 : 20 : sal_Bool bCheckBox = sal_False;
877 [ # # ][ - + ]: 20 : if( pSttNd && pBoxIdx )
878 : : {
879 [ # # ]: 0 : if( pSttNd == &pBoxIdx->GetNode() )
880 : 0 : pSttNd = 0;
881 : : else
882 : 0 : bCheckBox = sal_True;
883 : : }
884 : : else
885 : 20 : bCheckBox = 0 != pBoxIdx;
886 : :
887 [ - + ]: 20 : if( bCheckBox )
888 : : {
889 : : // check pBoxIdx
890 [ # # ]: 0 : SwPosition aPos( *pBoxIdx );
891 [ # # ][ # # ]: 0 : CheckTblBoxCntnt( &aPos );
892 : : }
893 : :
894 [ - + ]: 20 : if( pSttNd )
895 : : {
896 : 0 : pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() );
897 : :
898 [ # # ]: 0 : if( pBoxIdx )
899 : 0 : *pBoxIdx = *pSttNd;
900 : : else
901 [ # # ]: 0 : pBoxIdx = new SwNodeIndex( *pSttNd );
902 : : }
903 : : }
904 : :
905 : :
906 : 1239 : void SwCrsrShell::ClearTblBoxCntnt()
907 : : {
908 [ - + ]: 1239 : delete pBoxIdx, pBoxIdx = 0;
909 : 1239 : pBoxPtr = 0;
910 : 1239 : }
911 : :
912 : 51 : sal_Bool SwCrsrShell::EndAllTblBoxEdit()
913 : : {
914 : 51 : sal_Bool bRet = sal_False;
915 : 51 : ViewShell *pSh = this;
916 [ - + ]: 51 : do {
917 [ + - ]: 51 : if( pSh->IsA( TYPE( SwCrsrShell ) ) )
918 : : bRet |= ((SwCrsrShell*)pSh)->CheckTblBoxCntnt(
919 : 51 : ((SwCrsrShell*)pSh)->pCurCrsr->GetPoint() );
920 : :
921 : 51 : } while( this != (pSh = (ViewShell *)pSh->GetNext()) );
922 : 51 : return bRet;
923 : : }
924 : :
925 : :
926 : :
927 : :
928 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|