LibreOffice Module sw (master)  1
trvltbl.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <hintids.hxx>
21 #include <crsrsh.hxx>
22 #include <doc.hxx>
23 #include <cntfrm.hxx>
24 #include <editsh.hxx>
25 #include <pam.hxx>
26 #include <swtable.hxx>
27 #include <frmfmt.hxx>
28 #include <viscrs.hxx>
29 #include "callnk.hxx"
30 #include <tabfrm.hxx>
31 #include <ndtxt.hxx>
32 #include <shellres.hxx>
33 #include <cellfrm.hxx>
35 #include <svx/srchdlg.hxx>
36 
38 bool SwCursorShell::GoNextCell( bool bAppendLine )
39 {
40  bool bRet = false;
41  const SwTableNode* pTableNd = nullptr;
42 
43  if( IsTableMode() || nullptr != ( pTableNd = IsCursorInTable() ))
44  {
46  SwCallLink aLk( *this ); // watch Cursor-Moves
47  bRet = true;
48 
49  // Check if we have to move the cursor to a covered cell before
50  // proceeding:
51  const SwNode* pTableBoxStartNode = pCursor->GetNode().FindTableBoxStartNode();
52  const SwTableBox* pTableBox = nullptr;
53 
54  if ( pCursor->GetCursorRowSpanOffset() )
55  {
56  pTableBox = pTableBoxStartNode->GetTableBox();
57  if ( pTableBox->getRowSpan() > 1 )
58  {
59  if ( !pTableNd )
60  pTableNd = IsCursorInTable();
61  assert (pTableNd);
62  pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
63  static_cast<sal_uInt16>(pTableBox->getRowSpan() + pCursor->GetCursorRowSpanOffset() ) );
64  pTableBoxStartNode = pTableBox->GetSttNd();
65  }
66  }
67 
68  SwNodeIndex aCellStt( *pTableBoxStartNode->EndOfSectionNode(), 1 );
69 
70  // if there is another StartNode after the EndNode of a cell then
71  // there is another cell
72  if( !aCellStt.GetNode().IsStartNode() )
73  {
74  if( pCursor->HasMark() || !bAppendLine )
75  bRet = false;
76  else if (pTableNd)
77  {
78  // if there is no list anymore then create new one
79  if ( !pTableBox )
80  pTableBox = pTableNd->GetTable().GetTableBox(
81  pCursor->GetPoint()->nNode.GetNode().
82  StartOfSectionIndex() );
83 
84  OSL_ENSURE( pTableBox, "Box is not in this table" );
85  SwSelBoxes aBoxes;
86 
87  // the document might change; w/o Action views would not be notified
88  static_cast<SwEditShell*>(this)->StartAllAction();
89  bRet = mxDoc->InsertRow( SwTable::SelLineFromBox( pTableBox, aBoxes, false ));
90  static_cast<SwEditShell*>(this)->EndAllAction();
91  }
92  }
93  bRet = bRet && pCursor->GoNextCell();
94  if( bRet )
95  UpdateCursor();
96  }
97  return bRet;
98 }
99 
101 {
102  bool bRet = false;
103  if( IsTableMode() || IsCursorInTable() )
104  {
106  SwCallLink aLk( *this ); // watch Cursor-Moves
107  bRet = pCursor->GoPrevCell();
108  if( bRet )
109  UpdateCursor(); // update current cursor
110  }
111  return bRet;
112 }
113 
114 static const SwFrame* lcl_FindMostUpperCellFrame( const SwFrame* pFrame )
115 {
116  while ( pFrame &&
117  ( !pFrame->IsCellFrame() ||
118  !pFrame->GetUpper()->GetUpper()->IsTabFrame() ||
119  pFrame->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
120  {
121  pFrame = pFrame->GetUpper();
122  }
123  return pFrame;
124 }
125 
126 bool SwCursorShell::SelTableRowOrCol( bool bRow, bool bRowSimple )
127 {
128  // check if the current cursor's SPoint/Mark are in a table
129  SwFrame *pFrame = GetCurrFrame();
130  if( !pFrame->IsInTab() )
131  return false;
132 
133  const SwTabFrame* pTabFrame = pFrame->FindTabFrame();
134  const SwTabFrame* pMasterTabFrame = pTabFrame->IsFollow() ? pTabFrame->FindMaster( true ) : pTabFrame;
135  const SwTable* pTable = pTabFrame->GetTable();
136 
137  SET_CURR_SHELL( this );
138 
139  const SwTableBox* pStt = nullptr;
140  const SwTableBox* pEnd = nullptr;
141 
142  // search box based on layout
143  SwSelBoxes aBoxes;
145  const bool bCheckProtected = !IsReadOnlyAvailable();
146 
147  if( bCheckProtected )
148  eType = static_cast<SwTableSearchType>(eType | SwTableSearchType::Protect);
149 
150  if ( !bRowSimple )
151  {
152  GetTableSel( *this, aBoxes, eType );
153 
154  if( aBoxes.empty() )
155  return false;
156 
157  pStt = aBoxes[0];
158  pEnd = aBoxes.back();
159  }
160  // #i32329# Enhanced table selection
161  else if ( pTable->IsNewModel() )
162  {
163  const SwShellCursor *pCursor = GetCursor_();
165  pTable->CreateSelection( *pCursor, aBoxes, eSearchType, bCheckProtected );
166  if( aBoxes.empty() )
167  return false;
168 
169  pStt = aBoxes[0];
170  pEnd = aBoxes.back();
171 
172  m_eEnhancedTableSel = eSearchType;
173  }
174  else
175  {
176  const SwShellCursor *pCursor = GetCursor_();
177  const SwFrame* pStartFrame = pFrame;
178  const SwContentNode *pCNd = pCursor->GetContentNode( false );
179  std::pair<Point, bool> const tmp(pCursor->GetMkPos(), true);
180  const SwFrame* pEndFrame = pCNd
181  ? pCNd->getLayoutFrame(GetLayout(), nullptr, &tmp)
182  : nullptr;
183 
184  if ( bRow )
185  {
186  pStartFrame = lcl_FindMostUpperCellFrame( pStartFrame );
187  pEndFrame = lcl_FindMostUpperCellFrame( pEndFrame );
188  }
189 
190  if ( !pStartFrame || !pEndFrame )
191  return false;
192 
193  const bool bVert = pFrame->ImplFindTabFrame()->IsVertical();
194 
195  // If we select upwards it is sufficient to set pStt and pEnd
196  // to the first resp. last box of the selection obtained from
197  // GetTableSel. However, selecting downwards requires the frames
198  // located at the corners of the selection. This does not work
199  // for column selections in vertical tables:
200  const bool bSelectUp = ( bVert && !bRow ) ||
201  *pCursor->GetPoint() <= *pCursor->GetMark();
202  SwCellFrames aCells;
203  GetTableSel( static_cast<const SwCellFrame*>(pStartFrame),
204  static_cast<const SwCellFrame*>(pEndFrame),
205  aBoxes, bSelectUp ? nullptr : &aCells, eType );
206 
207  if( aBoxes.empty() || ( !bSelectUp && 4 != aCells.size() ) )
208  return false;
209 
210  if ( bSelectUp )
211  {
212  pStt = aBoxes[0];
213  pEnd = aBoxes.back();
214  }
215  else
216  {
217  // will become point of table cursor
218  pStt = aCells[bVert ? 0 : (bRow ? 2 : 1)]->GetTabBox();
219  // will become mark of table cursor
220  pEnd = aCells[bVert ? 3 : (bRow ? 1 : 2)]->GetTabBox();
221  }
222  }
223 
224  // if no table cursor exists, create one
225  if( !m_pTableCursor )
226  {
229  m_pCurrentCursor->SwSelPaintRects::Hide();
230  }
231 
233 
234  // set start and end of a column
235  m_pTableCursor->GetPoint()->nNode = *pEnd->GetSttNd();
240 
241  // set PtPos 'close' to the reference table, otherwise we might get problems
242  // with the repeated headlines check in UpdateCursor():
243  if ( !bRow )
244  m_pTableCursor->GetPtPos() = pMasterTabFrame->IsVertical()
245  ? pMasterTabFrame->getFrameArea().TopRight()
246  : pMasterTabFrame->getFrameArea().TopLeft();
247 
248  UpdateCursor();
249  return true;
250 }
251 
253 {
254  // check if the current cursor's SPoint/Mark are in a table
255  SwFrame *pFrame = GetCurrFrame();
256  if( !pFrame->IsInTab() )
257  return false;
258 
259  const SwTabFrame *pTableFrame = pFrame->ImplFindTabFrame();
260  const SwTabFrame* pMasterTabFrame = pTableFrame->IsFollow() ? pTableFrame->FindMaster( true ) : pTableFrame;
261  const SwTableNode* pTableNd = pTableFrame->GetTable()->GetTableNode();
262 
263  SET_CURR_SHELL( this );
264 
265  if( !m_pTableCursor )
266  {
269  m_pCurrentCursor->SwSelPaintRects::Hide();
270  }
271 
273  m_pTableCursor->GetPoint()->nNode = *pTableNd;
276  // set MkPos 'close' to the master table, otherwise we might get problems
277  // with the repeated headlines check in UpdateCursor():
278  m_pTableCursor->GetMkPos() = pMasterTabFrame->IsVertical() ? pMasterTabFrame->getFrameArea().TopRight() : pMasterTabFrame->getFrameArea().TopLeft();
279  m_pTableCursor->GetPoint()->nNode = *pTableNd->EndOfSectionNode();
281  UpdateCursor();
282  return true;
283 }
284 
286 {
287  // if we're in a table, create a table cursor, and select the cell
288  // that the current cursor's point resides in
289 
290  // search for start node of our table box. If not found, exit really
291  const SwStartNode* pStartNode =
293 
294 #if OSL_DEBUG_LEVEL > 0
295  // the old code checks whether we're in a table by asking the
296  // frame. This should yield the same result as searching for the
297  // table box start node, right?
298  SwFrame *pFrame = GetCurrFrame();
299  OSL_ENSURE( !pFrame->IsInTab() == !(pStartNode != nullptr),
300  "Schroedinger's table: We're in a box, and also we aren't." );
301 #endif
302  if( pStartNode == nullptr )
303  return false;
304 
305  SET_CURR_SHELL( this );
306 
307  // create a table cursor, if there isn't one already
308  if( !m_pTableCursor )
309  {
312  m_pCurrentCursor->SwSelPaintRects::Hide();
313  }
314 
315  // select the complete box with our shiny new m_pTableCursor
316  // 1. delete mark, and move point to first content node in box
318  *(m_pTableCursor->GetPoint()) = SwPosition( *pStartNode );
320 
321  // 2. set mark, and move point to last content node in box
323  *(m_pTableCursor->GetPoint()) = SwPosition( *(pStartNode->EndOfSectionNode()) );
325 
326  // 3. exchange
328 
329  // with some luck, UpdateCursor() will now update everything that
330  // needs updating
331  UpdateCursor();
332 
333  return true;
334 }
335 
336 // TODO: provide documentation
345 static bool lcl_FindNextCell( SwNodeIndex& rIdx, bool bInReadOnly )
346 {
347  // check protected cells
348  SwNodeIndex aTmp( rIdx, 2 ); // TableNode + StartNode
349 
350  // the resulting cell should be in that table:
351  const SwTableNode* pTableNd = rIdx.GetNode().GetTableNode();
352 
353  if ( !pTableNd )
354  {
355  OSL_FAIL( "lcl_FindNextCell not celled with table start node!" );
356  return false;
357  }
358 
359  const SwNode* pTableEndNode = pTableNd->EndOfSectionNode();
360 
361  SwNodes& rNds = aTmp.GetNode().GetNodes();
362  SwContentNode* pCNd = aTmp.GetNode().GetContentNode();
363 
364  // no content node => go to next content node
365  if( !pCNd )
366  pCNd = rNds.GoNext( &aTmp );
367 
368  // robust
369  if ( !pCNd )
370  return false;
371 
373 
374  if ( nullptr == pFrame || pCNd->FindTableNode() != pTableNd ||
375  (!bInReadOnly && pFrame->IsProtected() ) )
376  {
377  // we are not located inside a 'valid' cell. We have to continue searching...
378 
379  // skip behind current section. This might be the end of the table cell
380  // or behind an inner section or...
381  aTmp.Assign( *pCNd->EndOfSectionNode(), 1 );
382 
383  // loop to find a suitable cell...
384  for( ;; )
385  {
386  SwNode* pNd = &aTmp.GetNode();
387 
388  // we break this loop if we reached the end of the table.
389  // to make this code even more robust, we also break if we are
390  // already behind the table end node:
391  if( pNd == pTableEndNode || /*robust: */ pNd->GetIndex() > pTableEndNode->GetIndex() )
392  return false;
393 
394  // ok, get the next content node:
395  pCNd = aTmp.GetNode().GetContentNode();
396  if( nullptr == pCNd )
397  pCNd = rNds.GoNext( &aTmp );
398 
399  // robust:
400  if ( !pCNd )
401  return false;
402 
403  // check if we have found a suitable table cell:
404  pFrame = pCNd->getLayoutFrame( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() );
405 
406  if ( nullptr != pFrame && pCNd->FindTableNode() == pTableNd &&
407  (bInReadOnly || !pFrame->IsProtected() ) )
408  {
409  // finally, we have found a suitable table cell => set index and return
410  rIdx = *pCNd;
411  return true;
412  }
413 
414  // continue behind the current section:
415  aTmp.Assign( *pCNd->EndOfSectionNode(), +1 );
416  }
417  }
418  rIdx = *pCNd;
419  return true;
420 }
421 
423 static bool lcl_FindPrevCell( SwNodeIndex& rIdx, bool bInReadOnly )
424 {
425  SwNodeIndex aTmp( rIdx, -2 ); // TableNode + EndNode
426 
427  const SwNode* pTableEndNode = &rIdx.GetNode();
428  const SwTableNode* pTableNd = pTableEndNode->StartOfSectionNode()->GetTableNode();
429 
430  if ( !pTableNd )
431  {
432  OSL_FAIL( "lcl_FindPrevCell not celled with table start node!" );
433  return false;
434  }
435 
436  SwContentNode* pCNd = aTmp.GetNode().GetContentNode();
437 
438  if( !pCNd )
439  pCNd = SwNodes::GoPrevious( &aTmp );
440 
441  if ( !pCNd )
442  return false;
443 
445 
446  if( nullptr == pFrame || pCNd->FindTableNode() != pTableNd ||
447  (!bInReadOnly && pFrame->IsProtected() ))
448  {
449  // skip before current section
450  aTmp.Assign( *pCNd->StartOfSectionNode(), -1 );
451  for( ;; )
452  {
453  SwNode* pNd = &aTmp.GetNode();
454 
455  if( pNd == pTableNd || pNd->GetIndex() < pTableNd->GetIndex() )
456  return false;
457 
458  pCNd = aTmp.GetNode().GetContentNode();
459  if( nullptr == pCNd )
460  pCNd = SwNodes::GoPrevious( &aTmp );
461 
462  if ( !pCNd )
463  return false;
464 
465  pFrame = pCNd->getLayoutFrame( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() );
466 
467  if( nullptr != pFrame && pCNd->FindTableNode() == pTableNd &&
468  (bInReadOnly || !pFrame->IsProtected() ) )
469  {
470  rIdx = *pCNd;
471  return true; // ok, not protected
472  }
473  aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 );
474  }
475  }
476  rIdx = *pCNd;
477  return true;
478 }
479 
480 bool GotoPrevTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
481  bool bInReadOnly )
482 {
483  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
484 
485  SwNodeIndex aIdx( rCurrentCursor.GetPoint()->nNode );
486 
487  SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
488  if( pTableNd )
489  {
490  // #i26532#: If we are inside a table, we may not go backward to the
491  // table start node, because we would miss any tables inside this table.
492  SwTableNode* pInnerTableNd = nullptr;
493  SwNodeIndex aTmpIdx( aIdx );
494  while( aTmpIdx.GetIndex() &&
495  nullptr == ( pInnerTableNd = aTmpIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
496  --aTmpIdx;
497 
498  if( pInnerTableNd == pTableNd )
499  aIdx.Assign( *pTableNd, - 1 );
500  }
501 
502  SwNodeIndex aOldIdx = aIdx;
503  sal_uLong nLastNd = rCurrentCursor.GetDoc()->GetNodes().Count() - 1;
504  do {
505  while( aIdx.GetIndex() &&
506  nullptr == ( pTableNd = aIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
507  {
508  --aIdx;
509  if ( aIdx == aOldIdx )
510  {
511  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
512  return false;
513  }
514  }
515 
516  if ( !aIdx.GetIndex() )
517  {
518  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
519  aIdx = nLastNd;
520  continue;
521  }
522 
523  {
524  if( &fnPosTable == &fnMoveForward ) // at the beginning?
525  {
526  aIdx = *aIdx.GetNode().StartOfSectionNode();
527  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
528  {
529  // skip table
530  aIdx.Assign( *pTableNd, -1 );
531  continue;
532  }
533  }
534  else
535  {
536  // check protected cells
537  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
538  {
539  // skip table
540  aIdx.Assign( *pTableNd, -1 );
541  continue;
542  }
543  }
544 
545  SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
546  if ( pTextNode )
547  {
548  rCurrentCursor.GetPoint()->nNode = *pTextNode;
549  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
550  pTextNode->Len() :
551  0 );
552  }
553  return true;
554  }
555  } while( true );
556 
557  return false;
558 }
559 
560 bool GotoNextTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
561  bool bInReadOnly )
562 {
563  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
564 
565  SwNodeIndex aIdx( rCurrentCursor.GetPoint()->nNode );
566  SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
567 
568  if( pTableNd )
569  aIdx.Assign( *pTableNd->EndOfSectionNode(), 1 );
570 
571  SwNodeIndex aOldIdx = aIdx;
572  sal_uLong nLastNd = rCurrentCursor.GetDoc()->GetNodes().Count() - 1;
573  do {
574  while( aIdx.GetIndex() < nLastNd &&
575  nullptr == ( pTableNd = aIdx.GetNode().GetTableNode()) )
576  {
577  ++aIdx;
578  if ( aIdx == aOldIdx )
579  {
580  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
581  return false;
582  }
583  }
584 
585  if ( aIdx.GetIndex() == nLastNd )
586  {
587  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
588  aIdx = 0;
589  continue;
590  }
591 
592  assert( pTableNd ); // coverity, should never be nullptr
593 
594  if( &fnPosTable == &fnMoveForward ) // at the beginning?
595  {
596  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
597  {
598  // skip table
599  aIdx.Assign( *pTableNd->EndOfSectionNode(), + 1 );
600  continue;
601  }
602  }
603  else
604  {
605  aIdx = *aIdx.GetNode().EndOfSectionNode();
606  // check protected cells
607  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
608  {
609  // skip table
610  aIdx.Assign( *pTableNd->EndOfSectionNode(), + 1 );
611  continue;
612  }
613  }
614 
615  SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
616  if ( pTextNode )
617  {
618  rCurrentCursor.GetPoint()->nNode = *pTextNode;
619  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
620  pTextNode->Len() :
621  0 );
622  }
623  return true;
624 
625  } while( true );
626 
627  // the flow is such that it is not possible to get there
628 
629  return false;
630 }
631 
632 bool GotoCurrTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
633  bool bInReadOnly )
634 {
635  SwTableNode* pTableNd = rCurrentCursor.GetPoint()->nNode.GetNode().FindTableNode();
636  if( !pTableNd )
637  return false;
638 
639  SwTextNode* pTextNode = nullptr;
640  if( &fnPosTable == &fnMoveBackward ) // to the end of the table
641  {
642  SwNodeIndex aIdx( *pTableNd->EndOfSectionNode() );
643  if( !lcl_FindPrevCell( aIdx, bInReadOnly ))
644  return false;
645  pTextNode = aIdx.GetNode().GetTextNode();
646  }
647  else
648  {
649  SwNodeIndex aIdx( *pTableNd );
650  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
651  return false;
652  pTextNode = aIdx.GetNode().GetTextNode();
653  }
654 
655  if ( pTextNode )
656  {
657  rCurrentCursor.GetPoint()->nNode = *pTextNode;
658  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
659  pTextNode->Len() :
660  0 );
661  }
662 
663  return true;
664 }
665 
666 bool SwCursor::MoveTable( SwWhichTable fnWhichTable, SwMoveFnCollection const & fnPosTable )
667 {
668  bool bRet = false;
669  SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
670 
671  if( pTableCursor || !HasMark() )
672  {
673  SwCursorSaveState aSaveState( *this );
674  bRet = (*fnWhichTable)( *this, fnPosTable, IsReadOnlyAvailable() ) &&
677  }
678  return bRet;
679 }
680 
681 bool SwCursorShell::MoveTable( SwWhichTable fnWhichTable, SwMoveFnCollection const & fnPosTable )
682 {
683  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
684 
686  bool bCheckPos;
687  bool bRet;
688  sal_uLong nPtNd = 0;
689  sal_Int32 nPtCnt = 0;
690 
692  {
693  // switch to table mode
696  m_pCurrentCursor->SwSelPaintRects::Hide();
698  pCursor = m_pTableCursor;
699  bCheckPos = false;
700  }
701  else
702  {
703  bCheckPos = true;
704  nPtNd = pCursor->GetPoint()->nNode.GetIndex();
705  nPtCnt = pCursor->GetPoint()->nContent.GetIndex();
706  }
707 
708  bRet = pCursor->MoveTable( fnWhichTable, fnPosTable );
709 
710  if( bRet )
711  {
712  // #i45028# - set "top" position for repeated headline rows
713  pCursor->GetPtPos() = Point();
714 
716 
717  if( bCheckPos &&
718  pCursor->GetPoint()->nNode.GetIndex() == nPtNd &&
719  pCursor->GetPoint()->nContent.GetIndex() == nPtCnt )
720  bRet = false;
721  }
722  return bRet;
723 }
724 
726 {
727  bool bRet = false;
728 
729  // Here we may trigger table formatting so we better do that inside an action
730  StartAction();
732  if( pTNd )
733  {
734  // in a table; check if table or section is balanced
735  OUString sSel;
736  if( m_pTableCursor )
737  sSel = GetBoxNms();
738  bRet = pTNd->GetTable().IsTableComplexForChart( sSel );
739  }
740  EndAction();
741 
742  return bRet;
743 }
744 
745 OUString SwCursorShell::GetBoxNms() const
746 {
747  OUString sNm;
748  const SwPosition* pPos;
749  SwFrame* pFrame;
750 
751  if( IsTableMode() )
752  {
754  pFrame = pCNd ? pCNd->getLayoutFrame( GetLayout() ) : nullptr;
755  if( !pFrame )
756  return sNm;
757 
758  do {
759  pFrame = pFrame->GetUpper();
760  } while ( pFrame && !pFrame->IsCellFrame() );
761 
762  OSL_ENSURE( pFrame, "no frame for this box" );
763 
764  if( !pFrame )
765  return sNm;
766 
767  sNm = static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetName() + ":";
768  pPos = m_pTableCursor->End();
769  }
770  else
771  {
772  const SwTableNode* pTableNd = IsCursorInTable();
773  if( !pTableNd )
774  return sNm;
775  pPos = GetCursor()->GetPoint();
776  }
777 
778  SwContentNode* pCNd = pPos->nNode.GetNode().GetContentNode();
779  pFrame = pCNd ? pCNd->getLayoutFrame( GetLayout() ) : nullptr;
780 
781  if( pFrame )
782  {
783  do {
784  pFrame = pFrame->GetUpper();
785  } while ( pFrame && !pFrame->IsCellFrame() );
786 
787  if( pFrame )
788  sNm += static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetName();
789  }
790  return sNm;
791 }
792 
793 bool SwCursorShell::GotoTable( const OUString& rName )
794 {
795  SwCallLink aLk( *this ); // watch Cursor-Moves
796  bool bRet = !m_pTableCursor && m_pCurrentCursor->GotoTable( rName );
797  if( bRet )
798  {
802  }
803  return bRet;
804 }
805 
807 {
809  return false;
810 
811  // check if box content is consistent with given box format, reset if not
812  SwTableBox* pChkBox = nullptr;
813  SwStartNode* pSttNd = nullptr;
814  if( !pPos )
815  {
816  // get stored position
817  if (nullptr != (pSttNd = m_pBoxIdx->GetNode().GetStartNode()) &&
818  SwTableBoxStartNode == pSttNd->GetStartNodeType() &&
819  m_pBoxPtr == pSttNd->FindTableNode()->GetTable().
820  GetTableBox( m_pBoxIdx->GetIndex() ) )
821  pChkBox = m_pBoxPtr;
822  }
823  else if( nullptr != ( pSttNd = pPos->nNode.GetNode().
824  FindSttNodeByType( SwTableBoxStartNode )) )
825  {
826  pChkBox = pSttNd->FindTableNode()->GetTable().GetTableBox( pSttNd->GetIndex() );
827  }
828 
829  // box has more than one paragraph
830  if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() )
831  pChkBox = nullptr;
832 
833  // destroy pointer before next action starts
834  if( !pPos && !pChkBox )
836 
837  // cursor not anymore in this section?
838  if( pChkBox && !pPos &&
840  pSttNd->GetIndex() + 1 == m_pCurrentCursor->GetPoint()->nNode.GetIndex() ))
841  pChkBox = nullptr;
842 
843  // Did the content of a box change at all? This is important if e.g. Undo
844  // could not restore the content properly.
845  if( pChkBox )
846  {
847  const SwTextNode* pNd = GetDoc()->GetNodes()[
848  pSttNd->GetIndex() + 1 ]->GetTextNode();
849  if( !pNd ||
851  SfxItemState::SET == pChkBox->GetFrameFormat()->
852  GetItemState( RES_BOXATR_FORMULA )) )
853  pChkBox = nullptr;
854  }
855 
856  if( pChkBox )
857  {
858  // destroy pointer before next action starts
860  StartAction();
861  GetDoc()->ChkBoxNumFormat( *pChkBox, true );
862  EndAction();
863  }
864 
865  return nullptr != pChkBox;
866 }
867 
869 {
870  if( IsSelTableCells() || !IsAutoUpdateCells() )
871  return ;
872 
873  if( !pPos )
874  pPos = m_pCurrentCursor->GetPoint();
875 
877 
878  bool bCheckBox = false;
879  if( pSttNd && m_pBoxIdx )
880  {
881  if( pSttNd == &m_pBoxIdx->GetNode() )
882  pSttNd = nullptr;
883  else
884  bCheckBox = true;
885  }
886  else
887  bCheckBox = nullptr != m_pBoxIdx;
888 
889  if( bCheckBox )
890  {
891  // check m_pBoxIdx
892  SwPosition aPos( *m_pBoxIdx );
893  CheckTableBoxContent( &aPos );
894  }
895 
896  if( pSttNd )
897  {
898  m_pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTableBox( pSttNd->GetIndex() );
899 
900  if( m_pBoxIdx )
901  *m_pBoxIdx = *pSttNd;
902  else
903  m_pBoxIdx = new SwNodeIndex( *pSttNd );
904  }
905 }
906 
908 {
909  delete m_pBoxIdx;
910  m_pBoxIdx = nullptr;
911  m_pBoxPtr = nullptr;
912 }
913 
915 {
916  bool bRet = false;
917  for(SwViewShell& rSh : GetRingContainer())
918  {
919  if( dynamic_cast<const SwCursorShell *>(&rSh) != nullptr )
920  bRet |= static_cast<SwCursorShell*>(&rSh)->CheckTableBoxContent(
921  static_cast<SwCursorShell*>(&rSh)->m_pCurrentCursor->GetPoint() );
922 
923  }
924  return bRet;
925 }
926 
927 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwStartNode * FindSttNodeByType(SwStartNodeType eTyp)
Definition: node.cxx:753
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
Base class of the Writer layout elements.
Definition: frame.hxx:295
SwTableBox * m_pBoxPtr
table row
Definition: crsrsh.hxx:189
void DeleteMark()
Definition: pam.hxx:177
void CreateSelection(const SwPaM &rPam, SwSelBoxes &rBoxes, const SearchType eSearchType, bool bProtect) const
void SwTable::CreateSelection(..) fills the selection structure with table cells for a given SwPaM...
sal_uLong GetIndex() const
Definition: node.hxx:282
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1551
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
const Value & back() const
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:179
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:905
bool GotoTable(const OUString &rName)
Definition: trvltbl.cxx:793
bool IsFollow() const
Definition: flowfrm.hxx:166
bool IsAutoUpdateCells() const
Definition: crsrsh.hxx:809
sal_uLong Count() const
Definition: ndarr.hxx:143
Marks a position in the document model.
Definition: pam.hxx:35
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:184
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1344
void SaveTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:868
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:743
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:173
const OUString & GetText() const
Definition: ndtxt.hxx:210
virtual const SwRootFrame * GetCurrentLayout() const =0
static ShellResource * GetShellRes()
Definition: viewsh.cxx:2493
bool GotoPrevTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:480
void ClearTableBoxContent()
Definition: trvltbl.cxx:907
check overlapping PaMs
Definition: crsrsh.hxx:158
const SwTable * GetTable() const
Definition: tabfrm.hxx:144
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:647
long GetCursorRowSpanOffset() const
Definition: swcrsr.hxx:215
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:284
sal_uIntPtr sal_uLong
const SwPosition * GetMark() const
Definition: pam.hxx:209
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1147
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:216
bool IsTableComplexForChart(const OUString &rSel) const
Definition: docchart.cxx:39
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1288
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool IsCellFrame() const
Definition: frame.hxx:1202
bool GoNextCell(bool bAppendLine=true)
set cursor into next/previous cell
Definition: trvltbl.cxx:38
bool GotoCurrTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:632
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
std::deque< SwCellFrame * > SwCellFrames
Definition: tblsel.hxx:41
Point TopLeft() const
Definition: swrect.cxx:174
static bool lcl_FindNextCell(SwNodeIndex &rIdx, bool bInReadOnly)
get the next non-protected cell inside a table
Definition: trvltbl.cxx:345
SwTableNode * GetTableNode()
Definition: node.hxx:599
static const SwFrame * lcl_FindMostUpperCellFrame(const SwFrame *pFrame)
Definition: trvltbl.cxx:114
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:174
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:175
bool IsInTab() const
Definition: frame.hxx:931
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
const SwTable & GetTable() const
Definition: node.hxx:497
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
SwShellTableCursor * m_pTableCursor
table Cursor; only in tables when the selection lays over 2 columns
Definition: crsrsh.hxx:185
virtual bool GotoTable(const OUString &rName)
Definition: swcrsr.cxx:2157
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:172
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:332
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:485
bool(* SwWhichTable)(SwPaM &, SwMoveFnCollection const &, bool bInReadOnly)
Definition: cshtyp.hxx:58
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:468
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:893
SwTableSearchType
Definition: tblsel.hxx:58
A helper class to save cursor state (position).
Definition: swcrsr.hxx:230
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:717
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:896
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:141
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
static SwSelBoxes & SelLineFromBox(const SwTableBox *pBox, SwSelBoxes &rBoxes, bool bToTop=true)
Definition: tblcpy.cxx:1026
void EndAction(const bool bIdleEnd=false, const bool DoSetPosX=false)
Definition: crsrsh.cxx:228
bool EndAllTableBoxEdit()
Definition: trvltbl.cxx:914
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
void Exchange()
Definition: pam.cxx:473
bool SelTableBox()
Definition: trvltbl.cxx:285
SwContentNode * GetContentNode()
Definition: node.hxx:615
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwDoc * GetDoc()
Definition: node.hxx:702
SwDoc * GetDoc() const
Definition: pam.hxx:243
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:739
const Point & GetMkPos() const
Definition: viscrs.hxx:144
#define SET_CURR_SHELL(shell)
Definition: swtypes.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
bool IsSelTableCells() const
Definition: crsrsh.hxx:804
ring_container GetRingContainer()
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:320
bool empty() const
SwStartNode * GetStartNode()
Definition: node.hxx:591
DocumentType const eType
static void SetSearchLabel(const SearchLabel &rSL)
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:404
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
const SwPosition * Start() const
Definition: pam.hxx:212
OUString GetBoxNms() const
Definition: trvltbl.cxx:745
void StartAction()
Definition: crsrsh.cxx:211
bool SelTable()
Definition: trvltbl.cxx:252
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:144
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:478
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
SwNodeIndex * m_pBoxIdx
for recognizing of the changed
Definition: crsrsh.hxx:188
bool IsTabFrame() const
Definition: frame.hxx:1194
long getRowSpan() const
Definition: swtable.cxx:102
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2426
bool GoPrevCell()
Definition: trvltbl.cxx:100
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:681
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
SwShellCursor * GetNext()
Definition: viscrs.hxx:165
sal_Int32 GetIndex() const
Definition: index.hxx:95
SwNodes & GetNodes()
Definition: doc.hxx:402
const SwPosition * End() const
Definition: pam.hxx:217
SwTableBox & FindEndOfRowSpan(const SwTable &, sal_uInt16 nMaxStep)
SwTableBox::FindEndOfRowSpan(..) returns the last overlapped cell if there is any.
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
const Point & GetPtPos() const
Definition: viscrs.hxx:142
bool CheckTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:806
scroll window
Definition: crsrsh.hxx:157
bool SelTableRowOrCol(bool bRow, bool bRowSimple=false)
Definition: trvltbl.cxx:126
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:349
Point TopRight() const
Definition: swrect.cxx:175
bool IsVertical() const
Definition: frame.hxx:949
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:666
bool IsTableComplexForChart()
Definition: trvltbl.cxx:725
bool GotoNextTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:560
make visible in spite of Readonly
Definition: crsrsh.hxx:159
bool IsNewModel() const
Definition: swtable.hxx:185
static bool lcl_FindPrevCell(SwNodeIndex &rIdx, bool bInReadOnly)
see lcl_FindNextCell()
Definition: trvltbl.cxx:423
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2075
SwTable::SearchType m_eEnhancedTableSel
Definition: crsrsh.hxx:206
OUString const aCalc_Error
Definition: shellres.hxx:40
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1271
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
void ChkBoxNumFormat(SwTableBox &rCurrentBox, bool bCallUpdate)
Definition: ndtbl.cxx:3983
#define RES_BOXATR_FORMULA
Definition: hintids.hxx:264
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
Definition: ndindex.hxx:272
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1621
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
SwTableNode * GetTableNode() const
Definition: swtable.cxx:1927
Base class of the Writer document model elements.
Definition: node.hxx:79