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