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