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