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  else
173  {
174  const SwShellCursor *pCursor = GetCursor_();
175  const SwFrame* pStartFrame = pFrame;
176  const SwContentNode *pCNd = pCursor->GetContentNode( false );
177  std::pair<Point, bool> const tmp(pCursor->GetMkPos(), true);
178  const SwFrame* pEndFrame = pCNd
179  ? pCNd->getLayoutFrame(GetLayout(), nullptr, &tmp)
180  : nullptr;
181 
182  if ( bRow )
183  {
184  pStartFrame = lcl_FindMostUpperCellFrame( pStartFrame );
185  pEndFrame = lcl_FindMostUpperCellFrame( pEndFrame );
186  }
187 
188  if ( !pStartFrame || !pEndFrame )
189  return false;
190 
191  const bool bVert = pFrame->ImplFindTabFrame()->IsVertical();
192 
193  // If we select upwards it is sufficient to set pStt and pEnd
194  // to the first resp. last box of the selection obtained from
195  // GetTableSel. However, selecting downwards requires the frames
196  // located at the corners of the selection. This does not work
197  // for column selections in vertical tables:
198  const bool bSelectUp = ( bVert && !bRow ) ||
199  *pCursor->GetPoint() <= *pCursor->GetMark();
200  SwCellFrames aCells;
201  GetTableSel( static_cast<const SwCellFrame*>(pStartFrame),
202  static_cast<const SwCellFrame*>(pEndFrame),
203  aBoxes, bSelectUp ? nullptr : &aCells, eType );
204 
205  if( aBoxes.empty() || ( !bSelectUp && 4 != aCells.size() ) )
206  return false;
207 
208  if ( bSelectUp )
209  {
210  pStt = aBoxes[0];
211  pEnd = aBoxes.back();
212  }
213  else
214  {
215  // will become point of table cursor
216  pStt = aCells[bVert ? 0 : (bRow ? 2 : 1)]->GetTabBox();
217  // will become mark of table cursor
218  pEnd = aCells[bVert ? 3 : (bRow ? 1 : 2)]->GetTabBox();
219  }
220  }
221 
222  // if no table cursor exists, create one
223  if( !m_pTableCursor )
224  {
227  m_pCurrentCursor->SwSelPaintRects::Hide();
228  }
229 
231 
232  // set start and end of a column
233  m_pTableCursor->GetPoint()->nNode = *pEnd->GetSttNd();
238 
239  // set PtPos 'close' to the reference table, otherwise we might get problems
240  // with the repeated headlines check in UpdateCursor():
241  if ( !bRow )
242  m_pTableCursor->GetPtPos() = pMasterTabFrame->IsVertical()
243  ? pMasterTabFrame->getFrameArea().TopRight()
244  : pMasterTabFrame->getFrameArea().TopLeft();
245 
246  UpdateCursor();
247  return true;
248 }
249 
251 {
252  // check if the current cursor's SPoint/Mark are in a table
253  SwFrame *pFrame = GetCurrFrame();
254  if( !pFrame->IsInTab() )
255  return false;
256 
257  const SwTabFrame *pTableFrame = pFrame->ImplFindTabFrame();
258  const SwTabFrame* pMasterTabFrame = pTableFrame->IsFollow() ? pTableFrame->FindMaster( true ) : pTableFrame;
259  const SwTableNode* pTableNd = pTableFrame->GetTable()->GetTableNode();
260 
261  SET_CURR_SHELL( this );
262 
263  if( !m_pTableCursor )
264  {
267  m_pCurrentCursor->SwSelPaintRects::Hide();
268  }
269 
271  m_pTableCursor->GetPoint()->nNode = *pTableNd;
274  // set MkPos 'close' to the master table, otherwise we might get problems
275  // with the repeated headlines check in UpdateCursor():
276  m_pTableCursor->GetMkPos() = pMasterTabFrame->IsVertical() ? pMasterTabFrame->getFrameArea().TopRight() : pMasterTabFrame->getFrameArea().TopLeft();
277  m_pTableCursor->GetPoint()->nNode = *pTableNd->EndOfSectionNode();
279  UpdateCursor();
280  return true;
281 }
282 
284 {
285  // if we're in a table, create a table cursor, and select the cell
286  // that the current cursor's point resides in
287 
288  // search for start node of our table box. If not found, exit really
289  const SwStartNode* pStartNode =
291 
292 #if OSL_DEBUG_LEVEL > 0
293  // the old code checks whether we're in a table by asking the
294  // frame. This should yield the same result as searching for the
295  // table box start node, right?
296  SwFrame *pFrame = GetCurrFrame();
297  OSL_ENSURE( !pFrame->IsInTab() == !(pStartNode != nullptr),
298  "Schroedinger's table: We're in a box, and also we aren't." );
299 #endif
300  if( pStartNode == nullptr )
301  return false;
302 
303  SET_CURR_SHELL( this );
304 
305  // create a table cursor, if there isn't one already
306  if( !m_pTableCursor )
307  {
310  m_pCurrentCursor->SwSelPaintRects::Hide();
311  }
312 
313  // select the complete box with our shiny new m_pTableCursor
314  // 1. delete mark, and move point to first content node in box
316  *(m_pTableCursor->GetPoint()) = SwPosition( *pStartNode );
318 
319  // 2. set mark, and move point to last content node in box
321  *(m_pTableCursor->GetPoint()) = SwPosition( *(pStartNode->EndOfSectionNode()) );
323 
324  // 3. exchange
326 
327  // with some luck, UpdateCursor() will now update everything that
328  // needs updating
329  UpdateCursor();
330 
331  return true;
332 }
333 
334 // TODO: provide documentation
343 static bool lcl_FindNextCell( SwNodeIndex& rIdx, bool bInReadOnly )
344 {
345  // check protected cells
346  SwNodeIndex aTmp( rIdx, 2 ); // TableNode + StartNode
347 
348  // the resulting cell should be in that table:
349  const SwTableNode* pTableNd = rIdx.GetNode().GetTableNode();
350 
351  if ( !pTableNd )
352  {
353  OSL_FAIL( "lcl_FindNextCell not celled with table start node!" );
354  return false;
355  }
356 
357  const SwNode* pTableEndNode = pTableNd->EndOfSectionNode();
358 
359  SwNodes& rNds = aTmp.GetNode().GetNodes();
360  SwContentNode* pCNd = aTmp.GetNode().GetContentNode();
361 
362  // no content node => go to next content node
363  if( !pCNd )
364  pCNd = rNds.GoNext( &aTmp );
365 
366  // robust
367  if ( !pCNd )
368  return false;
369 
371 
372  if ( nullptr == pFrame || pCNd->FindTableNode() != pTableNd ||
373  (!bInReadOnly && pFrame->IsProtected() ) )
374  {
375  // we are not located inside a 'valid' cell. We have to continue searching...
376 
377  // skip behind current section. This might be the end of the table cell
378  // or behind an inner section or...
379  aTmp.Assign( *pCNd->EndOfSectionNode(), 1 );
380 
381  // loop to find a suitable cell...
382  for( ;; )
383  {
384  SwNode* pNd = &aTmp.GetNode();
385 
386  // we break this loop if we reached the end of the table.
387  // to make this code even more robust, we also break if we are
388  // already behind the table end node:
389  if( pNd == pTableEndNode || /*robust: */ pNd->GetIndex() > pTableEndNode->GetIndex() )
390  return false;
391 
392  // ok, get the next content node:
393  pCNd = aTmp.GetNode().GetContentNode();
394  if( nullptr == pCNd )
395  pCNd = rNds.GoNext( &aTmp );
396 
397  // robust:
398  if ( !pCNd )
399  return false;
400 
401  // check if we have found a suitable table cell:
402  pFrame = pCNd->getLayoutFrame( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() );
403 
404  if ( nullptr != pFrame && pCNd->FindTableNode() == pTableNd &&
405  (bInReadOnly || !pFrame->IsProtected() ) )
406  {
407  // finally, we have found a suitable table cell => set index and return
408  rIdx = *pCNd;
409  return true;
410  }
411 
412  // continue behind the current section:
413  aTmp.Assign( *pCNd->EndOfSectionNode(), +1 );
414  }
415  }
416  rIdx = *pCNd;
417  return true;
418 }
419 
421 static bool lcl_FindPrevCell( SwNodeIndex& rIdx, bool bInReadOnly )
422 {
423  SwNodeIndex aTmp( rIdx, -2 ); // TableNode + EndNode
424 
425  const SwNode* pTableEndNode = &rIdx.GetNode();
426  const SwTableNode* pTableNd = pTableEndNode->StartOfSectionNode()->GetTableNode();
427 
428  if ( !pTableNd )
429  {
430  OSL_FAIL( "lcl_FindPrevCell not celled with table start node!" );
431  return false;
432  }
433 
434  SwContentNode* pCNd = aTmp.GetNode().GetContentNode();
435 
436  if( !pCNd )
437  pCNd = SwNodes::GoPrevious( &aTmp );
438 
439  if ( !pCNd )
440  return false;
441 
443 
444  if( nullptr == pFrame || pCNd->FindTableNode() != pTableNd ||
445  (!bInReadOnly && pFrame->IsProtected() ))
446  {
447  // skip before current section
448  aTmp.Assign( *pCNd->StartOfSectionNode(), -1 );
449  for( ;; )
450  {
451  SwNode* pNd = &aTmp.GetNode();
452 
453  if( pNd == pTableNd || pNd->GetIndex() < pTableNd->GetIndex() )
454  return false;
455 
456  pCNd = aTmp.GetNode().GetContentNode();
457  if( nullptr == pCNd )
458  pCNd = SwNodes::GoPrevious( &aTmp );
459 
460  if ( !pCNd )
461  return false;
462 
463  pFrame = pCNd->getLayoutFrame( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() );
464 
465  if( nullptr != pFrame && pCNd->FindTableNode() == pTableNd &&
466  (bInReadOnly || !pFrame->IsProtected() ) )
467  {
468  rIdx = *pCNd;
469  return true; // ok, not protected
470  }
471  aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 );
472  }
473  }
474  rIdx = *pCNd;
475  return true;
476 }
477 
478 bool GotoPrevTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
479  bool bInReadOnly )
480 {
481  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
482 
483  SwNodeIndex aIdx( rCurrentCursor.GetPoint()->nNode );
484 
485  SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
486  if( pTableNd )
487  {
488  // #i26532#: If we are inside a table, we may not go backward to the
489  // table start node, because we would miss any tables inside this table.
490  SwTableNode* pInnerTableNd = nullptr;
491  SwNodeIndex aTmpIdx( aIdx );
492  while( aTmpIdx.GetIndex() &&
493  nullptr == ( pInnerTableNd = aTmpIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
494  --aTmpIdx;
495 
496  if( pInnerTableNd == pTableNd )
497  aIdx.Assign( *pTableNd, - 1 );
498  }
499 
500  SwNodeIndex aOldIdx = aIdx;
501  sal_uLong nLastNd = rCurrentCursor.GetDoc()->GetNodes().Count() - 1;
502  do {
503  while( aIdx.GetIndex() &&
504  nullptr == ( pTableNd = aIdx.GetNode().StartOfSectionNode()->GetTableNode()) )
505  {
506  --aIdx;
507  if ( aIdx == aOldIdx )
508  {
509  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
510  return false;
511  }
512  }
513 
514  if ( !aIdx.GetIndex() )
515  {
516  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
517  aIdx = nLastNd;
518  continue;
519  }
520 
521  {
522  if( &fnPosTable == &fnMoveForward ) // at the beginning?
523  {
524  aIdx = *aIdx.GetNode().StartOfSectionNode();
525  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
526  {
527  // skip table
528  aIdx.Assign( *pTableNd, -1 );
529  continue;
530  }
531  }
532  else
533  {
534  // check protected cells
535  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
536  {
537  // skip table
538  aIdx.Assign( *pTableNd, -1 );
539  continue;
540  }
541  }
542 
543  SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
544  if ( pTextNode )
545  {
546  rCurrentCursor.GetPoint()->nNode = *pTextNode;
547  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
548  pTextNode->Len() :
549  0 );
550  }
551  return true;
552  }
553  } while( true );
554 
555  return false;
556 }
557 
558 bool GotoNextTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
559  bool bInReadOnly )
560 {
561  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
562 
563  SwNodeIndex aIdx( rCurrentCursor.GetPoint()->nNode );
564  SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
565 
566  if( pTableNd )
567  aIdx.Assign( *pTableNd->EndOfSectionNode(), 1 );
568 
569  SwNodeIndex aOldIdx = aIdx;
570  sal_uLong nLastNd = rCurrentCursor.GetDoc()->GetNodes().Count() - 1;
571  do {
572  while( aIdx.GetIndex() < nLastNd &&
573  nullptr == ( pTableNd = aIdx.GetNode().GetTableNode()) )
574  {
575  ++aIdx;
576  if ( aIdx == aOldIdx )
577  {
578  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
579  return false;
580  }
581  }
582 
583  if ( aIdx.GetIndex() == nLastNd )
584  {
585  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
586  aIdx = 0;
587  continue;
588  }
589 
590  assert( pTableNd ); // coverity, should never be nullptr
591 
592  if( &fnPosTable == &fnMoveForward ) // at the beginning?
593  {
594  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
595  {
596  // skip table
597  aIdx.Assign( *pTableNd->EndOfSectionNode(), + 1 );
598  continue;
599  }
600  }
601  else
602  {
603  aIdx = *aIdx.GetNode().EndOfSectionNode();
604  // check protected cells
605  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
606  {
607  // skip table
608  aIdx.Assign( *pTableNd->EndOfSectionNode(), + 1 );
609  continue;
610  }
611  }
612 
613  SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
614  if ( pTextNode )
615  {
616  rCurrentCursor.GetPoint()->nNode = *pTextNode;
617  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
618  pTextNode->Len() :
619  0 );
620  }
621  return true;
622 
623  } while( true );
624 
625  // the flow is such that it is not possible to get there
626 
627  return false;
628 }
629 
630 bool GotoCurrTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
631  bool bInReadOnly )
632 {
633  SwTableNode* pTableNd = rCurrentCursor.GetPoint()->nNode.GetNode().FindTableNode();
634  if( !pTableNd )
635  return false;
636 
637  SwTextNode* pTextNode = nullptr;
638  if( &fnPosTable == &fnMoveBackward ) // to the end of the table
639  {
640  SwNodeIndex aIdx( *pTableNd->EndOfSectionNode() );
641  if( !lcl_FindPrevCell( aIdx, bInReadOnly ))
642  return false;
643  pTextNode = aIdx.GetNode().GetTextNode();
644  }
645  else
646  {
647  SwNodeIndex aIdx( *pTableNd );
648  if( !lcl_FindNextCell( aIdx, bInReadOnly ))
649  return false;
650  pTextNode = aIdx.GetNode().GetTextNode();
651  }
652 
653  if ( pTextNode )
654  {
655  rCurrentCursor.GetPoint()->nNode = *pTextNode;
656  rCurrentCursor.GetPoint()->nContent.Assign( pTextNode, &fnPosTable == &fnMoveBackward ?
657  pTextNode->Len() :
658  0 );
659  }
660 
661  return true;
662 }
663 
664 bool SwCursor::MoveTable( SwWhichTable fnWhichTable, SwMoveFnCollection const & fnPosTable )
665 {
666  bool bRet = false;
667  SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
668 
669  if( pTableCursor || !HasMark() )
670  {
671  SwCursorSaveState aSaveState( *this );
672  bRet = (*fnWhichTable)( *this, fnPosTable, IsReadOnlyAvailable() ) &&
675  }
676  return bRet;
677 }
678 
679 bool SwCursorShell::MoveTable( SwWhichTable fnWhichTable, SwMoveFnCollection const & fnPosTable )
680 {
681  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
682 
684  bool bCheckPos;
685  bool bRet;
686  sal_uLong nPtNd = 0;
687  sal_Int32 nPtCnt = 0;
688 
690  {
691  // switch to table mode
694  m_pCurrentCursor->SwSelPaintRects::Hide();
696  pCursor = m_pTableCursor;
697  bCheckPos = false;
698  }
699  else
700  {
701  bCheckPos = true;
702  nPtNd = pCursor->GetPoint()->nNode.GetIndex();
703  nPtCnt = pCursor->GetPoint()->nContent.GetIndex();
704  }
705 
706  bRet = pCursor->MoveTable( fnWhichTable, fnPosTable );
707 
708  if( bRet )
709  {
710  // #i45028# - set "top" position for repeated headline rows
711  pCursor->GetPtPos() = Point();
712 
714 
715  if( bCheckPos &&
716  pCursor->GetPoint()->nNode.GetIndex() == nPtNd &&
717  pCursor->GetPoint()->nContent.GetIndex() == nPtCnt )
718  bRet = false;
719  }
720  return bRet;
721 }
722 
724 {
725  bool bRet = false;
726 
727  // Here we may trigger table formatting so we better do that inside an action
728  StartAction();
730  if( pTNd )
731  {
732  // in a table; check if table or section is balanced
733  OUString sSel;
734  if( m_pTableCursor )
735  sSel = GetBoxNms();
736  bRet = pTNd->GetTable().IsTableComplexForChart( sSel );
737  }
738  EndAction();
739 
740  return bRet;
741 }
742 
743 OUString SwCursorShell::GetBoxNms() const
744 {
745  OUString sNm;
746  const SwPosition* pPos;
747  SwFrame* pFrame;
748 
749  if( IsTableMode() )
750  {
752  pFrame = pCNd ? pCNd->getLayoutFrame( GetLayout() ) : nullptr;
753  if( !pFrame )
754  return sNm;
755 
756  do {
757  pFrame = pFrame->GetUpper();
758  } while ( pFrame && !pFrame->IsCellFrame() );
759 
760  OSL_ENSURE( pFrame, "no frame for this box" );
761 
762  if( !pFrame )
763  return sNm;
764 
765  sNm = static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetName();
766  sNm += ":";
767  pPos = m_pTableCursor->End();
768  }
769  else
770  {
771  const SwTableNode* pTableNd = IsCursorInTable();
772  if( !pTableNd )
773  return sNm;
774  pPos = GetCursor()->GetPoint();
775  }
776 
777  SwContentNode* pCNd = pPos->nNode.GetNode().GetContentNode();
778  pFrame = pCNd ? pCNd->getLayoutFrame( GetLayout() ) : nullptr;
779 
780  if( pFrame )
781  {
782  do {
783  pFrame = pFrame->GetUpper();
784  } while ( pFrame && !pFrame->IsCellFrame() );
785 
786  if( pFrame )
787  sNm += static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetName();
788  }
789  return sNm;
790 }
791 
792 bool SwCursorShell::GotoTable( const OUString& rName )
793 {
794  SwCallLink aLk( *this ); // watch Cursor-Moves
795  bool bRet = !m_pTableCursor && m_pCurrentCursor->GotoTable( rName );
796  if( bRet )
797  {
801  }
802  return bRet;
803 }
804 
806 {
808  return false;
809 
810  // check if box content is consistent with given box format, reset if not
811  SwTableBox* pChkBox = nullptr;
812  SwStartNode* pSttNd = nullptr;
813  if( !pPos )
814  {
815  // get stored position
816  if (nullptr != (pSttNd = m_pBoxIdx->GetNode().GetStartNode()) &&
817  SwTableBoxStartNode == pSttNd->GetStartNodeType() &&
818  m_pBoxPtr == pSttNd->FindTableNode()->GetTable().
819  GetTableBox( m_pBoxIdx->GetIndex() ) )
820  pChkBox = m_pBoxPtr;
821  }
822  else if( nullptr != ( pSttNd = pPos->nNode.GetNode().
823  FindSttNodeByType( SwTableBoxStartNode )) )
824  {
825  pChkBox = pSttNd->FindTableNode()->GetTable().GetTableBox( pSttNd->GetIndex() );
826  }
827 
828  // box has more than one paragraph
829  if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() )
830  pChkBox = nullptr;
831 
832  // destroy pointer before next action starts
833  if( !pPos && !pChkBox )
835 
836  // cursor not anymore in this section?
837  if( pChkBox && !pPos &&
839  pSttNd->GetIndex() + 1 == m_pCurrentCursor->GetPoint()->nNode.GetIndex() ))
840  pChkBox = nullptr;
841 
842  // Did the content of a box change at all? This is important if e.g. Undo
843  // could not restore the content properly.
844  if( pChkBox )
845  {
846  const SwTextNode* pNd = GetDoc()->GetNodes()[
847  pSttNd->GetIndex() + 1 ]->GetTextNode();
848  if( !pNd ||
850  SfxItemState::SET == pChkBox->GetFrameFormat()->
851  GetItemState( RES_BOXATR_FORMULA )) )
852  pChkBox = nullptr;
853  }
854 
855  if( pChkBox )
856  {
857  // destroy pointer before next action starts
859  StartAction();
860  GetDoc()->ChkBoxNumFormat( *pChkBox, true );
861  EndAction();
862  }
863 
864  return nullptr != pChkBox;
865 }
866 
868 {
869  if( IsSelTableCells() || !IsAutoUpdateCells() )
870  return ;
871 
872  if( !pPos )
873  pPos = m_pCurrentCursor->GetPoint();
874 
876 
877  bool bCheckBox = false;
878  if( pSttNd && m_pBoxIdx )
879  {
880  if( pSttNd == &m_pBoxIdx->GetNode() )
881  pSttNd = nullptr;
882  else
883  bCheckBox = true;
884  }
885  else
886  bCheckBox = nullptr != m_pBoxIdx;
887 
888  if( bCheckBox )
889  {
890  // check m_pBoxIdx
891  SwPosition aPos( *m_pBoxIdx );
892  CheckTableBoxContent( &aPos );
893  }
894 
895  if( pSttNd )
896  {
897  m_pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTableBox( pSttNd->GetIndex() );
898 
899  if( m_pBoxIdx )
900  *m_pBoxIdx = *pSttNd;
901  else
902  m_pBoxIdx = new SwNodeIndex( *pSttNd );
903  }
904 }
905 
907 {
908  delete m_pBoxIdx;
909  m_pBoxIdx = nullptr;
910  m_pBoxPtr = nullptr;
911 }
912 
914 {
915  bool bRet = false;
916  for(SwViewShell& rSh : GetRingContainer())
917  {
918  if( dynamic_cast<const SwCursorShell *>(&rSh) != nullptr )
919  bRet |= static_cast<SwCursorShell*>(&rSh)->CheckTableBoxContent(
920  static_cast<SwCursorShell*>(&rSh)->m_pCurrentCursor->GetPoint() );
921 
922  }
923  return bRet;
924 }
925 
926 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwStartNode * FindSttNodeByType(SwStartNodeType eTyp)
Definition: node.cxx:755
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:901
bool GotoTable(const OUString &rName)
Definition: trvltbl.cxx:792
bool IsFollow() const
Definition: flowfrm.hxx:166
bool IsAutoUpdateCells() const
Definition: crsrsh.hxx:804
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:867
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:745
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:173
const OUString & GetText() const
Definition: ndtxt.hxx:211
virtual const SwRootFrame * GetCurrentLayout() const =0
static ShellResource * GetShellRes()
Definition: viewsh.cxx:2489
bool GotoPrevTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:478
void ClearTableBoxContent()
Definition: trvltbl.cxx:906
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:646
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:1148
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:216
bool IsTableComplexForChart(const OUString &rSel) const
Definition: docchart.cxx:47
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1290
SwNode & GetNode() const
Definition: ndindex.hxx:118
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:630
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:343
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:151
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:331
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:481
bool(* SwWhichTable)(SwPaM &, SwMoveFnCollection const &, bool bInReadOnly)
Definition: cshtyp.hxx:58
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:468
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:888
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:715
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:892
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:144
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:1029
void EndAction(const bool bIdleEnd=false, const bool DoSetPosX=false)
Definition: crsrsh.cxx:228
bool EndAllTableBoxEdit()
Definition: trvltbl.cxx:913
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
void Exchange()
Definition: pam.cxx:469
bool SelTableBox()
Definition: trvltbl.cxx:283
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:734
const Point & GetMkPos() const
Definition: viscrs.hxx:142
#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:802
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:437
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:743
void StartAction()
Definition: crsrsh.cxx:211
bool SelTable()
Definition: trvltbl.cxx:250
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:477
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:679
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
SwShellCursor * GetNext()
Definition: viscrs.hxx:163
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:140
bool CheckTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:805
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:351
Point TopRight() const
Definition: swrect.cxx:175
bool IsVertical() const
Definition: frame.hxx:949
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:664
bool IsTableComplexForChart()
Definition: trvltbl.cxx:723
bool GotoNextTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:558
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:421
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2071
OUString const aCalc_Error
Definition: shellres.hxx:40
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1273
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
void ChkBoxNumFormat(SwTableBox &rCurrentBox, bool bCallUpdate)
Definition: ndtbl.cxx:3990
#define RES_BOXATR_FORMULA
Definition: hintids.hxx:262
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
Definition: ndindex.hxx:271
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1622
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