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