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->GetPointNode().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()->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->GetMarkContentNode();
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
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()->Assign( *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()->Assign( *pStartNode );
321
322 // 2. set mark, and move point to last content node in box
324 m_pTableCursor->GetPoint()->Assign( *(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()->GetNode() );
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()->Assign(*pTextNode, &fnPosTable == &fnMoveBackward ?
550 pTextNode->Len() :
551 0 );
552 }
553 return true;
554 }
555 } while( true );
556
557 return false;
558}
559
560bool GotoNextTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
561 bool bInReadOnly )
562{
563 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
564
565 SwNodeIndex aIdx( rCurrentCursor.GetPoint()->GetNode() );
566 SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
567
568 if( pTableNd )
569 aIdx.Assign( *pTableNd->EndOfSectionNode(), 1 );
570
571 SwNodeIndex aOldIdx = aIdx;
572 SwNodeOffset 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 = SwNodeOffset(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()->Assign(*pTextNode, &fnPosTable == &fnMoveBackward ?
619 pTextNode->Len() :
620 0 );
621 }
622 return true;
623
624 } while( true );
625
626 // the flow is such that it is not possible to get there
627
628 return false;
629}
630
631bool GotoCurrTable( SwPaM& rCurrentCursor, SwMoveFnCollection const & fnPosTable,
632 bool bInReadOnly )
633{
634 SwTableNode* pTableNd = rCurrentCursor.GetPoint()->GetNode().FindTableNode();
635 if( !pTableNd )
636 return false;
637
638 SwTextNode* pTextNode = nullptr;
639 if( &fnPosTable == &fnMoveBackward ) // to the end of the table
640 {
641 SwNodeIndex aIdx( *pTableNd->EndOfSectionNode() );
642 if( !lcl_FindPrevCell( aIdx, bInReadOnly ))
643 return false;
644 pTextNode = aIdx.GetNode().GetTextNode();
645 }
646 else
647 {
648 SwNodeIndex aIdx( *pTableNd );
649 if( !lcl_FindNextCell( aIdx, bInReadOnly ))
650 return false;
651 pTextNode = aIdx.GetNode().GetTextNode();
652 }
653
654 if ( pTextNode )
655 {
656 rCurrentCursor.GetPoint()->Assign(*pTextNode, &fnPosTable == &fnMoveBackward ?
657 pTextNode->Len() :
658 0 );
659 }
660
661 return true;
662}
663
664bool 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
679bool 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 SwNodeOffset 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()->GetNodeIndex();
703 nPtCnt = pCursor->GetPoint()->GetContentIndex();
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()->GetNodeIndex() == nPtNd &&
717 pCursor->GetPoint()->GetContentIndex() == 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
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 pPos = m_pTableCursor->End();
767 }
768 else
769 {
770 const SwTableNode* pTableNd = IsCursorInTable();
771 if( !pTableNd )
772 return sNm;
773 pPos = GetCursor()->GetPoint();
774 }
775
776 SwContentNode* pCNd = pPos->GetNode().GetContentNode();
777 pFrame = pCNd ? pCNd->getLayoutFrame( GetLayout() ) : nullptr;
778
779 if( pFrame )
780 {
781 do {
782 pFrame = pFrame->GetUpper();
783 } while ( pFrame && !pFrame->IsCellFrame() );
784
785 if( pFrame )
786 sNm += static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetName();
787 }
788 return sNm;
789}
790
791bool SwCursorShell::GotoTable( const OUString& rName )
792{
793 SwCallLink aLk( *this ); // watch Cursor-Moves
794 bool bRet = !m_pTableCursor && m_pCurrentCursor->GotoTable( rName );
795 if( bRet )
796 {
800 }
801 return bRet;
802}
803
805{
807 return false;
808
809 // check if box content is consistent with given box format, reset if not
810 SwTableBox* pChkBox = nullptr;
811 SwStartNode* pSttNd = nullptr;
812 if( !pPos )
813 {
814 // get stored position
815 if (nullptr != (pSttNd = m_pBoxIdx->GetNode().GetStartNode()) &&
817 m_pBoxPtr == pSttNd->FindTableNode()->GetTable().
818 GetTableBox( m_pBoxIdx->GetIndex() ) )
819 pChkBox = m_pBoxPtr;
820 }
821 else
822 {
824 if( pSttNd)
825 pChkBox = pSttNd->FindTableNode()->GetTable().GetTableBox( pSttNd->GetIndex() );
826 }
827
828 // box has more than one paragraph
829 if( pChkBox && pSttNd->GetIndex() + SwNodeOffset(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()->GetNodeIndex() ))
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{
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( auto pCursorShell = dynamic_cast<SwCursorShell *>(&rSh) )
919 bRet |= pCursorShell->CheckTableBoxContent(
920 pCursorShell->m_pCurrentCursor->GetPoint() );
921
922 }
923 return bRet;
924}
925
926/* 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:59
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
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:1876
bool IsTableComplexForChart()
Definition: trvltbl.cxx:723
bool GoPrevCell()
Definition: trvltbl.cxx:101
bool EndAllTableBoxEdit()
Definition: trvltbl.cxx:913
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:494
OUString GetBoxNms() const
Definition: trvltbl.cxx:743
void ClearTableBoxContent()
Definition: trvltbl.cxx:906
void StartAction()
Definition: crsrsh.cxx:226
const SwTableNode * IsCursorInTable() const
Check if Point of current cursor is placed within a table.
Definition: crsrsh.cxx:600
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:343
bool SelTableBox()
Definition: trvltbl.cxx:286
SwTable::SearchType m_eEnhancedTableSel
Definition: crsrsh.hxx:213
bool SelTableRowOrCol(bool bRow, bool bRowSimple=false)
Definition: trvltbl.cxx:127
SwNodeIndex * m_pBoxIdx
for recognizing of the changed
Definition: crsrsh.hxx:195
bool SelTable()
Definition: trvltbl.cxx:253
bool GotoTable(const OUString &rName)
Definition: trvltbl.cxx:791
bool IsSelTableCells() const
Definition: crsrsh.hxx:834
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:679
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
SwTableBox * m_pBoxPtr
table row
Definition: crsrsh.hxx:196
bool CheckTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:804
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:243
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2771
bool IsAutoUpdateCells() const
Definition: crsrsh.hxx:839
SwShellTableCursor * m_pTableCursor
table Cursor; only in tables when the selection lays over 2 columns
Definition: crsrsh.hxx:192
@ READONLY
make visible in spite of Readonly
Definition: crsrsh.hxx:166
@ CHKRANGE
check overlapping PaMs
Definition: crsrsh.hxx:165
@ SCROLLWIN
scroll window
Definition: crsrsh.hxx:164
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:186
bool IsTableMode() const
Definition: crsrsh.hxx:668
bool GoNextCell(bool bAppendLine=true)
set cursor into next/previous cell
Definition: trvltbl.cxx:39
void SaveTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:867
sal_Int32 GetCursorRowSpanOffset() const
Definition: swcrsr.hxx:217
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:174
bool MoveTable(SwWhichTable, SwMoveFnCollection const &)
Definition: trvltbl.cxx:664
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:222
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:175
virtual bool GotoTable(const OUString &rName)
Definition: swcrsr.cxx:2250
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:150
void ChkBoxNumFormat(SwTableBox &rCurrentBox, bool bCallUpdate)
Definition: ndtbl.cxx:4035
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
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:1232
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:554
bool IsTabFrame() const
Definition: frame.hxx:1224
bool IsInTab() const
Definition: frame.hxx:961
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1639
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
bool IsVertical() const
Definition: frame.hxx:979
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset nIdx)
Definition: ndindex.hxx:114
Base class of the Writer document model elements.
Definition: node.hxx:98
SwStartNode * GetStartNode()
Definition: node.hxx:642
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:218
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:772
SwDoc & GetDoc()
Definition: node.hxx:233
bool IsStartNode() const
Definition: node.hxx:187
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
SwStartNode * FindSttNodeByType(SwStartNodeType eTyp)
Definition: node.cxx:782
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
SwContentNode * GetContentNode()
Definition: node.hxx:666
SwTableNode * GetTableNode()
Definition: node.hxx:650
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1333
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
SwNodeOffset Count() const
Definition: ndarr.hxx:142
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
SwNode & GetPointNode() const
Definition: pam.hxx:275
void Exchange()
Definition: pam.hxx:242
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:657
const SwPosition * End() const
Definition: pam.hxx:263
SwContentNode * GetMarkContentNode() const
Definition: pam.hxx:280
SwDoc & GetDoc() const
Definition: pam.hxx:291
void DeleteMark()
Definition: pam.hxx:232
const SwPosition * GetPoint() const
Definition: pam.hxx:253
const SwPosition * Start() const
Definition: pam.hxx:258
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
Point TopLeft() const
Definition: swrect.hxx:254
Point TopRight() const
Definition: swrect.hxx:258
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
SwShellCursor * GetNext()
Definition: viscrs.hxx:188
const Point & GetPtPos() const
Definition: viscrs.hxx:165
const Point & GetMkPos() const
Definition: viscrs.hxx:167
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:1133
Starts a section of nodes in the document model.
Definition: node.hxx:348
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:364
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:49
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:798
const SwTable * GetTable() const
Definition: tabfrm.hxx:162
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:443
sal_Int32 getRowSpan() const
Definition: swtable.hxx:540
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:481
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:495
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:542
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
SwTableNode * GetTableNode() const
Definition: swtable.cxx:2315
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,...
bool IsTableComplexForChart(std::u16string_view aSel) const
Definition: docchart.cxx:39
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1344
@ SEARCH_COL
Definition: swtable.hxx:148
@ SEARCH_ROW
Definition: swtable.hxx:147
bool IsNewModel() const
Definition: swtable.hxx:193
static SwSelBoxes & SelLineFromBox(const SwTableBox *pBox, SwSelBoxes &rBoxes, bool bToTop=true)
Definition: tblcpy.cxx:1017
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:291
const OUString & GetText() const
Definition: ndtxt.hxx:244
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:199
static ShellResource * GetShellRes()
Definition: viewsh.cxx:2664
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
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(157)
@ 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:1194
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1203
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:60
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
OUString aCalc_Error
Definition: shellres.hxx:41
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
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:560
bool GotoCurrTable(SwPaM &rCurrentCursor, SwMoveFnCollection const &fnPosTable, bool bInReadOnly)
Definition: trvltbl.cxx:631
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