LibreOffice Module sw (master) 1
fetab.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 <memory>
21#include <hintids.hxx>
22
23#include <vcl/errinf.hxx>
25#include <editeng/protitem.hxx>
26#include <editeng/brushitem.hxx>
28#include <svtools/ruler.hxx>
29#include <osl/diagnose.h>
30#include <swwait.hxx>
31#include <fmtfsize.hxx>
32#include <fmtornt.hxx>
33#include <frmatr.hxx>
34#include <fesh.hxx>
35#include <wrtsh.hxx>
36#include <doc.hxx>
37#include <docsh.hxx>
38#include <IDocumentState.hxx>
40#include <cntfrm.hxx>
41#include <txtfrm.hxx>
42#include <notxtfrm.hxx>
43#include <rootfrm.hxx>
44#include <pagefrm.hxx>
45#include <tabfrm.hxx>
46#include <rowfrm.hxx>
47#include <cellfrm.hxx>
48#include <flyfrm.hxx>
49#include <swtable.hxx>
50#include <swddetbl.hxx>
51#include <ndtxt.hxx>
52#include <calc.hxx>
53#include <dialoghelp.hxx>
54#include <tabcol.hxx>
55#include <tblafmt.hxx>
56#include <cellatr.hxx>
57#include <pam.hxx>
58#include <viscrs.hxx>
59#include <tblsel.hxx>
60#include <swerror.h>
61#include <swundo.hxx>
62#include <frmtool.hxx>
63#include <fmtrowsplt.hxx>
64#include <node.hxx>
65#include <sortedobjs.hxx>
66
67using namespace ::com::sun::star;
68
69// also see swtable.cxx
70#define COLFUZZY 20L
71
72static bool IsSame( tools::Long nA, tools::Long nB ) { return std::abs(nA-nB) <= COLFUZZY; }
73
74namespace {
75
76class TableWait
77{
78 const std::unique_ptr<SwWait> m_pWait;
79 // this seems really fishy: do some locking, if an arbitrary number of lines is exceeded
80 static const size_t our_kLineLimit = 20;
81 static bool ShouldWait(size_t nCnt, SwFrame *pFrame, size_t nCnt2)
82 { return our_kLineLimit < nCnt || our_kLineLimit < nCnt2 || (pFrame && our_kLineLimit < pFrame->ImplFindTabFrame()->GetTable()->GetTabLines().size()); }
83public:
84 TableWait(size_t nCnt, SwFrame *pFrame, SwDocShell &rDocShell, size_t nCnt2 = 0)
85 : m_pWait( ShouldWait(nCnt, pFrame, nCnt2) ? std::make_unique<SwWait>( rDocShell, true ) : nullptr )
86 { }
87};
88
89}
90
92{
93 SwCursor * pSwCursor = GetCursor();
94
95 OSL_ENSURE(pSwCursor, "no SwCursor");
96
97 SwPosition aStartPos = *pSwCursor->GetPoint(), aEndPos = aStartPos;
98
99 /* Search least and greatest position in current cursor ring.
100 */
101 for(SwPaM& rTmpCursor : pSwCursor->GetRingContainer())
102 {
103 SwCursor* pTmpCursor = static_cast<SwCursor *>(&rTmpCursor);
104 const SwPosition * pPt = pTmpCursor->GetPoint(),
105 * pMk = pTmpCursor->GetMark();
106
107 if (*pPt < aStartPos)
108 aStartPos = *pPt;
109
110 if (*pPt > aEndPos)
111 aEndPos = *pPt;
112
113 if (*pMk < aStartPos)
114 aStartPos = *pMk;
115
116 if (*pMk > aEndPos)
117 aEndPos = *pMk;
118
119 }
120
121 KillPams();
122
123 /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */
124
125 /* Set cursor to end of selection to ensure IsLastCellInRow works
126 properly. */
127 {
128 SwCursor aTmpCursor( aEndPos, nullptr );
129 *pSwCursor = aTmpCursor;
130 }
131
132 /* Move the cursor out of the columns to delete and stay in the
133 same row. If the table has only one column the cursor will
134 stay in the row and the shell will take care of it. */
135 if (IsLastCellInRow())
136 {
137 /* If the cursor is in the last row of the table, first
138 try to move it to the previous cell. If that fails move
139 it to the next cell. */
140
141 {
142 SwCursor aTmpCursor( aStartPos, nullptr );
143 *pSwCursor = aTmpCursor;
144 }
145
146 if (! pSwCursor->GoPrevCell())
147 {
148 SwCursor aTmpCursor( aEndPos, nullptr );
149 *pSwCursor = aTmpCursor;
150 pSwCursor->GoNextCell();
151 }
152 }
153 else
154 {
155 /* If the cursor is not in the last row of the table, first
156 try to move it to the next cell. If that fails move it
157 to the previous cell. */
158
159 {
160 SwCursor aTmpCursor( aEndPos, nullptr );
161 *pSwCursor = aTmpCursor;
162 }
163
164 if (! pSwCursor->GoNextCell())
165 {
166 SwCursor aTmpCursor( aStartPos, nullptr );
167 *pSwCursor = aTmpCursor;
168 pSwCursor->GoPrevCell();
169 }
170 }
171}
172
173void SwFEShell::InsertRow( sal_uInt16 nCnt, bool bBehind )
174{
175 // check if Point/Mark of current cursor are in a table
176 SwFrame *pFrame = GetCurrFrame();
177 if( !pFrame || !pFrame->IsInTab() )
178 return;
179
180 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
181 {
183 DialogMask::MessageInfo | DialogMask::ButtonsOk );
184 return;
185 }
186
187 CurrShell aCurr( this );
189
190 // search boxes via the layout
191 SwSelBoxes aBoxes;
192 bool bSelectAll = StartsWith_() == StartsWith::Table && ExtendedSelectedAll();
193 if (bSelectAll)
194 {
195 // Set the end of the selection to the last paragraph of the last cell of the table.
196 SwPaM* pPaM = getShellCursor(false);
197 SwNode* pNode = pPaM->Start()->GetNode().FindTableNode()->EndOfSectionNode();
198 // pNode is the end node of the table, we want the last node before the end node of the last cell.
199 pPaM->End()->Assign( pNode->GetIndex() - 2 );
200 }
201 GetTableSel( *this, aBoxes, SwTableSearchType::Row );
202
203 TableWait aWait( nCnt, pFrame, *GetDoc()->GetDocShell(), aBoxes.size() );
204
205 if ( !aBoxes.empty() )
206 GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
207
209}
210
211void SwFEShell::InsertCol( sal_uInt16 nCnt, bool bBehind )
212{
213 // check if Point/Mark of current cursor are in a table
214 SwFrame *pFrame = GetCurrFrame();
215 if( !pFrame || !pFrame->IsInTab() )
216 return;
217
218 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
219 {
221 DialogMask::MessageInfo | DialogMask::ButtonsOk );
222 return;
223 }
224
225 CurrShell aCurr( this );
226
227 if( !CheckSplitCells( *this, nCnt + 1, SwTableSearchType::Col ) )
228 {
230 DialogMask::MessageInfo | DialogMask::ButtonsOk );
231 return;
232 }
233
235 // search boxes via the layout
236 SwSelBoxes aBoxes;
237 GetTableSel( *this, aBoxes, SwTableSearchType::Col );
238
239 TableWait aWait( nCnt, pFrame, *GetDoc()->GetDocShell(), aBoxes.size() );
240
241 if( !aBoxes.empty() )
242 GetDoc()->InsertCol( aBoxes, nCnt, bBehind );
243
245}
246
247// Determines if the current cursor is in the last row of the table.
249{
250 SwTabCols aTabCols;
251 GetTabCols( aTabCols );
252 bool bResult = false;
253
254 if (IsTableRightToLeft())
255 /* If the table is right-to-left the last row is the most left one. */
256 bResult = 0 == GetCurTabColNum();
257 else
258 /* If the table is left-to-right the last row is the most right one. */
259 bResult = aTabCols.Count() == GetCurTabColNum();
260
261 return bResult;
262}
263
265{
266 // check if Point/Mark of current cursor are in a table
267 SwFrame *pFrame = GetCurrFrame();
268 if( !pFrame || !pFrame->IsInTab() )
269 return false;
270
271 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
272 {
274 DialogMask::MessageInfo | DialogMask::ButtonsOk );
275 return false;
276 }
277
278 CurrShell aCurr( this );
280
281 // search boxes via the layout
282 bool bRet;
283 SwSelBoxes aBoxes;
285
286 // NewModel tables already ExpandColumnSelection, so don't do it here also.
287 const SwContentNode* pContentNd = getShellCursor(false)->GetPointNode().GetContentNode();
288 const SwTableNode* pTableNd = pContentNd ? pContentNd->FindTableNode() : nullptr;
289 if (pTableNd && pTableNd->GetTable().IsNewModel())
290 eSearchType = SwTableSearchType::NONE;
291
292 GetTableSel(*this, aBoxes, eSearchType);
293 if ( !aBoxes.empty() )
294 {
295 TableWait aWait( aBoxes.size(), pFrame, *GetDoc()->GetDocShell() );
296
297 // remove crsr from the deletion area.
298 // Put them behind/on the table; via the
299 // document position they will be put to the old position
300 while( !pFrame->IsCellFrame() )
301 pFrame = pFrame->GetUpper();
302
304
305 // then delete the column
309 }
310 else
311 bRet = false;
312
314 return bRet;
315}
316
318{
319 DeleteRow(true);
320}
321
322bool SwFEShell::DeleteRow(bool bCompleteTable)
323{
324 // check if Point/Mark of current cursor are in a table
325 SwFrame *pFrame = GetCurrFrame();
326 if( !pFrame || !pFrame->IsInTab() )
327 return false;
328
329 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
330 {
332 DialogMask::MessageInfo | DialogMask::ButtonsOk );
333 return false;
334 }
335
336 CurrShell aCurr( this );
337
338 bool bRecordChanges = GetDoc()->GetDocShell()->IsChangeRecording();
339 bool bRecordAndHideChanges = bRecordChanges &&
341
342 // tracked deletion: all rows have already had tracked row change in the table selection
343 if ( bRecordChanges && !SwDoc::HasRowNotTracked( *getShellCursor( false ) ) )
344 return false;
345
346 if ( bRecordChanges )
348
350
351 // tracked deletion: remove only textbox content,
352 // and set IsNoTracked table line property to false
353 if ( bRecordChanges )
354 {
355 SvxPrintItem aNotTracked(RES_PRINT, false);
356 GetDoc()->SetRowNotTracked( *getShellCursor( false ), aNotTracked );
357
358 if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
359 pWrtShell->SelectTableRow();
360
361 // don't need to remove the row frames in Show Changes mode
362 if ( !bRecordAndHideChanges )
363 {
364 if (SwEditShell* pEditShell = GetDoc()->GetEditShell())
365 pEditShell->Delete(false);
366
369
370 return true;
371 }
372 }
373
374 // search for boxes via the layout
375 bool bRet;
376 SwSelBoxes aBoxes;
377 GetTableSel( *this, aBoxes, SwTableSearchType::Row );
378
379 if( !aBoxes.empty() )
380 {
381 TableWait aWait( aBoxes.size(), pFrame, *GetDoc()->GetDocShell() );
382
383 // Delete cursors from the deletion area.
384 // Then the cursor is:
385 // 1. the following row, if there is another row after this
386 // 2. the preceding row, if there is another row before this
387 // 3. otherwise below the table
388 {
389 SwTableNode* pTableNd = pFrame->IsTextFrame()
390 ? static_cast<SwTextFrame*>(pFrame)->GetTextNodeFirst()->FindTableNode()
391 : static_cast<SwNoTextFrame*>(pFrame)->GetNode()->FindTableNode();
392
393 // search all boxes / lines
394 FndBox_ aFndBox( nullptr, nullptr );
395 {
396 FndPara aPara( aBoxes, &aFndBox );
397 ForEach_FndLineCopyCol( pTableNd->GetTable().GetTabLines(), &aPara );
398 }
399
400 if( aFndBox.GetLines().empty() )
401 {
403 return false;
404 }
405
406 KillPams();
407
408 FndBox_* pFndBox = &aFndBox;
409 while( 1 == pFndBox->GetLines().size() &&
410 1 == pFndBox->GetLines().front()->GetBoxes().size())
411 {
412 FndBox_ *const pTmp = pFndBox->GetLines().front()->GetBoxes()[0].get();
413 if( pTmp->GetBox()->GetSttNd() )
414 break; // otherwise too far
415 pFndBox = pTmp;
416 }
417
418 SwTableLine* pDelLine = pFndBox->GetLines().back()->GetLine();
419 SwTableBox* pDelBox = pDelLine->GetTabBoxes().back();
420 while( !pDelBox->GetSttNd() )
421 {
422 SwTableLine* pLn = pDelBox->GetTabLines().back();
423 pDelBox = pLn->GetTabBoxes().back();
424 }
425 SwTableBox* pNextBox = pDelLine->FindNextBox( pTableNd->GetTable(),
426 pDelBox );
427 // skip deleted lines in Hide Changes mode with enabled change tracking
428 if ( bRecordAndHideChanges )
429 {
430 SwRedlineTable::size_type nRedlinePos = 0;
431 while( pNextBox && pNextBox->GetUpper()->IsDeleted(nRedlinePos) )
432 pNextBox = pNextBox->GetUpper()->FindNextBox( pTableNd->GetTable(),
433 pNextBox->GetUpper()->GetTabBoxes().back() );
434 }
435
436 // skip protected cells
437 while( pNextBox &&
439 pNextBox = pNextBox->FindNextBox( pTableNd->GetTable(), pNextBox );
440
441 if( !pNextBox ) // no next? then the previous
442 {
443 pDelLine = pFndBox->GetLines().front()->GetLine();
444 pDelBox = pDelLine->GetTabBoxes()[ 0 ];
445 while( !pDelBox->GetSttNd() )
446 pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
447 pNextBox = pDelLine->FindPreviousBox( pTableNd->GetTable(),
448 pDelBox );
449 // skip previous deleted lines in Hide Changes mode with enabled change tracking
450 if ( bRecordAndHideChanges )
451 {
452 SwRedlineTable::size_type nRedlinePos = 0;
453 while( pNextBox && pNextBox->GetUpper()->IsDeleted(nRedlinePos) )
454 {
455 pNextBox = pNextBox->GetUpper()->FindPreviousBox( pTableNd->GetTable(),
456 pNextBox->GetUpper()->GetTabBoxes()[0] );
457 nRedlinePos = 0;
458 }
459 }
460
461 // skip previous protected cells
462 while( pNextBox &&
464 pNextBox = pNextBox->FindPreviousBox( pTableNd->GetTable(), pNextBox );
465 }
466
467 // delete row content in Hide Changes mode
468 if ( bRecordAndHideChanges )
469 {
470 SwEditShell* pEditShell = GetDoc()->GetEditShell();
471
472 // select the rows deleted with change tracking
473 if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
474 {
475 pWrtShell->SelectTableRow();
476 SwShellTableCursor* pTableCursor = GetTableCursor();
477 auto pStt = aBoxes[0];
478 auto pEnd = aBoxes.back();
479 pTableCursor->DeleteMark();
480
481 // set start and end of the selection
482 pTableCursor->GetPoint()->Assign( *pEnd->GetSttNd()->EndOfSectionNode() );
483 pTableCursor->Move( fnMoveBackward, GoInContent );
484 pTableCursor->SetMark();
485 pTableCursor->GetPoint()->Assign( *pStt->GetSttNd()->EndOfSectionNode() );
486 pTableCursor->Move( fnMoveBackward, GoInContent );
487 pWrtShell->UpdateCursor();
488 }
489
490 if (pEditShell)
491 pEditShell->Delete(false);
492 }
493
494 SwNodeOffset nIdx;
495 if( pNextBox ) // put cursor here
496 nIdx = pNextBox->GetSttIdx() + 1;
497 else // otherwise below the table
498 nIdx = pTableNd->EndOfSectionIndex() + 1;
499
500 SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx );
501 SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
502 if( !pCNd )
503 pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
504
505 // remove row frames in Hide Changes mode (and table frames, if needed)
506 if ( bRecordAndHideChanges )
507 {
508 // remove all frames of the table, and make them again without the deleted ones
509 // TODO remove only the deleted frames
510 pTableNd->DelFrames();
511 if ( !pTableNd->GetTable().IsDeleted() )
512 {
513 pTableNd->MakeOwnFrames();
514 }
515
517
518 // put cursor
519 SwPaM* pPam = GetCursor();
520 pPam->GetPoint()->Assign( *pCNd, 0 );
521 pPam->SetMark(); // both want something
522 pPam->DeleteMark();
523 if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
524 {
525 pWrtShell->UpdateCursor();
526 // tdf#150578 enable the disabled table toolbar by (zero) cursor moving
527 pWrtShell->Right( SwCursorSkipMode::Chars, false, 0, false );
528 }
529
531 return true;
532 }
533 else if( pCNd )
534 {
535 // put cursor
536 SwPaM* pPam = GetCursor();
537 pPam->GetPoint()->Assign( *pCNd, 0 );
538 pPam->SetMark(); // both want something
539 pPam->DeleteMark();
540 }
541 }
542
543 // now delete the lines
545 bRet = GetDoc()->DeleteRowCol( aBoxes );
547 }
548 else
549 bRet = false;
550
552 return bRet;
553}
554
556{
557 // check if Point/Mark of current cursor are in a table
559 if( IsTableMode() )
560 {
561 SwShellTableCursor* pTableCursor = GetTableCursor();
562 const SwTableNode* pTableNd = pTableCursor->GetPointNode().FindTableNode();
563 if( dynamic_cast< const SwDDETable* >(&pTableNd->GetTable()) != nullptr )
564 {
566 DialogMask::MessageInfo | DialogMask::ButtonsOk );
567 }
568 else
569 {
570 CurrShell aCurr( this );
572
573 TableWait aWait(pTableCursor->GetSelectedBoxesCount(), nullptr,
574 *GetDoc()->GetDocShell(),
575 pTableNd->GetTable().GetTabLines().size() );
576
577 nRet = GetDoc()->MergeTable( *pTableCursor );
578
579 KillPams();
580
582 }
583 }
584 return nRet;
585}
586
587void SwFEShell::SplitTab( bool bVert, sal_uInt16 nCnt, bool bSameHeight )
588{
589 // check if Point/Mark of current cursor are in a table
590 SwFrame *pFrame = GetCurrFrame();
591 if( !pFrame || !pFrame->IsInTab() )
592 return;
593
594 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
595 {
597 DialogMask::MessageInfo | DialogMask::ButtonsOk );
598 return;
599 }
600
601 CurrShell aCurr( this );
602
603 if( bVert && !CheckSplitCells( *this, nCnt + 1, SwTableSearchType::NONE ) )
604 {
606 DialogMask::MessageInfo | DialogMask::ButtonsOk );
607 return;
608 }
610 // search boxes via the layout
611 SwSelBoxes aBoxes;
612 GetTableSel( *this, aBoxes );
613 if( !aBoxes.empty() )
614 {
615 TableWait aWait( nCnt, pFrame, *GetDoc()->GetDocShell(), aBoxes.size() );
616
617 // now delete the columns
618 GetDoc()->SplitTable( aBoxes, bVert, nCnt, bSameHeight );
619
620 ClearFEShellTabCols(*GetDoc(), nullptr);
621 }
623}
624
625void SwFEShell::GetTabCols_(SwTabCols &rToFill, const SwFrame *pBox) const
626{
627 const SwTabFrame *pTab = pBox->FindTabFrame();
628 if (m_pColumnCache)
629 {
630 bool bDel = true;
631 if (m_pColumnCache->pLastTable == pTab->GetTable())
632 {
633 bDel = false;
634 SwRectFnSet aRectFnSet(pTab);
635
636 const SwPageFrame* pPage = pTab->FindPageFrame();
637 const sal_uLong nLeftMin = aRectFnSet.GetLeft(pTab->getFrameArea()) -
638 aRectFnSet.GetLeft(pPage->getFrameArea());
639 const sal_uLong nRightMax = aRectFnSet.GetRight(pTab->getFrameArea()) -
640 aRectFnSet.GetLeft(pPage->getFrameArea());
641
642 if (m_pColumnCache->pLastTabFrame != pTab)
643 {
644 // if TabFrame was changed, we only shift a little bit
645 // as the width is the same
646 SwRectFnSet fnRectX(m_pColumnCache->pLastTabFrame);
647 if (fnRectX.GetWidth(m_pColumnCache->pLastTabFrame->getFrameArea()) ==
648 aRectFnSet.GetWidth(pTab->getFrameArea()) )
649 {
650 m_pColumnCache->pLastCols->SetLeftMin( nLeftMin );
651
652 m_pColumnCache->pLastTabFrame = pTab;
653 }
654 else
655 bDel = true;
656 }
657
658 if ( !bDel &&
659 m_pColumnCache->pLastCols->GetLeftMin () == o3tl::narrowing<sal_uInt16>(nLeftMin) &&
660 m_pColumnCache->pLastCols->GetLeft () == o3tl::narrowing<sal_uInt16>(aRectFnSet.GetLeft(pTab->getFramePrintArea())) &&
661 m_pColumnCache->pLastCols->GetRight () == o3tl::narrowing<sal_uInt16>(aRectFnSet.GetRight(pTab->getFramePrintArea()))&&
662 m_pColumnCache->pLastCols->GetRightMax() == o3tl::narrowing<sal_uInt16>(nRightMax) - m_pColumnCache->pLastCols->GetLeftMin() )
663 {
664 if (m_pColumnCache->pLastCellFrame != pBox)
665 {
666 pTab->GetTable()->GetTabCols( *m_pColumnCache->pLastCols,
667 static_cast<const SwCellFrame*>(pBox)->GetTabBox(), true);
668 m_pColumnCache->pLastCellFrame = pBox;
669 }
670 rToFill = *m_pColumnCache->pLastCols;
671 }
672 else
673 bDel = true;
674 }
675 if ( bDel )
676 m_pColumnCache.reset();
677 }
678 if (!m_pColumnCache)
679 {
680 SwDoc::GetTabCols( rToFill, static_cast<const SwCellFrame*>(pBox) );
681
682 m_pColumnCache.reset(new SwColCache);
683 m_pColumnCache->pLastCols.reset(new SwTabCols(rToFill));
684 m_pColumnCache->pLastTable = pTab->GetTable();
685 m_pColumnCache->pLastTabFrame = pTab;
686 m_pColumnCache->pLastCellFrame = pBox;
687 }
688}
689
690void SwFEShell::GetTabRows_(SwTabCols &rToFill, const SwFrame *pBox) const
691{
692 const SwTabFrame *pTab = pBox->FindTabFrame();
693 if (m_pRowCache)
694 {
695 bool bDel = true;
696 if (m_pRowCache->pLastTable == pTab->GetTable())
697 {
698 bDel = false;
699 SwRectFnSet aRectFnSet(pTab);
700 const SwPageFrame* pPage = pTab->FindPageFrame();
701 const tools::Long nLeftMin = ( aRectFnSet.IsVert() ?
702 pTab->GetPrtLeft() - pPage->getFrameArea().Left() :
703 pTab->GetPrtTop() - pPage->getFrameArea().Top() );
704 const tools::Long nLeft = aRectFnSet.IsVert() ? LONG_MAX : 0;
705 const tools::Long nRight = aRectFnSet.GetHeight(pTab->getFramePrintArea());
706 const tools::Long nRightMax = aRectFnSet.IsVert() ? nRight : LONG_MAX;
707
708 if (m_pRowCache->pLastTabFrame != pTab || m_pRowCache->pLastCellFrame != pBox)
709 bDel = true;
710
711 if ( !bDel &&
712 m_pRowCache->pLastCols->GetLeftMin () == nLeftMin &&
713 m_pRowCache->pLastCols->GetLeft () == nLeft &&
714 m_pRowCache->pLastCols->GetRight () == nRight &&
715 m_pRowCache->pLastCols->GetRightMax() == nRightMax )
716 {
717 rToFill = *m_pRowCache->pLastCols;
718 }
719 else
720 bDel = true;
721 }
722 if ( bDel )
723 m_pRowCache.reset();
724 }
725 if (!m_pRowCache)
726 {
727 SwDoc::GetTabRows( rToFill, static_cast<const SwCellFrame*>(pBox) );
728
729 m_pRowCache.reset(new SwColCache);
730 m_pRowCache->pLastCols.reset(new SwTabCols(rToFill));
731 m_pRowCache->pLastTable = pTab->GetTable();
732 m_pRowCache->pLastTabFrame = pTab;
733 m_pRowCache->pLastCellFrame = pBox;
734 }
735}
736
737void SwFEShell::SetTabCols( const SwTabCols &rNew, bool bCurRowOnly )
738{
739 SwFrame *pBox = GetCurrFrame();
740 if( !pBox || !pBox->IsInTab() )
741 return;
742
743 CurrShell aCurr( this );
745
746 do
747 {
748 pBox = pBox->GetUpper();
749 } while (pBox && !pBox->IsCellFrame());
750
751 GetDoc()->SetTabCols( rNew, bCurRowOnly, static_cast<SwCellFrame*>(pBox) );
753}
754
755void SwFEShell::GetTabCols( SwTabCols &rToFill ) const
756{
757 const SwFrame *pFrame = GetCurrFrame();
758 if( !pFrame || !pFrame->IsInTab() )
759 return;
760 do
761 {
762 pFrame = pFrame->GetUpper();
763 }
764 while (pFrame && !pFrame->IsCellFrame());
765
766 if (!pFrame)
767 return;
768
769 GetTabCols_( rToFill, pFrame );
770}
771
772void SwFEShell::GetTabRows( SwTabCols &rToFill ) const
773{
774 const SwFrame *pFrame = GetCurrFrame();
775 if( !pFrame || !pFrame->IsInTab() )
776 return;
777 do
778 {
779 pFrame = pFrame->GetUpper();
780 } while (pFrame && !pFrame->IsCellFrame());
781
782 if (!pFrame)
783 return;
784
785 GetTabRows_( rToFill, pFrame );
786}
787
788void SwFEShell::SetTabRows( const SwTabCols &rNew, bool bCurColOnly )
789{
790 SwFrame *pBox = GetCurrFrame();
791 if( !pBox || !pBox->IsInTab() )
792 return;
793
794 CurrShell aCurr( this );
796
797 do
798 {
799 pBox = pBox->GetUpper();
800 } while (pBox && !pBox->IsCellFrame());
801
802 GetDoc()->SetTabRows( rNew, bCurColOnly, static_cast<SwCellFrame*>(pBox) );
804}
805
806void SwFEShell::GetMouseTabRows( SwTabCols &rToFill, const Point &rPt ) const
807{
808 const SwFrame *pBox = GetBox( rPt );
809 if ( pBox )
810 GetTabRows_( rToFill, pBox );
811}
812
813void SwFEShell::SetMouseTabRows( const SwTabCols &rNew, bool bCurColOnly, const Point &rPt )
814{
815 const SwFrame *pBox = GetBox( rPt );
816 if( pBox )
817 {
818 CurrShell aCurr( this );
820 GetDoc()->SetTabRows( rNew, bCurColOnly, static_cast<const SwCellFrame*>(pBox) );
822 }
823}
824
826{
827 CurrShell aCurr( this );
829 GetDoc()->SetRowSplit( *getShellCursor( false ), rNew );
831}
832
833std::unique_ptr<SwFormatRowSplit> SwFEShell::GetRowSplit() const
834{
835 return SwDoc::GetRowSplit( *getShellCursor( false ) );
836}
837
839{
840 CurrShell aCurr( this );
842 GetDoc()->SetRowHeight( *getShellCursor( false ), rNew );
844}
845
846std::unique_ptr<SwFormatFrameSize> SwFEShell::GetRowHeight() const
847{
848 return SwDoc::GetRowHeight( *getShellCursor( false ) );
849}
850
851bool SwFEShell::BalanceRowHeight( bool bTstOnly, const bool bOptimize )
852{
853 CurrShell aCurr( this );
854 if( !bTstOnly )
856 bool bRet = GetDoc()->BalanceRowHeight( *getShellCursor( false ), bTstOnly, bOptimize );
857 if( !bTstOnly )
859 return bRet;
860}
861
863{
864 CurrShell aCurr( this );
866 GetDoc()->SetRowBackground( *getShellCursor( false ), rNew );
868}
869
870bool SwFEShell::GetRowBackground( std::unique_ptr<SvxBrushItem>& rToFill ) const
871{
872 return SwDoc::GetRowBackground( *getShellCursor( false ), rToFill );
873}
874
876{
877 CurrShell aCurr( this );
879 GetDoc()->SetTabBorders( *getShellCursor( false ), rSet );
881}
882
883void SwFEShell::SetTabLineStyle( const Color* pColor, bool bSetLine,
884 const editeng::SvxBorderLine* pBorderLine )
885{
886 CurrShell aCurr( this );
889 pColor, bSetLine, pBorderLine );
891}
892
894{
896}
897
899{
900 CurrShell aCurr( this );
902 GetDoc()->SetBoxAttr( *getShellCursor( false ), rNew );
904}
905
906bool SwFEShell::GetBoxBackground( std::unique_ptr<SvxBrushItem>& rToFill ) const
907{
908 std::unique_ptr<SfxPoolItem> aTemp = std::move(rToFill);
909 bool bRetval(SwDoc::GetBoxAttr(*getShellCursor( false ), aTemp));
910 rToFill.reset(static_cast<SvxBrushItem*>(aTemp.release()));
911 return bRetval;
912}
913
915{
916 CurrShell aCurr( this );
918 GetDoc()->SetBoxAttr( *getShellCursor( false ), rNew );
920}
921
922bool SwFEShell::GetBoxDirection( std::unique_ptr<SvxFrameDirectionItem>& rToFill ) const
923{
924 std::unique_ptr<SfxPoolItem> aTemp = std::move(rToFill);
925 bool bRetval(SwDoc::GetBoxAttr(*getShellCursor( false ), aTemp));
926 rToFill.reset(static_cast<SvxFrameDirectionItem*>(aTemp.release()));
927 return bRetval;
928}
929
930void SwFEShell::SetBoxAlign( sal_uInt16 nAlign )
931{
932 CurrShell aCurr( this );
934 GetDoc()->SetBoxAlign( *getShellCursor( false ), nAlign );
936}
937
938sal_uInt16 SwFEShell::GetBoxAlign() const
939{
940 return SwDoc::GetBoxAlign( *getShellCursor( false ) );
941}
942
944{
945 SwFrame *pFrame = GetCurrFrame();
946 if( !pFrame || !pFrame->IsInTab() )
947 return;
948
949 CurrShell aCurr( this );
951 GetDoc()->SetAttr( rNew, *pFrame->ImplFindTabFrame()->GetFormat() );
952 EndAllAction(); // no call, nothing changes!
954}
955
956void SwFEShell::GetTabBackground( std::unique_ptr<SvxBrushItem>& rToFill ) const
957{
958 SwFrame *pFrame = GetCurrFrame();
959 if( pFrame && pFrame->IsInTab() )
960 rToFill = pFrame->ImplFindTabFrame()->GetFormat()->makeBackgroundBrushItem();
961}
962
964{
965 // whole table selected?
966 if ( IsTableMode() )
967 {
968 SwSelBoxes aBoxes;
969 ::GetTableSelCrs( *this, aBoxes );
970 if( !aBoxes.empty() )
971 {
972 const SwTableNode *pTableNd = IsCursorInTable();
973 return pTableNd &&
974 aBoxes[0]->GetSttIdx() - 1 == pTableNd->EndOfSectionNode()->StartOfSectionIndex() &&
975 aBoxes.back()->GetSttNd()->EndOfSectionIndex() + 1 == pTableNd->EndOfSectionIndex();
976 }
977 }
978 return false;
979}
980
982{
983 if(!IsCursorInTable())
984 return false;
985 // whole table selected?
986 if( IsTableMode() )
987 return true;
988 SwPaM* pPam = GetCursor();
989 // empty boxes are also selected as the absence of selection
990 bool bChg = false;
991 if( pPam->GetPoint() == pPam->End())
992 {
993 bChg = true;
994 pPam->Exchange();
995 }
996 SwNode* pNd;
997 if( pPam->GetPoint()->GetNodeIndex() -1 ==
998 ( pNd = &pPam->GetPointNode())->StartOfSectionIndex() &&
999 !pPam->GetPoint()->GetContentIndex() &&
1000 pPam->GetMark()->GetNodeIndex() + 1 ==
1001 pNd->EndOfSectionIndex())
1002 {
1003 SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 );
1004 SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
1005 if( !pCNd )
1006 {
1007 pCNd = SwNodes::GoPrevious( &aIdx );
1008 assert(pCNd && "no ContentNode in box ??");
1009 }
1010 if( pPam->GetMark()->GetContentIndex() == pCNd->Len() )
1011 {
1012 if( bChg )
1013 pPam->Exchange();
1014 return true;
1015 }
1016 }
1017 if( bChg )
1018 pPam->Exchange();
1019 return false;
1020}
1021
1023{
1024 SvxProtectItem aProt( RES_PROTECT );
1025 aProt.SetContentProtect( true );
1026
1027 CurrShell aCurr( this );
1029
1030 GetDoc()->SetBoxAttr( *getShellCursor( false ), aProt );
1031
1032 if( !IsCursorReadonly() )
1033 {
1034 if( IsTableMode() )
1035 ClearMark();
1037 }
1039}
1040
1041// cancel table selection
1043{
1044 CurrShell aCurr( this );
1046
1047 SwSelBoxes aBoxes;
1048 if( IsTableMode() )
1049 ::GetTableSelCrs( *this, aBoxes );
1050 else
1051 {
1052 SwFrame *pFrame = GetCurrFrame();
1053 do {
1054 pFrame = pFrame->GetUpper();
1055 } while ( pFrame && !pFrame->IsCellFrame() );
1056 if( pFrame )
1057 {
1058 SwTableBox *pBox = const_cast<SwTableBox*>(static_cast<SwCellFrame*>(pFrame)->GetTabBox());
1059 aBoxes.insert( pBox );
1060 }
1061 }
1062
1063 if( !aBoxes.empty() )
1064 GetDoc()->UnProtectCells( aBoxes );
1065
1067}
1068
1070{
1071 CurrShell aCurr( this );
1075}
1076
1077bool SwFEShell::HasTableAnyProtection( const OUString* pTableName,
1078 bool* pFullTableProtection )
1079{
1080 return GetDoc()->HasTableAnyProtection( GetCursor()->GetPoint(), pTableName,
1081 pFullTableProtection );
1082}
1083
1085{
1086 bool bUnProtectAvailable = false;
1087 const SwTableNode *pTableNd = IsCursorInTable();
1088 if( pTableNd && !pTableNd->IsProtect() )
1089 {
1090 SwSelBoxes aBoxes;
1091 if( IsTableMode() )
1092 ::GetTableSelCrs( *this, aBoxes );
1093 else
1094 {
1095 SwFrame *pFrame = GetCurrFrame();
1096 do {
1097 pFrame = pFrame->GetUpper();
1098 } while ( pFrame && !pFrame->IsCellFrame() );
1099 if( pFrame )
1100 {
1101 SwTableBox *pBox = const_cast<SwTableBox*>(static_cast<SwCellFrame*>(pFrame)->GetTabBox());
1102 aBoxes.insert( pBox );
1103 }
1104 }
1105 if( !aBoxes.empty() )
1106 bUnProtectAvailable = ::HasProtectedCells( aBoxes );
1107 }
1108 return bUnProtectAvailable;
1109}
1110
1112{
1113 const SwFrame *pFrame = GetCurrFrame();
1114 const SwTabFrame *pTab = pFrame ? pFrame->FindTabFrame() : nullptr;
1115 if( pTab )
1116 return pTab->GetTable()->GetRowsToRepeat();
1117 return 0;
1118}
1119
1120void SwFEShell::SetRowsToRepeat( sal_uInt16 nSet )
1121{
1122 SwFrame *pFrame = GetCurrFrame();
1123 SwTabFrame *pTab = pFrame ? pFrame->FindTabFrame() : nullptr;
1124 if( pTab && pTab->GetTable()->GetRowsToRepeat() != nSet )
1125 {
1126 SwWait aWait( *GetDoc()->GetDocShell(), true );
1127 CurrShell aCurr( this );
1129 GetDoc()->SetRowsToRepeat( *pTab->GetTable(), nSet );
1131 }
1132}
1133
1134// returns the number of rows consecutively selected from top
1135static sal_uInt16 lcl_GetRowNumber( const SwPosition& rPos )
1136{
1137 Point aTmpPt;
1138 const SwContentNode *pNd;
1139 const SwContentFrame *pFrame;
1140
1141 std::pair<Point, bool> const tmp(aTmpPt, false);
1142 pNd = rPos.GetNode().GetContentNode();
1143 if( nullptr != pNd )
1144 pFrame = pNd->getLayoutFrame(pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), &rPos, &tmp);
1145 else
1146 pFrame = nullptr;
1147
1148 const SwFrame* pRow = (pFrame && pFrame->IsInTab()) ? pFrame->GetUpper() : nullptr;
1149
1150 while (pRow && (!pRow->GetUpper() || !pRow->GetUpper()->IsTabFrame()))
1151 pRow = pRow->GetUpper();
1152
1153 if (!pRow)
1154 return USHRT_MAX;
1155
1156 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pRow->GetUpper());
1157 const SwTableLine* pTabLine = static_cast<const SwRowFrame*>(pRow)->GetTabLine();
1158 sal_uInt16 nRet = USHRT_MAX;
1159 sal_uInt16 nI = 0;
1160 while ( sal::static_int_cast<SwTableLines::size_type>(nI) < pTabFrame->GetTable()->GetTabLines().size() )
1161 {
1162 if ( pTabFrame->GetTable()->GetTabLines()[ nI ] == pTabLine )
1163 {
1164 nRet = nI;
1165 break;
1166 }
1167 ++nI;
1168 }
1169
1170 return nRet;
1171}
1172
1174{
1175 sal_uInt16 nRet = 0;
1176 const SwPaM* pPaM = IsTableMode() ? GetTableCursor() : GetCursor_();
1177 const sal_uInt16 nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() );
1178
1179 if ( !IsTableMode() )
1180 {
1181 nRet = 0 == nPtLine ? 1 : 0;
1182 }
1183 else
1184 {
1185 const sal_uInt16 nMkLine = lcl_GetRowNumber( *pPaM->GetMark() );
1186
1187 if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) ||
1188 ( nMkLine == 0 && nPtLine != USHRT_MAX ) )
1189 {
1190 nRet = std::max( nPtLine, nMkLine ) + 1;
1191 }
1192 }
1193
1194 return nRet;
1195}
1196
1197/*
1198 * 1. case: bRepeat = true
1199 * returns true if the current frame is located inside a table headline in
1200 * a follow frame
1201 *
1202 * 2. case: bRepeat = false
1203 * returns true if the current frame is located inside a table headline OR
1204 * inside the first line of a table!!!
1205 */
1206bool SwFEShell::CheckHeadline( bool bRepeat ) const
1207{
1208 bool bRet = false;
1209 if ( !IsTableMode() )
1210 {
1211 SwFrame *pFrame = GetCurrFrame(); // DONE MULTIIHEADER
1212 SwTabFrame* pTab = (pFrame && pFrame->IsInTab()) ? pFrame->FindTabFrame() : nullptr;
1213 if (pTab)
1214 {
1215 if ( bRepeat )
1216 {
1217 bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrame );
1218 }
1219 else
1220 {
1221 bRet = static_cast<SwLayoutFrame*>(pTab->Lower())->IsAnLower( pFrame ) ||
1222 pTab->IsInHeadline( *pFrame );
1223 }
1224 }
1225 }
1226 return bRet;
1227}
1228
1229void SwFEShell::AdjustCellWidth( const bool bBalance, const bool bNoShrink )
1230{
1231 CurrShell aCurr( this );
1233
1234 // switch on wait-cursor, as we do not know how
1235 // much content is affected
1236 TableWait aWait(std::numeric_limits<size_t>::max(), nullptr,
1237 *GetDoc()->GetDocShell());
1238
1239 GetDoc()->AdjustCellWidth( *getShellCursor( false ), bBalance, bNoShrink );
1241}
1242
1243bool SwFEShell::IsAdjustCellWidthAllowed( bool bBalance ) const
1244{
1245 // at least one row with content should be contained in the selection
1246
1247 SwFrame *pFrame = GetCurrFrame();
1248 if( !pFrame || !pFrame->IsInTab() )
1249 return false;
1250
1251 SwSelBoxes aBoxes;
1252 ::GetTableSelCrs( *this, aBoxes );
1253
1254 if ( bBalance )
1255 return aBoxes.size() > 1;
1256
1257 if ( aBoxes.empty() )
1258 {
1259 do
1260 {
1261 pFrame = pFrame->GetUpper();
1262 }
1263 while (pFrame && !pFrame->IsCellFrame());
1264
1265 if (!pFrame)
1266 return false;
1267
1268 SwTableBox *pBox = const_cast<SwTableBox*>(static_cast<SwCellFrame*>(pFrame)->GetTabBox());
1269 aBoxes.insert( pBox );
1270 }
1271
1272 for (size_t i = 0; i < aBoxes.size(); ++i)
1273 {
1274 SwTableBox *pBox = aBoxes[i];
1275 if ( pBox->GetSttNd() )
1276 {
1277 SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
1278 SwTextNode* pCNd = aIdx.GetNode().GetTextNode();
1279 if( !pCNd )
1280 pCNd = static_cast<SwTextNode*>(GetDoc()->GetNodes().GoNext( &aIdx ));
1281
1282 while ( pCNd )
1283 {
1284 if (!pCNd->GetText().isEmpty())
1285 return true;
1286 ++aIdx;
1287 pCNd = aIdx.GetNode().GetTextNode();
1288 }
1289 }
1290 }
1291 return false;
1292}
1293
1294void SwFEShell::SetTableStyle(const OUString& rStyleName)
1295{
1296 // make sure SwDoc has the style
1297 SwTableAutoFormat *pTableFormat = GetDoc()->GetTableStyles().FindAutoFormat(rStyleName);
1298 if (!pTableFormat)
1299 return;
1300
1301 SwTableNode *pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1302 if (!pTableNode)
1303 return;
1304
1305 // set the name & update
1306 UpdateTableStyleFormatting(pTableNode, false, &rStyleName);
1307}
1308
1309 // AutoFormat for the table/table selection
1311{
1312 // make sure SwDoc has the style
1313 GetDoc()->GetTableStyles().AddAutoFormat(rStyle);
1314
1315 SwTableNode *pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1316 if (!pTableNode)
1317 return false;
1318
1319 // set the name & update
1320 return UpdateTableStyleFormatting(pTableNode, false, &rStyle.GetName());
1321}
1322
1324 bool bResetDirect, OUString const*const pStyleName)
1325{
1326 if (!pTableNode)
1327 {
1328 pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1329 if (!pTableNode || pTableNode->GetTable().IsTableComplex())
1330 return false;
1331 }
1332
1333 OUString const aTableStyleName(pStyleName
1334 ? *pStyleName
1335 : pTableNode->GetTable().GetTableStyleName());
1336 SwTableAutoFormat* pTableStyle = GetDoc()->GetTableStyles().FindAutoFormat(aTableStyleName);
1337 if (!pTableStyle)
1338 return false;
1339
1340 SwSelBoxes aBoxes;
1341
1342 // whole table or only current selection
1343 if( IsTableMode() )
1344 ::GetTableSelCrs( *this, aBoxes );
1345 else
1346 {
1347 const SwTableSortBoxes& rTBoxes = pTableNode->GetTable().GetTabSortBoxes();
1348 for (size_t n = 0; n < rTBoxes.size(); ++n)
1349 {
1350 SwTableBox* pBox = rTBoxes[ n ];
1351 aBoxes.insert( pBox );
1352 }
1353 }
1354
1355 bool bRet;
1356 if( !aBoxes.empty() )
1357 {
1358 CurrShell aCurr( this );
1360 bRet = GetDoc()->SetTableAutoFormat(
1361 aBoxes, *pTableStyle, bResetDirect, pStyleName != nullptr);
1362 ClearFEShellTabCols(*GetDoc(), nullptr);
1364 }
1365 else
1366 bRet = false;
1367 return bRet;
1368}
1369
1371{
1372 const SwTableNode *pTableNd = IsCursorInTable();
1373 if( !pTableNd || pTableNd->GetTable().IsTableComplex() )
1374 return false;
1375
1376 SwSelBoxes aBoxes;
1377
1378 if ( !IsTableMode() ) // if cursor are not current
1379 GetCursor();
1380
1381 // whole table or only current selection
1382 if( IsTableMode() )
1383 ::GetTableSelCrs( *this, aBoxes );
1384 else
1385 {
1386 const SwTableSortBoxes& rTBoxes = pTableNd->GetTable().GetTabSortBoxes();
1387 for (size_t n = 0; n < rTBoxes.size(); ++n)
1388 {
1389 SwTableBox* pBox = rTBoxes[ n ];
1390 aBoxes.insert( pBox );
1391 }
1392 }
1393
1394 return GetDoc()->GetTableAutoFormat( aBoxes, rGet );
1395}
1396
1398{
1399 // check if SPoint/Mark of current cursor are in a table
1400 SwFrame *pFrame = GetCurrFrame();
1401 if( !pFrame || !pFrame->IsInTab() )
1402 return false;
1403
1404 if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
1405 {
1407 DialogMask::MessageInfo | DialogMask::ButtonsOk );
1408 return false;
1409 }
1410
1411 CurrShell aCurr( this );
1413
1414 // search boxes via the layout
1415 bool bRet;
1416 SwSelBoxes aBoxes;
1417 GetTableSelCrs( *this, aBoxes );
1418 if( !aBoxes.empty() )
1419 {
1420 TableWait aWait( aBoxes.size(), pFrame, *GetDoc()->GetDocShell() );
1421
1422 // cursor should be removed from deletion area.
1423 // Put them behind/on the table; via the document
1424 // position they'll be set to the old position
1425 while( !pFrame->IsCellFrame() )
1426 pFrame = pFrame->GetUpper();
1427 ParkCursor( *static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetSttNd() );
1428
1429 bRet = GetDoc()->DeleteRowCol( aBoxes );
1430
1431 ClearFEShellTabCols(*GetDoc(), nullptr);
1432 }
1433 else
1434 bRet = false;
1436 return bRet;
1437}
1438
1440{
1442 SwFrame *pFrame = GetCurrFrame();
1443 OSL_ENSURE( pFrame, "Cursor parked?" );
1444
1445 // check if SPoint/Mark of current cursor are in a table
1446 if (!pFrame || !pFrame->IsInTab())
1447 return 0;
1448
1449 do
1450 {
1451 // JP 26.09.95: why compare with ContentFrame
1452 // and not with CellFrame ????
1453 pFrame = pFrame->GetUpper();
1454 } while (pFrame && !pFrame->IsCellFrame());
1455
1456 if (!pFrame)
1457 return 0;
1458
1459 size_t nRet = 0;
1460
1461 SwRectFnSet aRectFnSet(pFrame);
1462
1463 const SwPageFrame* pPage = pFrame->FindPageFrame();
1464
1465 // get TabCols, as only via these we get to the position
1466 SwTabCols aTabCols;
1467 GetTabCols( aTabCols );
1468
1469 if( pFrame->FindTabFrame()->IsRightToLeft() )
1470 {
1471 tools::Long nX = aRectFnSet.GetRight(pFrame->getFrameArea()) - aRectFnSet.GetLeft(pPage->getFrameArea());
1472
1473 const tools::Long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();
1474
1475 if ( !::IsSame( nX, nRight ) )
1476 {
1477 nX = nRight - nX + aTabCols.GetLeft();
1478 for ( size_t i = 0; i < aTabCols.Count(); ++i )
1479 if ( ::IsSame( nX, aTabCols[i] ) )
1480 {
1481 nRet = i + 1;
1482 break;
1483 }
1484 }
1485 }
1486 else
1487 {
1488 const tools::Long nX = aRectFnSet.GetLeft(pFrame->getFrameArea()) -
1489 aRectFnSet.GetLeft(pPage->getFrameArea());
1490
1491 const tools::Long nLeft = aTabCols.GetLeftMin();
1492
1493 if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
1494 {
1495 for ( size_t i = 0; i < aTabCols.Count(); ++i )
1496 if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
1497 {
1498 nRet = i + 1;
1499 break;
1500 }
1501 }
1502 }
1503 return nRet;
1504}
1505
1506static const SwFrame *lcl_FindFrameInTab( const SwLayoutFrame *pLay, const Point &rPt, SwTwips nFuzzy )
1507{
1508 const SwFrame *pFrame = pLay->Lower();
1509
1510 while( pFrame && pLay->IsAnLower( pFrame ) )
1511 {
1512 if ( pFrame->getFrameArea().IsNear( rPt, nFuzzy ) )
1513 {
1514 if ( pFrame->IsLayoutFrame() )
1515 {
1516 const SwFrame *pTmp = ::lcl_FindFrameInTab( static_cast<const SwLayoutFrame*>(pFrame), rPt, nFuzzy );
1517 if ( pTmp )
1518 return pTmp;
1519 }
1520
1521 return pFrame;
1522 }
1523
1524 pFrame = pFrame->FindNext();
1525 }
1526
1527 return nullptr;
1528}
1529
1530static const SwCellFrame *lcl_FindFrame( const SwLayoutFrame *pLay, const Point &rPt,
1531 SwTwips nFuzzy, bool* pbRow, bool* pbCol )
1532{
1533 // bMouseMoveRowCols :
1534 // Method is called for
1535 // - Moving columns/rows with the mouse or
1536 // - Enhanced table selection
1537 const bool bMouseMoveRowCols = nullptr == pbCol;
1538
1539 bool bCloseToRow = false;
1540 bool bCloseToCol = false;
1541
1542 const SwFrame *pFrame = pLay->ContainsContent();
1543 const SwFrame* pRet = nullptr;
1544
1545 if ( pFrame )
1546 {
1547 do
1548 {
1549 if ( pFrame->IsInTab() )
1550 pFrame = const_cast<SwFrame*>(pFrame)->ImplFindTabFrame();
1551
1552 if (!pFrame)
1553 break;
1554
1555 if ( pFrame->IsTabFrame() )
1556 {
1557 Point aPt( rPt );
1558 bool bSearchForFrameInTab = true;
1559 SwTwips nTmpFuzzy = nFuzzy;
1560
1561 if ( !bMouseMoveRowCols )
1562 {
1563 // We ignore nested tables for the enhanced table selection:
1564 while ( pFrame->GetUpper()->IsInTab() )
1565 pFrame = pFrame->GetUpper()->FindTabFrame();
1566
1567 // We first check if the given point is 'close' to the left or top
1568 // border of the table frame:
1569 OSL_ENSURE( pFrame, "Nested table frame without outer table" );
1570 SwRectFnSet aRectFnSet(pFrame);
1571 const bool bRTL = pFrame->IsRightToLeft();
1572
1573 SwRect aTabRect = pFrame->getFramePrintArea();
1574 aTabRect.Pos() += pFrame->getFrameArea().Pos();
1575
1576 const SwTwips nLeft = bRTL ?
1577 aRectFnSet.GetRight(aTabRect) :
1578 aRectFnSet.GetLeft(aTabRect);
1579 const SwTwips nTop = aRectFnSet.GetTop(aTabRect);
1580
1581 SwTwips const rPointX = aRectFnSet.IsVert() ? aPt.Y() : aPt.X();
1582 SwTwips const rPointY = aRectFnSet.IsVert() ? aPt.X() : aPt.Y();
1583
1584 const SwTwips nXDiff = aRectFnSet.XDiff( nLeft, rPointX ) * ( bRTL ? -1 : 1 );
1585 const SwTwips nYDiff = aRectFnSet.YDiff( nTop, rPointY );
1586
1587 bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy;
1588 bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy;
1589
1590 if ( bCloseToCol && 2 * nYDiff > nFuzzy )
1591 {
1592 const SwFrame* pPrev = pFrame->GetPrev();
1593 if ( pPrev )
1594 {
1595 SwRect aPrevRect = pPrev->getFramePrintArea();
1596 aPrevRect.Pos() += pPrev->getFrameArea().Pos();
1597
1598 if( aPrevRect.Contains( rPt ) )
1599 {
1600 bCloseToCol = false;
1601 }
1602 }
1603
1604 }
1605
1606 // If we found the point to be 'close' to the left or top border
1607 // of the table frame, we adjust the point to be on that border:
1608 if ( bCloseToRow && bCloseToCol )
1609 aPt = bRTL ? aTabRect.TopRight() : aRectFnSet.GetPos(aTabRect);
1610 else if ( bCloseToRow )
1611 aRectFnSet.IsVert() ? aPt.setY(nLeft) : aPt.setX(nLeft);
1612 else if ( bCloseToCol )
1613 aRectFnSet.IsVert() ? aPt.setX(nTop) : aPt.setY(nTop);
1614
1615 if ( !bCloseToRow && !bCloseToCol )
1616 bSearchForFrameInTab = false;
1617
1618 // Since the point has been adjusted, we call lcl_FindFrameInTab()
1619 // with a fuzzy value of 1:
1620 nTmpFuzzy = 1;
1621 }
1622
1623 const SwFrame* pTmp = bSearchForFrameInTab ?
1624 ::lcl_FindFrameInTab( static_cast<const SwLayoutFrame*>(pFrame), aPt, nTmpFuzzy ) :
1625 nullptr;
1626
1627 if ( pTmp )
1628 {
1629 pFrame = pTmp;
1630 break;
1631 }
1632 }
1633 pFrame = pFrame->FindNextCnt();
1634
1635 } while ( pFrame && pLay->IsAnLower( pFrame ) );
1636 }
1637
1638 if ( pFrame && pFrame->IsInTab() && pLay->IsAnLower( pFrame ) )
1639 {
1640 do
1641 {
1642 // We allow mouse drag of table borders within nested tables,
1643 // but disallow hotspot selection of nested tables.
1644 if ( bMouseMoveRowCols )
1645 {
1646 // find the next cell frame
1647 while ( pFrame && !pFrame->IsCellFrame() )
1648 pFrame = pFrame->GetUpper();
1649 }
1650 else
1651 {
1652 // find the most upper cell frame:
1653 while ( pFrame &&
1654 ( !pFrame->IsCellFrame() ||
1655 !pFrame->GetUpper()->GetUpper()->IsTabFrame() ||
1656 pFrame->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
1657 pFrame = pFrame->GetUpper();
1658 }
1659
1660 if ( pFrame ) // Note: this condition should be the same like the while condition!!!
1661 {
1662 // #i32329# Enhanced table selection
1663 // used for hotspot selection of tab/cols/rows
1664 if ( !bMouseMoveRowCols )
1665 {
1666
1667 OSL_ENSURE( pbCol && pbRow, "pbCol or pbRow missing" );
1668
1669 if ( bCloseToRow || bCloseToCol )
1670 {
1671 *pbRow = bCloseToRow;
1672 *pbCol = bCloseToCol;
1673 pRet = pFrame;
1674 break;
1675 }
1676 }
1677 else
1678 {
1679 // used for mouse move of columns/rows
1680 const SwTabFrame* pTabFrame = pFrame->FindTabFrame();
1681 SwRect aTabRect = pTabFrame->getFramePrintArea();
1682 aTabRect.Pos() += pTabFrame->getFrameArea().Pos();
1683
1684 SwRectFnSet aRectFnSet(pTabFrame);
1685
1686 const SwTwips nTabTop = aRectFnSet.GetTop(aTabRect);
1687 const SwTwips nMouseTop = aRectFnSet.IsVert() ? rPt.X() : rPt.Y();
1688
1689 // Do not allow to drag upper table border:
1690 if ( !::IsSame( nTabTop, nMouseTop ) )
1691 {
1692 if ( ::IsSame( pFrame->getFrameArea().Left(), rPt.X() ) ||
1693 ::IsSame( pFrame->getFrameArea().Right(),rPt.X() ) )
1694 {
1695 if ( pbRow ) *pbRow = false;
1696 pRet = pFrame;
1697 break;
1698 }
1699 if ( ::IsSame( pFrame->getFrameArea().Top(), rPt.Y() ) ||
1700 ::IsSame( pFrame->getFrameArea().Bottom(),rPt.Y() ) )
1701 {
1702 if ( pbRow ) *pbRow = true;
1703 pRet = pFrame;
1704 break;
1705 }
1706 }
1707 }
1708
1709 pFrame = pFrame->GetUpper();
1710 }
1711 } while ( pFrame );
1712 }
1713
1714 // robust:
1715 OSL_ENSURE( !pRet || pRet->IsCellFrame(), "lcl_FindFrame() is supposed to find a cell frame!" );
1716 return pRet && pRet->IsCellFrame() ? static_cast<const SwCellFrame*>(pRet) : nullptr;
1717}
1718
1719// pbCol = 0 => Used for moving table rows/cols with mouse
1720// pbCol != 0 => Used for selecting table/rows/cols
1721
1722#define ENHANCED_TABLE_SELECTION_FUZZY 10
1723
1724const SwFrame* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const
1725{
1726 const SwPageFrame *pPage = static_cast<SwPageFrame*>(GetLayout()->Lower());
1727 vcl::Window* pOutWin = GetWin();
1728 SwTwips nFuzzy = COLFUZZY;
1729 if( pOutWin )
1730 {
1731 // #i32329# Enhanced table selection
1733 Size aTmp( nSize, nSize );
1734 aTmp = pOutWin->PixelToLogic( aTmp );
1735 nFuzzy = aTmp.Width();
1736 }
1737
1738 while ( pPage && !pPage->getFrameArea().IsNear( rPt, nFuzzy ) )
1739 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1740
1741 const SwCellFrame *pFrame = nullptr;
1742 if ( pPage )
1743 {
1744 // We cannot search the box by GetModelPositionForViewPoint or GetContentPos.
1745 // This would lead to a performance collapse for documents
1746 // with a lot of paragraphs/tables on one page
1747 //(BrowseMode!)
1748
1749 // check flys first
1750 if ( pPage->GetSortedObjs() )
1751 {
1752 for ( size_t i = 0; !pFrame && i < pPage->GetSortedObjs()->size(); ++i )
1753 {
1754 SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
1755 if ( auto pFlyFrame = pObj->DynCastFlyFrame() )
1756 {
1757 pFrame = lcl_FindFrame( pFlyFrame, rPt, nFuzzy, pbRow, pbCol );
1758 }
1759 }
1760 }
1761 const SwLayoutFrame *pLay = static_cast<const SwLayoutFrame*>(pPage->Lower());
1762 while ( pLay && !pFrame )
1763 {
1764 pFrame = lcl_FindFrame( pLay, rPt, nFuzzy, pbRow, pbCol );
1765 pLay = static_cast<const SwLayoutFrame*>(pLay->GetNext());
1766 }
1767 }
1768 return pFrame;
1769}
1770
1771/* Helper function*/
1772/* calculated the distance between Point rC and Line Segment (rA, rB) */
1773static double lcl_DistancePoint2Segment( const Point& rA, const Point& rB, const Point& rC )
1774{
1775 double nRet = 0;
1776
1777 const basegfx::B2DVector aBC( rC.X() - rB.X(), rC.Y() - rB.Y() );
1778 const basegfx::B2DVector aAB( rB.X() - rA.X(), rB.Y() - rA.Y() );
1779 const double nDot1 = aBC.scalar( aAB );
1780
1781 if ( nDot1 > 0 ) // check outside case 1
1782 nRet = aBC.getLength();
1783 else
1784 {
1785 const basegfx::B2DVector aAC( rC.X() - rA.X(), rC.Y() - rA.Y() );
1786 const basegfx::B2DVector aBA( rA.X() - rB.X(), rA.Y() - rB.Y() );
1787 const double nDot2 = aAC.scalar( aBA );
1788
1789 if ( nDot2 > 0 ) // check outside case 2
1790 nRet = aAC.getLength();
1791 else
1792 {
1793 const double nDiv = aAB.getLength();
1794 nRet = nDiv ? aAB.cross( aAC ) / nDiv : 0;
1795 }
1796 }
1797
1798 return std::abs(nRet);
1799}
1800
1801/* Helper function*/
1802static Point lcl_ProjectOntoClosestTableFrame( const SwTabFrame& rTab, const Point& rPoint, bool bRowDrag )
1803{
1804 Point aRet( rPoint );
1805 const SwTabFrame* pCurrentTab = &rTab;
1806 const bool bVert = pCurrentTab->IsVertical();
1807 const bool bRTL = pCurrentTab->IsRightToLeft();
1808
1809 // Western Layout:
1810 // bRowDrag = true => compare to left border of table
1811 // bRowDrag = false => compare to top border of table
1812
1813 // Asian Layout:
1814 // bRowDrag = true => compare to right border of table
1815 // bRowDrag = false => compare to top border of table
1816
1817 // RTL Layout:
1818 // bRowDrag = true => compare to right border of table
1819 // bRowDrag = false => compare to top border of table
1820 bool bLeft = false;
1821 bool bRight = false;
1822
1823 if ( bRowDrag )
1824 {
1825 if ( bVert || bRTL )
1826 bRight = true;
1827 else
1828 bLeft = true;
1829 }
1830
1831 // used to find the minimal distance
1832 double nMin = -1;
1833 Point aMin1;
1834 Point aMin2;
1835
1836 Point aS1;
1837 Point aS2;
1838
1839 while ( pCurrentTab )
1840 {
1841 SwRect aTabRect( pCurrentTab->getFramePrintArea() );
1842 aTabRect += pCurrentTab->getFrameArea().Pos();
1843
1844 if ( bLeft )
1845 {
1846 // distance to left table border
1847 aS1 = aTabRect.TopLeft();
1848 aS2 = aTabRect.BottomLeft();
1849 }
1850 else if ( bRight )
1851 {
1852 // distance to right table border
1853 aS1 = aTabRect.TopRight();
1854 aS2 = aTabRect.BottomRight();
1855 }
1856 else //if ( bTop )
1857 {
1858 // distance to top table border
1859 aS1 = aTabRect.TopLeft();
1860 aS2 = aTabRect.TopRight();
1861 }
1862
1863 const double nDist = lcl_DistancePoint2Segment( aS1, aS2, rPoint );
1864
1865 if ( nDist < nMin || -1 == nMin )
1866 {
1867 aMin1 = aS1;
1868 aMin2 = aS2;
1869 nMin = nDist;
1870 }
1871
1872 pCurrentTab = pCurrentTab->GetFollow();
1873 }
1874
1875 // project onto closest line:
1876 if ( bLeft || bRight )
1877 {
1878 aRet.setX(aMin1.getX());
1879 if ( aRet.getY() > aMin2.getY() )
1880 aRet.setY(aMin2.getY());
1881 else if ( aRet.getY() < aMin1.getY() )
1882 aRet.setY(aMin1.getY());
1883 }
1884 else
1885 {
1886 aRet.setY(aMin1.getY());
1887 if ( aRet.getX() > aMin2.getX() )
1888 aRet.setX(aMin2.getX());
1889 else if ( aRet.getX() < aMin1.getX() )
1890 aRet.setX(aMin1.getX());
1891 }
1892
1893 return aRet;
1894}
1895
1896// #i32329# Enhanced table selection
1897bool SwFEShell::SelTableRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
1898{
1899 bool bRet = false;
1900 Point aEndPt;
1901 if ( pEnd )
1902 aEndPt = *pEnd;
1903
1904 SwPosition* ppPos[2] = { nullptr, nullptr };
1905 Point paPt [2] = { rPt, aEndPt };
1906 bool pbRow[2] = { false, false };
1907 bool pbCol[2] = { false, false };
1908
1909 // pEnd is set during dragging.
1910 for ( sal_uInt16 i = 0; i < ( pEnd ? 2 : 1 ); ++i )
1911 {
1912 const SwCellFrame* pFrame =
1913 static_cast<const SwCellFrame*>(GetBox( paPt[i], &pbRow[i], &pbCol[i] ) );
1914
1915 if( pFrame )
1916 {
1917 while( pFrame && pFrame->Lower() && pFrame->Lower()->IsRowFrame() )
1918 pFrame = static_cast<const SwCellFrame*>( static_cast<const SwLayoutFrame*>( pFrame->Lower() )->Lower() );
1919 if( pFrame && pFrame->GetTabBox()->GetSttNd() &&
1920 pFrame->GetTabBox()->GetSttNd()->IsInProtectSect() )
1921 pFrame = nullptr;
1922 }
1923
1924 if ( pFrame )
1925 {
1926 const SwContentFrame* pContent = ::GetCellContent( *pFrame );
1927
1928 if ( pContent && pContent->IsTextFrame() )
1929 {
1930
1931 ppPos[i] = new SwPosition(static_cast<SwTextFrame const*>(pContent)->MapViewToModelPos(TextFrameIndex(0)));
1932
1933 // paPt[i] will not be used any longer, now we use it to store
1934 // a position inside the content frame
1935 paPt[i] = pContent->getFrameArea().Center();
1936 }
1937 }
1938
1939 // no calculation of end frame if start frame has not been found.
1940 if ( 1 == i || !ppPos[0] || !pEnd || !pFrame )
1941 break;
1942
1943 // find 'closest' table frame to pEnd:
1944 const SwTabFrame* pCurrentTab = pFrame->FindTabFrame();
1945 if ( pCurrentTab->IsFollow() )
1946 pCurrentTab = pCurrentTab->FindMaster( true );
1947
1948 const Point aProjection = lcl_ProjectOntoClosestTableFrame( *pCurrentTab, *pEnd, bRowDrag );
1949 paPt[1] = aProjection;
1950 }
1951
1952 if ( ppPos[0] )
1953 {
1954 SwShellCursor* pCursor = GetCursor_();
1955 SwCursorSaveState aSaveState( *pCursor );
1956 SwPosition aOldPos( *pCursor->GetPoint() );
1957
1958 pCursor->DeleteMark();
1959 *pCursor->GetPoint() = *ppPos[0];
1960 pCursor->GetPtPos() = paPt[0];
1961
1962 if ( !pCursor->IsInProtectTable() )
1963 {
1964 bool bNewSelection = true;
1965
1966 if ( ppPos[1] )
1967 {
1968 if ( ppPos[1]->GetNode().StartOfSectionNode() !=
1969 aOldPos.GetNode().StartOfSectionNode() )
1970 {
1971 pCursor->SetMark();
1972 SwCursorSaveState aSaveState2( *pCursor );
1973 *pCursor->GetPoint() = *ppPos[1];
1974 pCursor->GetPtPos() = paPt[1];
1975
1976 if ( pCursor->IsInProtectTable( false, false ) )
1977 {
1978 pCursor->RestoreSavePos();
1979 bNewSelection = false;
1980 }
1981 }
1982 else
1983 {
1984 pCursor->RestoreSavePos();
1985 bNewSelection = false;
1986 }
1987 }
1988
1989 if ( bNewSelection )
1990 {
1991 // #i35543# SelTableRowCol should remove any existing
1992 // table cursor:
1993 if ( IsTableMode() )
1995
1996 if ( pbRow[0] && pbCol[0] )
1997 bRet = SwCursorShell::SelTable();
1998 else if ( pbRow[0] )
1999 bRet = SwCursorShell::SelTableRowOrCol( true, true );
2000 else if ( pbCol[0] )
2001 bRet = SwCursorShell::SelTableRowOrCol( false, true );
2002 }
2003 else
2004 bRet = true;
2005 }
2006
2007 delete ppPos[0];
2008 delete ppPos[1];
2009 }
2010
2011 return bRet;
2012}
2013
2014SwTab SwFEShell::WhichMouseTabCol( const Point &rPt ) const
2015{
2016 SwTab nRet = SwTab::COL_NONE;
2017 bool bRow = false;
2018 bool bCol = false;
2019 bool bSelect = false;
2020
2021 // First try: Do we get the row/col move cursor?
2022 const SwCellFrame* pFrame = static_cast<const SwCellFrame*>(GetBox( rPt, &bRow ));
2023
2024 if ( !pFrame )
2025 {
2026 // Second try: Do we get the row/col/tab selection cursor?
2027 pFrame = static_cast<const SwCellFrame*>(GetBox( rPt, &bRow, &bCol ));
2028 bSelect = true;
2029 }
2030
2031 if( pFrame )
2032 {
2033 while( pFrame && pFrame->Lower() && pFrame->Lower()->IsRowFrame() )
2034 pFrame = static_cast<const SwCellFrame*>(static_cast<const SwLayoutFrame*>(pFrame->Lower())->Lower());
2035 if( pFrame && pFrame->GetTabBox()->GetSttNd() &&
2036 pFrame->GetTabBox()->GetSttNd()->IsInProtectSect() )
2037 pFrame = nullptr;
2038 }
2039
2040 if( pFrame )
2041 {
2042 if ( !bSelect )
2043 {
2044 if ( pFrame->IsVertical() )
2045 nRet = bRow ? SwTab::COL_VERT : SwTab::ROW_VERT;
2046 else
2047 nRet = bRow ? SwTab::ROW_HORI : SwTab::COL_HORI;
2048 }
2049 else
2050 {
2051 const SwTabFrame* pTabFrame = pFrame->FindTabFrame();
2052 if ( pTabFrame->IsVertical() )
2053 {
2054 if ( bRow && bCol )
2055 {
2056 nRet = SwTab::SEL_VERT;
2057 }
2058 else if ( bRow )
2059 {
2060 nRet = SwTab::ROWSEL_VERT;
2061 }
2062 else if ( bCol )
2063 {
2064 nRet = SwTab::COLSEL_VERT;
2065 }
2066 }
2067 else
2068 {
2069 if ( bRow && bCol )
2070 {
2071 nRet = pTabFrame->IsRightToLeft() ?
2074 }
2075 else if ( bRow )
2076 {
2077 nRet = pTabFrame->IsRightToLeft() ?
2080 }
2081 else if ( bCol )
2082 {
2083 nRet = SwTab::COLSEL_HORI;
2084 }
2085 }
2086 }
2087 }
2088
2089 return nRet;
2090}
2091
2092// -> #i23726#
2094{
2095 SwTextNode * pResult = nullptr;
2096
2098
2099 if( GetContentAtPos(rPt, aContentAtPos) && aContentAtPos.aFnd.pNode)
2100 pResult = aContentAtPos.aFnd.pNode->GetTextNode();
2101
2102 return pResult;
2103}
2104
2105bool SwFEShell::IsNumLabel( const Point &rPt, int nMaxOffset )
2106{
2107 bool bResult = false;
2108
2110
2111 if( GetContentAtPos(rPt, aContentAtPos))
2112 {
2113 if ((nMaxOffset >= 0 && aContentAtPos.nDist <= nMaxOffset) ||
2114 (nMaxOffset < 0))
2115 bResult = true;
2116 }
2117
2118 return bResult;
2119}
2120// <- #i23726#
2121
2122// #i42921#
2124 const Point& _rDocPos )
2125{
2126 bool bRet( false );
2127
2128 const SvxFrameDirection nTextDir =
2129 _rTextNode.GetTextDirection( SwPosition(_rTextNode), &_rDocPos );
2130 switch ( nTextDir )
2131 {
2132 case SvxFrameDirection::Unknown:
2133 case SvxFrameDirection::Horizontal_RL_TB:
2134 case SvxFrameDirection::Horizontal_LR_TB:
2135 {
2136 bRet = false;
2137 }
2138 break;
2139 case SvxFrameDirection::Vertical_LR_TB:
2140 case SvxFrameDirection::Vertical_RL_TB:
2141 {
2142 bRet = true;
2143 }
2144 break;
2145 default: break;
2146 }
2147
2148 return bRet;
2149}
2150
2151void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const
2152{
2153 const SwFrame *pBox = GetBox( rPt );
2154 if ( pBox )
2155 GetTabCols_( rToFill, pBox );
2156}
2157
2158void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, bool bCurRowOnly,
2159 const Point &rPt )
2160{
2161 const SwFrame *pBox = GetBox( rPt );
2162 if( pBox )
2163 {
2164 CurrShell aCurr( this );
2166 GetDoc()->SetTabCols( rNew, bCurRowOnly, static_cast<const SwCellFrame*>(pBox) );
2168 }
2169}
2170
2171sal_uInt16 SwFEShell::GetCurMouseColNum( const Point &rPt ) const
2172{
2173 return GetCurColNum_( GetBox( rPt ), nullptr );
2174}
2175
2176size_t SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const
2177{
2179 size_t nRet = 0;
2180
2181 const SwFrame *pFrame = GetBox( rPt );
2182 OSL_ENSURE( pFrame, "Table not found" );
2183 if( pFrame )
2184 {
2185 const tools::Long nX = pFrame->getFrameArea().Left();
2186
2187 // get TabCols, only via these we get the position
2188 SwTabCols aTabCols;
2189 GetMouseTabCols( aTabCols, rPt );
2190
2191 const tools::Long nLeft = aTabCols.GetLeftMin();
2192
2193 if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
2194 {
2195 for ( size_t i = 0; i < aTabCols.Count(); ++i )
2196 if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
2197 {
2198 nRet = i + 1;
2199 break;
2200 }
2201 }
2202 }
2203 return nRet;
2204}
2205
2206void ClearFEShellTabCols(SwDoc & rDoc, SwTabFrame const*const pFrame)
2207{
2208 auto const pShell(rDoc.getIDocumentLayoutAccess().GetCurrentViewShell());
2209 if (pShell)
2210 {
2211 for (SwViewShell& rCurrentShell : pShell->GetRingContainer())
2212 {
2213 if (auto const pFE = dynamic_cast<SwFEShell *>(&rCurrentShell))
2214 {
2215 pFE->ClearColumnRowCache(pFrame);
2216 }
2217 }
2218 }
2219}
2220
2222{
2223 if (m_pColumnCache)
2224 {
2225 if (pFrame == nullptr || pFrame == m_pColumnCache->pLastTabFrame)
2226 {
2227 m_pColumnCache.reset();
2228 }
2229 }
2230 if (m_pRowCache)
2231 {
2232 if (pFrame == nullptr || pFrame == m_pRowCache->pLastTabFrame)
2233 {
2234 m_pRowCache.reset();
2235 }
2236 }
2237}
2238
2240{
2241 SwFrame *pFrame = GetCurrFrame();
2242 if( pFrame && pFrame->IsInTab() )
2243 rSet.Put( pFrame->ImplFindTabFrame()->GetFormat()->GetAttrSet() );
2244}
2245
2247{
2248 SwFrame *pFrame = GetCurrFrame();
2249 if( pFrame && pFrame->IsInTab() )
2250 {
2251 CurrShell aCurr( this );
2253 SwTabFrame *pTab = pFrame->FindTabFrame();
2254 pTab->GetTable()->SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>());
2255 GetDoc()->SetAttr( rNew, *pTab->GetFormat() );
2258 }
2259}
2260
2261// change a cell width/cell height/column width/row height
2263{
2264 SwFrame *pFrame = GetCurrFrame();
2265 if( !pFrame || !pFrame->IsInTab() )
2266 return;
2267
2268 CurrShell aCurr( this );
2270
2271 do {
2272 pFrame = pFrame->GetUpper();
2273 } while( !pFrame->IsCellFrame() );
2274
2275 SwTabFrame *pTab = pFrame->ImplFindTabFrame();
2276
2277 // if the table is in relative values (USHRT_MAX)
2278 // then it should be recalculated to absolute values now
2279 const SwFormatFrameSize& rTableFrameSz = pTab->GetFormat()->GetFrameSize();
2280 SwRectFnSet aRectFnSet(pTab);
2281 tools::Long nPrtWidth = aRectFnSet.GetWidth(pTab->getFramePrintArea());
2286 nPrtWidth != rTableFrameSz.GetWidth() )
2287 {
2288 SwFormatFrameSize aSz( rTableFrameSz );
2289 aSz.SetWidth( pTab->getFramePrintArea().Width() );
2290 pTab->GetFormat()->SetFormatAttr( aSz );
2291 }
2292
2293 SwTwips nLogDiff = nDiff;
2294 nLogDiff *= pTab->GetFormat()->GetFrameSize().GetWidth();
2295 nLogDiff /= nPrtWidth;
2296
2299 *const_cast<SwTableBox*>(static_cast<SwCellFrame*>(pFrame)->GetTabBox()),
2300 eType, nDiff, nLogDiff );
2301
2302 ClearFEShellTabCols(*GetDoc(), nullptr);
2304}
2305
2306static bool lcl_IsFormulaSelBoxes( const SwTable& rTable, const SwTableBoxFormula& rFormula,
2307 SwCellFrames& rCells )
2308{
2309 SwTableBoxFormula aTmp( rFormula );
2310 SwSelBoxes aBoxes;
2311 aTmp.GetBoxesOfFormula(rTable, aBoxes);
2312 for (size_t nSelBoxes = aBoxes.size(); nSelBoxes; )
2313 {
2314 SwTableBox* pBox = aBoxes[ --nSelBoxes ];
2315
2316 if( std::none_of(rCells.begin(), rCells.end(), [&pBox](SwCellFrame* pFrame) { return pFrame->GetTabBox() == pBox; }) )
2317 return false;
2318 }
2319
2320 return true;
2321}
2322
2323 // ask formula for auto-sum
2324void SwFEShell::GetAutoSum( OUString& rFormula ) const
2325{
2326 SwFrame *pFrame = GetCurrFrame();
2327 SwTabFrame *pTab = pFrame ? pFrame->ImplFindTabFrame() : nullptr;
2328 if( !pTab )
2329 return;
2330
2331 SwCellFrames aCells;
2332 OUString sFields;
2333 if( ::GetAutoSumSel( *this, aCells ))
2334 {
2335 sal_uInt16 nW = 0;
2336 for( size_t n = aCells.size(); n; )
2337 {
2338 SwCellFrame* pCFrame = aCells[ --n ];
2339 sal_uInt16 nBoxW = pCFrame->GetTabBox()->IsFormulaOrValueBox();
2340 if( !nBoxW )
2341 break;
2342
2343 if( !nW )
2344 {
2345 if( USHRT_MAX == nBoxW )
2346 continue; // skip space at beginning
2347
2348 // formula only if box is contained
2349 if( RES_BOXATR_FORMULA == nBoxW &&
2350 !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrame->
2351 GetTabBox()->GetFrameFormat()->GetTableBoxFormula(), aCells))
2352 {
2353 nW = RES_BOXATR_VALUE;
2354 // restore previous spaces!
2355 for( size_t i = aCells.size(); n+1 < i; )
2356 {
2357 sFields = "|<" + aCells[--i]->GetTabBox()->GetName() + ">"
2358 + sFields;
2359 }
2360 }
2361 else
2362 nW = nBoxW;
2363 }
2364 else if( RES_BOXATR_VALUE == nW )
2365 {
2366 // search for values, Value/Formula/Text found -> include
2367 if( RES_BOXATR_FORMULA == nBoxW &&
2368 ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrame->
2369 GetTabBox()->GetFrameFormat()->GetTableBoxFormula(), aCells ))
2370 break;
2371 else if( USHRT_MAX != nBoxW )
2372 sFields = OUStringChar(cListDelim) + sFields;
2373 else
2374 break;
2375 }
2376 else if( RES_BOXATR_FORMULA == nW )
2377 {
2378 // only continue search when the current formula points to
2379 // all boxes contained in the selection
2380 if( RES_BOXATR_FORMULA == nBoxW )
2381 {
2382 if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrame->
2383 GetTabBox()->GetFrameFormat()->GetTableBoxFormula(), aCells ))
2384 {
2385 // redo only for values!
2386
2387 nW = RES_BOXATR_VALUE;
2388 sFields.clear();
2389 // restore previous spaces!
2390 for( size_t i = aCells.size(); n+1 < i; )
2391 {
2392 sFields = "|<" + aCells[--i]->GetTabBox()->GetName() + ">"
2393 + sFields;
2394 }
2395 }
2396 else
2397 sFields = OUStringChar(cListDelim) + sFields;
2398 }
2399 else if( USHRT_MAX == nBoxW )
2400 break;
2401 else
2402 continue; // ignore this box
2403 }
2404 else
2405 // all other stuff terminates the loop
2406 // possibly allow texts??
2407 break;
2408
2409 sFields = "<" + pCFrame->GetTabBox()->GetName() + ">" + sFields;
2410 }
2411 }
2412
2413 rFormula = OUString::createFromAscii( sCalc_Sum );
2414 if (!sFields.isEmpty())
2415 {
2416 rFormula += "(" + sFields + ")";
2417 }
2418}
2419
2421{
2422 SwFrame *pFrame = GetCurrFrame();
2423 SwTabFrame *pTab = (pFrame && pFrame->IsInTab()) ? pFrame->ImplFindTabFrame() : nullptr;
2424 if (!pTab)
2425 return false;
2426 return pTab->IsRightToLeft();
2427}
2428
2429bool SwFEShell::IsMouseTableRightToLeft(const Point &rPt) const
2430{
2431 SwFrame *pFrame = const_cast<SwFrame *>(GetBox( rPt ));
2432 const SwTabFrame* pTabFrame = pFrame ? pFrame->ImplFindTabFrame() : nullptr;
2433 OSL_ENSURE( pTabFrame, "Table not found" );
2434 return pTabFrame && pTabFrame->IsRightToLeft();
2435}
2436
2438{
2439 SwFrame *pFrame = GetCurrFrame();
2440 SwTabFrame *pTab = (pFrame && pFrame->IsInTab()) ? pFrame->ImplFindTabFrame() : nullptr;
2441 if (!pTab)
2442 return false;
2443 return pTab->IsVertical();
2444}
2445
2446/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
const char sCalc_Sum[]
Definition: calc.cxx:75
const sal_Unicode cListDelim
Definition: calc.hxx:41
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
const FndLines_t & GetLines() const
Definition: tblsel.hxx:172
const SwTableBox * GetBox() const
Definition: tblsel.hxx:174
virtual const SwRootFrame * GetCurrentLayout() const =0
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual void SetModified()=0
Must be called manually at changes of format.
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
constexpr tools::Long Width() const
void SetContentProtect(bool bNew)
bool IsContentProtected() const
tools::Long GetWidth() const
void SetWidth(tools::Long n)
wrapper class for the positioning of Writer fly frames and drawing objects
virtual const SwFlyFrame * DynCastFlyFrame() const
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:31
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
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:1225
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt) const
determines the text direction for a certain position.
Definition: node.cxx:2086
virtual sal_Int32 Len() const
Definition: node.cxx:1258
A helper class to save cursor state (position).
Definition: swcrsr.hxx:233
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:914
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:341
friend bool GetAutoSumSel(const SwCursorShell &, SwCellFrames &)
Definition: tblsel.cxx:691
void ParkCursor(const SwNode &rIdx)
Remove selections and additional cursors of all shells.
Definition: crsrsh.cxx:2914
StartsWith StartsWith_()
If document body starts with a table or starts/ends with hidden paragraph.
Definition: crsrsh.cxx:626
bool SelTableRowOrCol(bool bRow, bool bRowSimple=false)
Definition: trvltbl.cxx:127
bool SelTable()
Definition: trvltbl.cxx:253
bool IsCursorReadonly() const
Definition: crsrsh.cxx:3335
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
void TableCursorToCursor()
enter block mode, change normal cursor into block cursor
Definition: crsrsh.cxx:910
const SwShellTableCursor * GetTableCursor() const
Definition: crsrsh.hxx:664
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2497
bool ExtendedSelectedAll()
If ExtendedSelectAll() was called and selection didn't change since then.
Definition: crsrsh.cxx:607
void ClearMark()
Definition: crsrsh.cxx:953
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3082
void KillPams()
Definition: crsrsh.cxx:1036
bool GetContentAtPos(const Point &rPt, SwContentAtPos &rContentAtPos, bool bSetCursor=false, SwRect *pFieldRect=nullptr)
Definition: crstrvl.cxx:1428
bool IsTableMode() const
Definition: crsrsh.hxx:662
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2341
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:174
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:557
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:175
virtual bool IsChangeRecording() const override
passwword protection for Writer (derived from SfxObjectShell) see also: FN_REDLINE_ON,...
Definition: docsh.cxx:1343
Definition: doc.hxx:195
bool GetTableAutoFormat(const SwSelBoxes &rBoxes, SwTableAutoFormat &rGet)
Find out who has the Attributes.
Definition: ndtbl.cxx:3789
void InsertCol(const SwCursor &rCursor, sal_uInt16 nCnt=1, bool bBehind=true)
Inserting Columns/Rows.
Definition: ndtbl.cxx:1684
void SetRowHeight(const SwCursor &rCursor, const SwFormatFrameSize &rNew)
Definition: ndtbl1.cxx:389
void SetTabLineStyle(const SwCursor &rCursor, const Color *pColor, bool bSetLine, const editeng::SvxBorderLine *pBorderLine)
Definition: ndtbl1.cxx:968
static sal_uInt16 GetBoxAlign(const SwCursor &rCursor)
Definition: ndtbl1.cxx:1395
void SetRowSplit(const SwCursor &rCursor, const SwFormatRowSplit &rNew)
Definition: ndtbl1.cxx:324
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:402
TableMergeErr MergeTable(SwPaM &rPam)
Definition: ndtbl.cxx:2191
bool BalanceRowHeight(const SwCursor &rCursor, bool bTstOnly, const bool bOptimize)
Adjustment of Rowheights.
Definition: ndtbl1.cxx:436
static bool GetRowBackground(const SwCursor &rCursor, std::unique_ptr< SvxBrushItem > &rToFill)
Definition: ndtbl1.cxx:515
static bool GetBoxAttr(const SwCursor &rCursor, std::unique_ptr< SfxPoolItem > &rToFill)
Retrieves a box attribute from the given cursor.
Definition: ndtbl1.cxx:1321
static void GetTabRows(SwTabCols &rFill, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2542
void SetAttr(const SfxPoolItem &, SwFormat &)
Set attribute in given format.1y If Undo is enabled, the old values is added to the Undo history.
Definition: docfmt.cxx:452
static std::unique_ptr< SwFormatFrameSize > GetRowHeight(const SwCursor &rCursor)
Definition: ndtbl1.cxx:414
SwNodes & GetNodes()
Definition: doc.hxx:420
void SetRowNotTracked(const SwCursor &rCursor, const SvxPrintItem &rNotTracked, bool bAll=false, bool bIns=false)
rNotTracked = false means that the row was deleted or inserted with its tracked cell content bAll: de...
Definition: ndtbl1.cxx:581
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
static std::unique_ptr< SwFormatRowSplit > GetRowSplit(const SwCursor &rCursor)
Definition: ndtbl1.cxx:350
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:413
void SetTabCols(const SwTabCols &rNew, bool bCurRowOnly, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2677
void InsertRow(const SwCursor &rCursor, sal_uInt16 nCnt=1, bool bBehind=true)
Definition: ndtbl.cxx:1739
void SetTabRows(const SwTabCols &rNew, bool bCurColOnly, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2733
static void GetTabCols(SwTabCols &rFill, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2488
void UnProtectTables(const SwPaM &rPam)
Definition: ndtbl.cxx:4462
bool SplitTable(const SwSelBoxes &rBoxes, bool bVert, sal_uInt16 nCnt, bool bSameHeight=false)
Split up/merge Boxes in the Table.
Definition: ndtbl.cxx:2127
void SetTabBorders(const SwCursor &rCursor, const SfxItemSet &rSet)
Definition: ndtbl1.cxx:688
void SetBoxAlign(const SwCursor &rCursor, sal_uInt16 nAlign)
Definition: ndtbl1.cxx:1386
bool DeleteRowCol(const SwSelBoxes &rBoxes, RowColMode eMode=RowColMode::DeleteRow)
Definition: ndtbl.cxx:1916
void AdjustCellWidth(const SwCursor &rCursor, const bool bBalance, const bool bNoShrink)
Adjusts selected cell widths in such a way, that their content does not need to be wrapped (if possib...
Definition: ndtbl1.cxx:1606
bool HasTableAnyProtection(const SwPosition *pPos, const OUString *pTableName, bool *pFullTableProtection)
Definition: ndtbl.cxx:4502
static bool HasRowNotTracked(const SwCursor &rCursor)
don't call SetRowNotTracked() for rows with tracked row change
Definition: ndtbl1.cxx:545
void SetRowsToRepeat(SwTable &rTable, sal_uInt16 nSet)
Definition: ndtbl.cxx:2879
void SetBoxAttr(const SwCursor &rCursor, const SfxPoolItem &rNew)
Definition: ndtbl1.cxx:1276
SwTableAutoFormatTable & GetTableStyles()
Return the available table styles.
Definition: ndtbl.cxx:3862
void SetColRowWidthHeight(SwTableBox &rCurrentBox, TableChgWidthHeightType eType, SwTwips nAbsDiff, SwTwips nRelDiff)
Definition: ndtbl.cxx:3947
SwDocShell * GetDocShell()
Definition: doc.hxx:1364
void SetRowBackground(const SwCursor &rCursor, const SvxBrushItem &rNew)
Definition: ndtbl1.cxx:489
void UnProtectCells(const OUString &rTableName)
Definition: ndtbl.cxx:4414
static void GetTabBorders(const SwCursor &rCursor, SfxItemSet &rSet)
Definition: ndtbl1.cxx:1059
bool SetTableAutoFormat(const SwSelBoxes &rBoxes, const SwTableAutoFormat &rNew, bool bResetDirect=false, bool isSetStyleName=false)
AutoFormat for table/table selection.
Definition: ndtbl.cxx:3698
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
bool Delete(bool isArtificialSelection=false)
Delete content of all ranges.
Definition: eddel.cxx:125
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
void EndAllAction()
Definition: edws.cxx:97
void GetTableAttr(SfxItemSet &) const
Definition: fetab.cxx:2239
bool DeleteCol()
Definition: fetab.cxx:264
void SetTabCols(const SwTabCols &rNew, bool bCurRowOnly)
Definition: fetab.cxx:737
void GetAutoSum(OUString &rFormula) const
Definition: fetab.cxx:2324
void InsertCol(sal_uInt16 nCnt, bool bBehind)
Definition: fetab.cxx:211
std::unique_ptr< SwColCache > m_pColumnCache
Definition: fesh.hxx:204
bool BalanceRowHeight(bool bTstOnly, const bool bOptimize=false)
Definition: fetab.cxx:851
void SetTabRows(const SwTabCols &rNew, bool bCurColOnly)
Definition: fetab.cxx:788
SwTextNode * GetNumRuleNodeAtPos(const Point &rPot)
Definition: fetab.cxx:2093
bool GetRowBackground(std::unique_ptr< SvxBrushItem > &rToFill) const
FALSE ambiguous.
Definition: fetab.cxx:870
bool HasTableAnyProtection(const OUString *pTableName, bool *pFullTableProtection)
Definition: fetab.cxx:1077
bool IsNumLabel(const Point &rPt, int nMaxOffset=-1)
Definition: fetab.cxx:2105
sal_uInt16 GetRowsToRepeat() const
Definition: fetab.cxx:1111
bool HasBoxSelection() const
Is content of a table cell or at least a table cell completely selected?
Definition: fetab.cxx:981
void SetBoxAlign(sal_uInt16 nOrient)
Definition: fetab.cxx:930
SAL_DLLPRIVATE const SwFrame * GetBox(const Point &rPt, bool *pbRow=nullptr, bool *pbCol=nullptr) const
Used for mouse operations on a table:
Definition: fetab.cxx:1724
void SetBoxBackground(const SvxBrushItem &rNew)
Definition: fetab.cxx:898
std::unique_ptr< SwColCache > m_pRowCache
Definition: fesh.hxx:205
void SetRowSplit(const SwFormatRowSplit &rSz)
Definition: fetab.cxx:825
void SetTableStyle(const OUString &rStyleName)
Set table style of the current table.
Definition: fetab.cxx:1294
void SetMouseTabRows(const SwTabCols &rNew, bool bCurColOnly, const Point &rPt)
Definition: fetab.cxx:813
void GetTabCols(SwTabCols &rToFill) const
Info about columns and margins.
Definition: fetab.cxx:755
void SetRowBackground(const SvxBrushItem &rNew)
Definition: fetab.cxx:862
void DeleteTable()
Definition: fetab.cxx:317
void SetRowHeight(const SwFormatFrameSize &rSz)
Definition: fetab.cxx:838
bool IsTableVertical() const
Definition: fetab.cxx:2437
bool IsLastCellInRow() const
Definition: fetab.cxx:248
void SetMouseTabCols(const SwTabCols &rNew, bool bCurRowOnly, const Point &rPt)
Definition: fetab.cxx:2158
SAL_DLLPRIVATE void GetTabCols_(SwTabCols &rToFill, const SwFrame *pBox) const
Definition: fetab.cxx:625
SAL_DLLPRIVATE void GetTabRows_(SwTabCols &rToFill, const SwFrame *pBox) const
Definition: fetab.cxx:690
bool GetBoxBackground(std::unique_ptr< SvxBrushItem > &rToFill) const
FALSE ambiguous.
Definition: fetab.cxx:906
sal_uInt16 GetRowSelectionFromTop() const
Definition: fetab.cxx:1173
void InsertRow(sal_uInt16 nCnt, bool bBehind)
Definition: fetab.cxx:173
bool IsAdjustCellWidthAllowed(bool bBalance=false) const
Not allowed if only empty cells are selected.
Definition: fetab.cxx:1243
SAL_DLLPRIVATE void EndAllActionAndCall()
Terminate actions for all shells and call ChangeLink.
Definition: fews.cxx:69
std::unique_ptr< SwFormatRowSplit > GetRowSplit() const
Definition: fetab.cxx:833
SAL_DLLPRIVATE void ClearColumnRowCache(SwTabFrame const *)
Definition: fetab.cxx:2221
bool DeleteTableSel()
Current selection, may be whole table.
Definition: fetab.cxx:1397
void SetRowsToRepeat(sal_uInt16 nNumOfRows)
Definition: fetab.cxx:1120
void UnProtectTables()
Unprotect all tables in selection.
Definition: fetab.cxx:1069
void SetTabBorders(const SfxItemSet &rSet)
Definition: fetab.cxx:875
static SAL_DLLPRIVATE sal_uInt16 GetCurColNum_(const SwFrame *pFrame, SwGetCurColNumPara *pPara)
Definition: fews.cxx:599
bool CanUnProtectCells() const
Definition: fetab.cxx:1084
void UnProtectCells()
Refers to table selection.
Definition: fetab.cxx:1042
bool GetTableAutoFormat(SwTableAutoFormat &rGet)
Definition: fetab.cxx:1370
void GetTabRows(SwTabCols &rToFill) const
Definition: fetab.cxx:772
SwTab WhichMouseTabCol(const Point &rPt) const
Definition: fetab.cxx:2014
void SetTabBackground(const SvxBrushItem &rNew)
Definition: fetab.cxx:943
bool IsMouseTableRightToLeft(const Point &rPt) const
Definition: fetab.cxx:2429
void GetMouseTabCols(SwTabCols &rToFill, const Point &rPt) const
Definition: fetab.cxx:2151
void SetTabLineStyle(const Color *pColor, bool bSetLine=false, const editeng::SvxBorderLine *pBorderLine=nullptr)
Definition: fetab.cxx:883
void SplitTab(bool bVert, sal_uInt16 nCnt, bool bSameHeight)
Split cell vertically or horizontally.
Definition: fetab.cxx:587
void AdjustCellWidth(const bool bBalance, const bool bNoShrink)
Definition: fetab.cxx:1229
bool DeleteRow(bool bCompleteTable=false)
Definition: fetab.cxx:322
void ProtectCells()
If a table selection exists it is destroyed in case cursor is not allowed in readonly.
Definition: fetab.cxx:1022
void GetTabBorders(SfxItemSet &rSet) const
Definition: fetab.cxx:893
bool HasWholeTabSelection() const
Definition: fetab.cxx:963
bool UpdateTableStyleFormatting(SwTableNode *pTableNode=nullptr, bool bResetDirect=false, OUString const *pStyleName=nullptr)
Update the direct formatting according to the current table style.
Definition: fetab.cxx:1323
void ParkCursorInTab()
Definition: fetab.cxx:91
sal_uInt16 GetCurMouseColNum(const Point &rPt) const
Definition: fetab.cxx:2171
bool SelTableRowCol(const Point &rPt, const Point *pEnd, bool bRowDrag)
pEnd will be used during MouseMove
Definition: fetab.cxx:1897
size_t GetCurMouseTabColNum(const Point &rPt) const
Definition: fetab.cxx:2176
void SetColRowWidthHeight(TableChgWidthHeightType eType, sal_uInt16 nDiff)
Definition: fetab.cxx:2262
std::unique_ptr< SwFormatFrameSize > GetRowHeight() const
Pointer must be destroyed by caller != 0.
Definition: fetab.cxx:846
size_t GetCurTabColNum() const
Definition: fetab.cxx:1439
static bool IsVerticalModeAtNdAndPos(const SwTextNode &_rTextNode, const Point &_rDocPos)
Definition: fetab.cxx:2123
sal_uInt16 GetBoxAlign() const
USHRT_MAX if ambiguous.
Definition: fetab.cxx:938
void GetTabBackground(std::unique_ptr< SvxBrushItem > &rToFill) const
Definition: fetab.cxx:956
bool GetBoxDirection(std::unique_ptr< SvxFrameDirectionItem > &rToFill) const
FALSE ambiguous.
Definition: fetab.cxx:922
void GetMouseTabRows(SwTabCols &rToFill, const Point &rPt) const
Definition: fetab.cxx:806
SAL_DLLPRIVATE bool CheckHeadline(bool bRepeat) const
Definition: fetab.cxx:1206
bool IsTableRightToLeft() const
Definition: fetab.cxx:2420
void SetTableAttr(const SfxItemSet &)
Definition: fetab.cxx:2246
TableMergeErr MergeTab()
Merge selected parts of table.
Definition: fetab.cxx:555
void SetBoxDirection(const SvxFrameDirectionItem &rNew)
Definition: fetab.cxx:914
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:94
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:106
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
std::unique_ptr< SvxBrushItem > makeBackgroundBrushItem(bool=true) const
Definition: format.cxx:736
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsRowFrame() const
Definition: frame.hxx:1228
bool IsCellFrame() const
Definition: frame.hxx:1232
bool IsTextFrame() const
Definition: frame.hxx:1240
tools::Long GetPrtLeft() const
Definition: ssfrm.cxx:52
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * FindNext()
Definition: frame.hxx:1147
SwFrame * GetNext()
Definition: frame.hxx:682
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:554
bool IsTabFrame() const
Definition: frame.hxx:1224
bool IsInTab() const
Definition: frame.hxx:961
bool IsRightToLeft() const
Definition: frame.hxx:993
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
tools::Long GetPrtTop() const
Definition: ssfrm.cxx:58
bool IsVertical() const
Definition: frame.hxx:979
SwFrame * GetPrev()
Definition: frame.hxx:683
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:217
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
bool IsLayoutFrame() const
Definition: frame.hxx:1176
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:233
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:401
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:72
const SwFrame * Lower() const
Definition: layfrm.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:903
SwNodeOffset GetIndex() const
Definition: node.hxx:312
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ... including anchor in case of fra...
Definition: node.cxx:449
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:439
SwDoc & GetDoc()
Definition: node.hxx:233
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:724
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:728
SwContentNode * GetContentNode()
Definition: node.hxx:666
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:733
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1333
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:642
void Exchange()
Definition: pam.cxx:656
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:668
const SwPosition * End() const
Definition: pam.hxx:271
void DeleteMark()
Definition: pam.hxx:231
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
A page of the document layout.
Definition: pagefrm.hxx:59
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:133
bool IsVert() const
Definition: frame.hxx:1372
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1387
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1386
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1382
tools::Long XDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1427
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1388
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1428
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1384
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1385
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
Point TopLeft() const
Definition: swrect.hxx:254
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
Point BottomLeft() const
Definition: swrect.hxx:262
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
bool IsNear(const Point &rPoint, tools::Long nTolerance) const
Definition: swrect.hxx:365
void Pos(const Point &rNew)
Definition: swrect.hxx:171
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
Point Center() const
Definition: swrect.hxx:338
Point BottomRight() const
Definition: swrect.hxx:266
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
Point TopRight() const
Definition: swrect.hxx:258
void Width(tools::Long nNew)
Definition: swrect.hxx:189
vector_type::size_type size_type
Definition: docary.hxx:222
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:425
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:29
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
const Point & GetPtPos() const
Definition: viscrs.hxx:165
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:939
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:1133
size_t size() const
Definition: sortedobjs.cxx:43
size_t Count() const
Definition: tabcol.hxx:65
tools::Long GetLeft() const
Definition: tabcol.hxx:78
tools::Long GetLeftMin() const
Definition: tabcol.hxx:77
tools::Long GetRight() const
Definition: tabcol.hxx:79
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:773
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:252
const SwTable * GetTable() const
Definition: tabfrm.hxx:160
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5824
void AddAutoFormat(const SwTableAutoFormat &rFormat)
Append table style to the existing styles.
Definition: tblafmt.cxx:938
SwTableAutoFormat * FindAutoFormat(std::u16string_view rName) const
Find table style with the provided name, return nullptr when not found.
Definition: tblafmt.cxx:990
const OUString & GetName() const
Definition: tblafmt.hxx:202
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:436
SwTableLine * GetUpper()
Definition: swtable.hxx:470
sal_uInt16 IsFormulaOrValueBox() const
Definition: swtable.cxx:2840
SwNodeOffset GetSttIdx() const
Definition: swtable.cxx:2138
OUString GetName() const
Definition: swtable.cxx:2085
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:474
SwTableLines & GetTabLines()
Definition: swtable.hxx:467
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *) const
Definition: tblrwcl.cxx:2319
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:488
SwTableBox * FindNextBox(const SwTable &, const SwTableBox *, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2308
size_t GetSelectedBoxesCount() const
Definition: swcrsr.hxx:279
void GetBoxesOfFormula(const SwTable &rTable, SwSelBoxes &rBoxes)
Definition: cellfml.cxx:924
SwTableLine is one table row in the document model.
Definition: swtable.hxx:374
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:384
bool IsDeleted(SwRedlineTable::size_type &rRedlinePos) const
Definition: swtable.cxx:1842
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *=nullptr, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2252
SwTableBox * FindNextBox(const SwTable &, const SwTableBox *=nullptr, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2201
size_type size() const
Definition: swtable.hxx:76
SwTableLine * back() const
Definition: swtable.hxx:82
const SwTable & GetTable() const
Definition: node.hxx:542
void MakeOwnFrames(SwPosition *pIdxBehind=nullptr)
Creates the frms for the table node (i.e.
Definition: ndtbl.cxx:2363
void DelFrames(SwRootFrame const *pLayout=nullptr)
Method deletes all views of document for the node.
Definition: ndtbl.cxx:2410
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
void SetHTMLTableLayout(std::shared_ptr< SwHTMLTableLayout > const &r)
Definition: swtable.cxx:2230
const OUString & GetTableStyleName() const
Return the table style name of this table.
Definition: swtable.hxx:196
bool IsDeleted() const
Definition: swtable.cxx:1601
SwTableLines & GetTabLines()
Definition: swtable.hxx:206
bool IsTableComplex() const
Definition: swtable.cxx:1444
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:201
SwTableSortBoxes & GetTabSortBoxes()
Definition: swtable.hxx:267
void GetTabCols(SwTabCols &rToFill, const SwTableBox *pStart, bool bHidden=false, bool bCurRowOnly=false) const
Definition: swtable.cxx:517
bool IsNewModel() const
Definition: swtable.hxx:193
TableChgMode GetTableChgMode() const
Definition: swtable.hxx:338
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:166
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
const OUString & GetText() const
Definition: ndtxt.hxx:244
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2177
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2159
vcl::Window * GetWin() const
Definition: viewsh.hxx:346
SwDoc * GetDoc() const
Definition: viewsh.hxx:290
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
double scalar(const B2DVector &rVec) const
double cross(const B2DVector &rVec) const
double getLength() const
const Value & back() const
bool empty() const
size_type size() const
std::pair< const_iterator, bool > insert(Value &&x)
ring_container GetRingContainer()
Definition: ring.hxx:240
Point PixelToLogic(const Point &rDevicePt) const
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:19
SwTab
Definition: fesh.hxx:182
@ ROW_VERT
@ ROWSEL_HORI_RTL
@ SEL_HORI
@ SEL_VERT
@ COL_NONE
@ COL_HORI
@ COLSEL_VERT
@ COLSEL_HORI
@ SEL_HORI_RTL
@ ROWSEL_VERT
@ COL_VERT
@ ROWSEL_HORI
@ ROW_HORI
static Point lcl_ProjectOntoClosestTableFrame(const SwTabFrame &rTab, const Point &rPoint, bool bRowDrag)
Definition: fetab.cxx:1802
#define COLFUZZY
Definition: fetab.cxx:70
static bool IsSame(tools::Long nA, tools::Long nB)
Definition: fetab.cxx:72
static const SwCellFrame * lcl_FindFrame(const SwLayoutFrame *pLay, const Point &rPt, SwTwips nFuzzy, bool *pbRow, bool *pbCol)
Definition: fetab.cxx:1530
#define ENHANCED_TABLE_SELECTION_FUZZY
Definition: fetab.cxx:1722
static sal_uInt16 lcl_GetRowNumber(const SwPosition &rPos)
Definition: fetab.cxx:1135
static bool lcl_IsFormulaSelBoxes(const SwTable &rTable, const SwTableBoxFormula &rFormula, SwCellFrames &rCells)
Definition: fetab.cxx:2306
void ClearFEShellTabCols(SwDoc &rDoc, SwTabFrame const *const pFrame)
Definition: fetab.cxx:2206
static double lcl_DistancePoint2Segment(const Point &rA, const Point &rB, const Point &rC)
Definition: fetab.cxx:1773
static const SwFrame * lcl_FindFrameInTab(const SwLayoutFrame *pLay, const Point &rPt, SwTwips nFuzzy)
Definition: fetab.cxx:1506
DocumentType eType
SvxFrameDirection
const SwContentFrame * GetCellContent(const SwLayoutFrame &rCell_)
method to get the content of the table cell
Definition: frmtool.cxx:3997
constexpr TypedWhichId< SwTableBoxValue > RES_BOXATR_VALUE(158)
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(157)
constexpr TypedWhichId< SvxProtectItem > RES_PROTECT(106)
constexpr TypedWhichId< SvxPrintItem > RES_PRINT(104)
sal_Int64 n
const long LONG_MAX
int i
long Long
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:1020
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1180
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:60
constexpr auto RULER_MOUSE_MARGINWIDTH
static SfxItemSet & rSet
sal_uIntPtr sal_uLong
static bool bCol
Definition: srtdlg.cxx:56
union SwContentAtPos::@24 aFnd
SwContentNode * pNode
Definition: crsrsh.hxx:107
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:230
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
#define ERR_TBLINSCOL_ERROR
Definition: swerror.h:36
#define ERR_TBLDDECHG_ERROR
Definition: swerror.h:37
#define ERR_TBLSPLIT_ERROR
Definition: swerror.h:35
tools::Long SwTwips
Definition: swtypes.hxx:51
@ UI_TABLE_DELETE
TableMergeErr
Definition: tblenum.hxx:64
constexpr TableChgWidthHeightType extractPosition(TableChgWidthHeightType e)
Definition: tblenum.hxx:43
TableChgWidthHeightType
Definition: tblenum.hxx:27
void ForEach_FndLineCopyCol(SwTableLines &rLines, FndPara *pFndPara)
This creates a structure mirroring the SwTable structure that contains all rows and non-leaf boxes (a...
Definition: tblsel.cxx:2090
void GetTableSelCrs(const SwCursorShell &rShell, SwSelBoxes &rBoxes)
Definition: tblsel.cxx:124
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:149
bool CheckSplitCells(const SwCursorShell &rShell, sal_uInt16 nDiv, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:1949
bool HasProtectedCells(const SwSelBoxes &rBoxes)
Definition: tblsel.cxx:854
SwTableSearchType
Definition: tblsel.hxx:59
std::deque< SwCellFrame * > SwCellFrames
Definition: tblsel.hxx:41