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