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