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( long nA, 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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 long nLeftMin = ( aRectFnSet.IsVert() ?
580  pTab->GetPrtLeft() - pPage->getFrameArea().Left() :
581  pTab->GetPrtTop() - pPage->getFrameArea().Top() );
582  const long nLeft = aRectFnSet.IsVert() ? LONG_MAX : 0;
583  const long nRight = aRectFnSet.GetHeight(pTab->getFramePrintArea());
584  const 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( this );
697  StartAllAction();
698  GetDoc()->SetTabRows( rNew, bCurColOnly, static_cast<const SwCellFrame*>(pBox) );
700  }
701 }
702 
704 {
705  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  if( nullptr != ( pNd = rPos.nNode.GetNode().GetContentNode() ))
1021  pFrame = pNd->getLayoutFrame(pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &rPos, &tmp);
1022  else
1023  pFrame = nullptr;
1024 
1025  const SwFrame* pRow = (pFrame && pFrame->IsInTab()) ? pFrame->GetUpper() : nullptr;
1026 
1027  while (pRow && (!pRow->GetUpper() || !pRow->GetUpper()->IsTabFrame()))
1028  pRow = pRow->GetUpper();
1029 
1030  if (!pRow)
1031  return USHRT_MAX;
1032 
1033  const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pRow->GetUpper());
1034  const SwTableLine* pTabLine = static_cast<const SwRowFrame*>(pRow)->GetTabLine();
1035  sal_uInt16 nRet = USHRT_MAX;
1036  sal_uInt16 nI = 0;
1037  while ( sal::static_int_cast<SwTableLines::size_type>(nI) < pTabFrame->GetTable()->GetTabLines().size() )
1038  {
1039  if ( pTabFrame->GetTable()->GetTabLines()[ nI ] == pTabLine )
1040  {
1041  nRet = nI;
1042  break;
1043  }
1044  ++nI;
1045  }
1046 
1047  return nRet;
1048 }
1049 
1051 {
1052  sal_uInt16 nRet = 0;
1053  const SwPaM* pPaM = IsTableMode() ? GetTableCursor() : GetCursor_();
1054  const sal_uInt16 nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() );
1055 
1056  if ( !IsTableMode() )
1057  {
1058  nRet = 0 == nPtLine ? 1 : 0;
1059  }
1060  else
1061  {
1062  const sal_uInt16 nMkLine = lcl_GetRowNumber( *pPaM->GetMark() );
1063 
1064  if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) ||
1065  ( nMkLine == 0 && nPtLine != USHRT_MAX ) )
1066  {
1067  nRet = std::max( nPtLine, nMkLine ) + 1;
1068  }
1069  }
1070 
1071  return nRet;
1072 }
1073 
1074 /*
1075  * 1. case: bRepeat = true
1076  * returns true if the current frame is located inside a table headline in
1077  * a follow frame
1078  *
1079  * 2. case: bRepeat = false
1080  * returns true if the current frame is located inside a table headline OR
1081  * inside the first line of a table!!!
1082  */
1083 bool SwFEShell::CheckHeadline( bool bRepeat ) const
1084 {
1085  bool bRet = false;
1086  if ( !IsTableMode() )
1087  {
1088  SwFrame *pFrame = GetCurrFrame(); // DONE MULTIIHEADER
1089  SwTabFrame* pTab = (pFrame && pFrame->IsInTab()) ? pFrame->FindTabFrame() : nullptr;
1090  if (pTab)
1091  {
1092  if ( bRepeat )
1093  {
1094  bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrame );
1095  }
1096  else
1097  {
1098  bRet = static_cast<SwLayoutFrame*>(pTab->Lower())->IsAnLower( pFrame ) ||
1099  pTab->IsInHeadline( *pFrame );
1100  }
1101  }
1102  }
1103  return bRet;
1104 }
1105 
1106 void SwFEShell::AdjustCellWidth( const bool bBalance, const bool bNoShrink )
1107 {
1108  SET_CURR_SHELL( this );
1109  StartAllAction();
1110 
1111  // switch on wait-cursor, as we do not know how
1112  // much content is affected
1113  TableWait aWait(std::numeric_limits<size_t>::max(), nullptr,
1114  *GetDoc()->GetDocShell());
1115 
1116  GetDoc()->AdjustCellWidth( *getShellCursor( false ), bBalance, bNoShrink );
1118 }
1119 
1120 bool SwFEShell::IsAdjustCellWidthAllowed( bool bBalance ) const
1121 {
1122  // at least one row with content should be contained in the selection
1123 
1124  SwFrame *pFrame = GetCurrFrame();
1125  if( !pFrame || !pFrame->IsInTab() )
1126  return false;
1127 
1128  SwSelBoxes aBoxes;
1129  ::GetTableSelCrs( *this, aBoxes );
1130 
1131  if ( bBalance )
1132  return aBoxes.size() > 1;
1133 
1134  if ( aBoxes.empty() )
1135  {
1136  do
1137  {
1138  pFrame = pFrame->GetUpper();
1139  }
1140  while (pFrame && !pFrame->IsCellFrame());
1141 
1142  if (!pFrame)
1143  return false;
1144 
1145  SwTableBox *pBox = const_cast<SwTableBox*>(static_cast<SwCellFrame*>(pFrame)->GetTabBox());
1146  aBoxes.insert( pBox );
1147  }
1148 
1149  for (size_t i = 0; i < aBoxes.size(); ++i)
1150  {
1151  SwTableBox *pBox = aBoxes[i];
1152  if ( pBox->GetSttNd() )
1153  {
1154  SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
1155  SwTextNode* pCNd = aIdx.GetNode().GetTextNode();
1156  if( !pCNd )
1157  pCNd = static_cast<SwTextNode*>(GetDoc()->GetNodes().GoNext( &aIdx ));
1158 
1159  while ( pCNd )
1160  {
1161  if (!pCNd->GetText().isEmpty())
1162  return true;
1163  ++aIdx;
1164  pCNd = aIdx.GetNode().GetTextNode();
1165  }
1166  }
1167  }
1168  return false;
1169 }
1170 
1171 bool SwFEShell::SetTableStyle(const OUString& rStyleName)
1172 {
1173  // make sure SwDoc has the style
1174  SwTableAutoFormat *pTableFormat = GetDoc()->GetTableStyles().FindAutoFormat(rStyleName);
1175  if (!pTableFormat)
1176  return false;
1177 
1178  SwTableNode *pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1179  if (!pTableNode)
1180  return false;
1181 
1182  // set the name & update
1183  return UpdateTableStyleFormatting(pTableNode, false, &rStyleName);
1184 }
1185 
1186  // AutoFormat for the table/table selection
1188 {
1189  // make sure SwDoc has the style
1190  GetDoc()->GetTableStyles().AddAutoFormat(rStyle);
1191 
1192  SwTableNode *pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1193  if (!pTableNode)
1194  return false;
1195 
1196  // set the name & update
1197  return UpdateTableStyleFormatting(pTableNode, false, &rStyle.GetName());
1198 }
1199 
1201  bool bResetDirect, OUString const*const pStyleName)
1202 {
1203  if (!pTableNode)
1204  {
1205  pTableNode = const_cast<SwTableNode*>(IsCursorInTable());
1206  if (!pTableNode || pTableNode->GetTable().IsTableComplex())
1207  return false;
1208  }
1209 
1210  OUString const aTableStyleName(pStyleName
1211  ? *pStyleName
1212  : pTableNode->GetTable().GetTableStyleName());
1213  SwTableAutoFormat* pTableStyle = GetDoc()->GetTableStyles().FindAutoFormat(aTableStyleName);
1214  if (!pTableStyle)
1215  return false;
1216 
1217  SwSelBoxes aBoxes;
1218 
1219  // whole table or only current selection
1220  if( IsTableMode() )
1221  ::GetTableSelCrs( *this, aBoxes );
1222  else
1223  {
1224  const SwTableSortBoxes& rTBoxes = pTableNode->GetTable().GetTabSortBoxes();
1225  for (size_t n = 0; n < rTBoxes.size(); ++n)
1226  {
1227  SwTableBox* pBox = rTBoxes[ n ];
1228  aBoxes.insert( pBox );
1229  }
1230  }
1231 
1232  bool bRet;
1233  if( !aBoxes.empty() )
1234  {
1235  SET_CURR_SHELL( this );
1236  StartAllAction();
1237  bRet = GetDoc()->SetTableAutoFormat(
1238  aBoxes, *pTableStyle, bResetDirect, pStyleName != nullptr);
1239  ClearFEShellTabCols(*GetDoc(), nullptr);
1241  }
1242  else
1243  bRet = false;
1244  return bRet;
1245 }
1246 
1248 {
1249  const SwTableNode *pTableNd = IsCursorInTable();
1250  if( !pTableNd || pTableNd->GetTable().IsTableComplex() )
1251  return false;
1252 
1253  SwSelBoxes aBoxes;
1254 
1255  if ( !IsTableMode() ) // if cursor are not current
1256  GetCursor();
1257 
1258  // whole table or only current selection
1259  if( IsTableMode() )
1260  ::GetTableSelCrs( *this, aBoxes );
1261  else
1262  {
1263  const SwTableSortBoxes& rTBoxes = pTableNd->GetTable().GetTabSortBoxes();
1264  for (size_t n = 0; n < rTBoxes.size(); ++n)
1265  {
1266  SwTableBox* pBox = rTBoxes[ n ];
1267  aBoxes.insert( pBox );
1268  }
1269  }
1270 
1271  return GetDoc()->GetTableAutoFormat( aBoxes, rGet );
1272 }
1273 
1275 {
1276  // check if SPoint/Mark of current cursor are in a table
1277  SwFrame *pFrame = GetCurrFrame();
1278  if( !pFrame || !pFrame->IsInTab() )
1279  return false;
1280 
1281  if( dynamic_cast< const SwDDETable* >(pFrame->ImplFindTabFrame()->GetTable()) != nullptr )
1282  {
1284  DialogMask::MessageInfo | DialogMask::ButtonsOk );
1285  return false;
1286  }
1287 
1288  SET_CURR_SHELL( this );
1289  StartAllAction();
1290 
1291  // search boxes via the layout
1292  bool bRet;
1293  SwSelBoxes aBoxes;
1294  GetTableSelCrs( *this, aBoxes );
1295  if( !aBoxes.empty() )
1296  {
1297  TableWait aWait( aBoxes.size(), pFrame, *GetDoc()->GetDocShell() );
1298 
1299  // cursor should be removed from deletion area.
1300  // Put them behind/on the table; via the document
1301  // position they'll be set to the old position
1302  while( !pFrame->IsCellFrame() )
1303  pFrame = pFrame->GetUpper();
1304  ParkCursor( SwNodeIndex( *static_cast<SwCellFrame*>(pFrame)->GetTabBox()->GetSttNd() ));
1305 
1306  bRet = GetDoc()->DeleteRowCol( aBoxes );
1307 
1308  ClearFEShellTabCols(*GetDoc(), nullptr);
1309  }
1310  else
1311  bRet = false;
1313  return bRet;
1314 }
1315 
1317 {
1319  SwFrame *pFrame = GetCurrFrame();
1320  OSL_ENSURE( pFrame, "Cursor parked?" );
1321 
1322  // check if SPoint/Mark of current cursor are in a table
1323  if (!pFrame || !pFrame->IsInTab())
1324  return 0;
1325 
1326  do
1327  {
1328  // JP 26.09.95: why compare with ContentFrame
1329  // and not with CellFrame ????
1330  pFrame = pFrame->GetUpper();
1331  } while (pFrame && !pFrame->IsCellFrame());
1332 
1333  if (!pFrame)
1334  return 0;
1335 
1336  size_t nRet = 0;
1337 
1338  SwRectFnSet aRectFnSet(pFrame);
1339 
1340  const SwPageFrame* pPage = pFrame->FindPageFrame();
1341 
1342  // get TabCols, as only via these we get to the position
1343  SwTabCols aTabCols;
1344  GetTabCols( aTabCols );
1345 
1346  if( pFrame->FindTabFrame()->IsRightToLeft() )
1347  {
1348  long nX = aRectFnSet.GetRight(pFrame->getFrameArea()) - aRectFnSet.GetLeft(pPage->getFrameArea());
1349 
1350  const long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();
1351 
1352  if ( !::IsSame( nX, nRight ) )
1353  {
1354  nX = nRight - nX + aTabCols.GetLeft();
1355  for ( size_t i = 0; i < aTabCols.Count(); ++i )
1356  if ( ::IsSame( nX, aTabCols[i] ) )
1357  {
1358  nRet = i + 1;
1359  break;
1360  }
1361  }
1362  }
1363  else
1364  {
1365  const long nX = aRectFnSet.GetLeft(pFrame->getFrameArea()) -
1366  aRectFnSet.GetLeft(pPage->getFrameArea());
1367 
1368  const long nLeft = aTabCols.GetLeftMin();
1369 
1370  if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
1371  {
1372  for ( size_t i = 0; i < aTabCols.Count(); ++i )
1373  if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
1374  {
1375  nRet = i + 1;
1376  break;
1377  }
1378  }
1379  }
1380  return nRet;
1381 }
1382 
1383 static const SwFrame *lcl_FindFrameInTab( const SwLayoutFrame *pLay, const Point &rPt, SwTwips nFuzzy )
1384 {
1385  const SwFrame *pFrame = pLay->Lower();
1386 
1387  while( pFrame && pLay->IsAnLower( pFrame ) )
1388  {
1389  if ( pFrame->getFrameArea().IsNear( rPt, nFuzzy ) )
1390  {
1391  if ( pFrame->IsLayoutFrame() )
1392  {
1393  const SwFrame *pTmp = ::lcl_FindFrameInTab( static_cast<const SwLayoutFrame*>(pFrame), rPt, nFuzzy );
1394  if ( pTmp )
1395  return pTmp;
1396  }
1397 
1398  return pFrame;
1399  }
1400 
1401  pFrame = pFrame->FindNext();
1402  }
1403 
1404  return nullptr;
1405 }
1406 
1407 static const SwCellFrame *lcl_FindFrame( const SwLayoutFrame *pLay, const Point &rPt,
1408  SwTwips nFuzzy, bool* pbRow, bool* pbCol )
1409 {
1410  // bMouseMoveRowCols :
1411  // Method is called for
1412  // - Moving columns/rows with the mouse or
1413  // - Enhanced table selection
1414  const bool bMouseMoveRowCols = nullptr == pbCol;
1415 
1416  bool bCloseToRow = false;
1417  bool bCloseToCol = false;
1418 
1419  const SwFrame *pFrame = pLay->ContainsContent();
1420  const SwFrame* pRet = nullptr;
1421 
1422  if ( pFrame )
1423  {
1424  do
1425  {
1426  if ( pFrame->IsInTab() )
1427  pFrame = const_cast<SwFrame*>(pFrame)->ImplFindTabFrame();
1428 
1429  if (!pFrame)
1430  break;
1431 
1432  if ( pFrame->IsTabFrame() )
1433  {
1434  Point aPt( rPt );
1435  bool bSearchForFrameInTab = true;
1436  SwTwips nTmpFuzzy = nFuzzy;
1437 
1438  if ( !bMouseMoveRowCols )
1439  {
1440  // We ignore nested tables for the enhanced table selection:
1441  while ( pFrame->GetUpper()->IsInTab() )
1442  pFrame = pFrame->GetUpper()->FindTabFrame();
1443 
1444  // We first check if the given point is 'close' to the left or top
1445  // border of the table frame:
1446  OSL_ENSURE( pFrame, "Nested table frame without outer table" );
1447  SwRectFnSet aRectFnSet(pFrame);
1448  const bool bRTL = pFrame->IsRightToLeft();
1449 
1450  SwRect aTabRect = pFrame->getFramePrintArea();
1451  aTabRect.Pos() += pFrame->getFrameArea().Pos();
1452 
1453  const SwTwips nLeft = bRTL ?
1454  aRectFnSet.GetRight(aTabRect) :
1455  aRectFnSet.GetLeft(aTabRect);
1456  const SwTwips nTop = aRectFnSet.GetTop(aTabRect);
1457 
1458  SwTwips const rPointX = aRectFnSet.IsVert() ? aPt.Y() : aPt.X();
1459  SwTwips const rPointY = aRectFnSet.IsVert() ? aPt.X() : aPt.Y();
1460 
1461  const SwTwips nXDiff = aRectFnSet.XDiff( nLeft, rPointX ) * ( bRTL ? -1 : 1 );
1462  const SwTwips nYDiff = aRectFnSet.YDiff( nTop, rPointY );
1463 
1464  bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy;
1465  bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy;
1466 
1467  if ( bCloseToCol && 2 * nYDiff > nFuzzy )
1468  {
1469  const SwFrame* pPrev = pFrame->GetPrev();
1470  if ( pPrev )
1471  {
1472  SwRect aPrevRect = pPrev->getFramePrintArea();
1473  aPrevRect.Pos() += pPrev->getFrameArea().Pos();
1474 
1475  if( aPrevRect.IsInside( rPt ) )
1476  {
1477  bCloseToCol = false;
1478  }
1479  }
1480 
1481  }
1482 
1483  // If we found the point to be 'close' to the left or top border
1484  // of the table frame, we adjust the point to be on that border:
1485  if ( bCloseToRow && bCloseToCol )
1486  aPt = bRTL ? aTabRect.TopRight() : aRectFnSet.GetPos(aTabRect);
1487  else if ( bCloseToRow )
1488  aRectFnSet.IsVert() ? aPt.setY(nLeft) : aPt.setX(nLeft);
1489  else if ( bCloseToCol )
1490  aRectFnSet.IsVert() ? aPt.setX(nTop) : aPt.setY(nTop);
1491 
1492  if ( !bCloseToRow && !bCloseToCol )
1493  bSearchForFrameInTab = false;
1494 
1495  // Since the point has been adjusted, we call lcl_FindFrameInTab()
1496  // with a fuzzy value of 1:
1497  nTmpFuzzy = 1;
1498  }
1499 
1500  const SwFrame* pTmp = bSearchForFrameInTab ?
1501  ::lcl_FindFrameInTab( static_cast<const SwLayoutFrame*>(pFrame), aPt, nTmpFuzzy ) :
1502  nullptr;
1503 
1504  if ( pTmp )
1505  {
1506  pFrame = pTmp;
1507  break;
1508  }
1509  }
1510  pFrame = pFrame->FindNextCnt();
1511 
1512  } while ( pFrame && pLay->IsAnLower( pFrame ) );
1513  }
1514 
1515  if ( pFrame && pFrame->IsInTab() && pLay->IsAnLower( pFrame ) )
1516  {
1517  do
1518  {
1519  // We allow mouse drag of table borders within nested tables,
1520  // but disallow hotspot selection of nested tables.
1521  if ( bMouseMoveRowCols )
1522  {
1523  // find the next cell frame
1524  while ( pFrame && !pFrame->IsCellFrame() )
1525  pFrame = pFrame->GetUpper();
1526  }
1527  else
1528  {
1529  // find the most upper cell frame:
1530  while ( pFrame &&
1531  ( !pFrame->IsCellFrame() ||
1532  !pFrame->GetUpper()->GetUpper()->IsTabFrame() ||
1533  pFrame->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
1534  pFrame = pFrame->GetUpper();
1535  }
1536 
1537  if ( pFrame ) // Note: this condition should be the same like the while condition!!!
1538  {
1539  // #i32329# Enhanced table selection
1540  // used for hotspot selection of tab/cols/rows
1541  if ( !bMouseMoveRowCols )
1542  {
1543 
1544  OSL_ENSURE( pbCol && pbRow, "pbCol or pbRow missing" );
1545 
1546  if ( bCloseToRow || bCloseToCol )
1547  {
1548  *pbRow = bCloseToRow;
1549  *pbCol = bCloseToCol;
1550  pRet = pFrame;
1551  break;
1552  }
1553  }
1554  else
1555  {
1556  // used for mouse move of columns/rows
1557  const SwTabFrame* pTabFrame = pFrame->FindTabFrame();
1558  SwRect aTabRect = pTabFrame->getFramePrintArea();
1559  aTabRect.Pos() += pTabFrame->getFrameArea().Pos();
1560 
1561  SwRectFnSet aRectFnSet(pTabFrame);
1562 
1563  const SwTwips nTabTop = aRectFnSet.GetTop(aTabRect);
1564  const SwTwips nMouseTop = aRectFnSet.IsVert() ? rPt.X() : rPt.Y();
1565 
1566  // Do not allow to drag upper table border:
1567  if ( !::IsSame( nTabTop, nMouseTop ) )
1568  {
1569  if ( ::IsSame( pFrame->getFrameArea().Left(), rPt.X() ) ||
1570  ::IsSame( pFrame->getFrameArea().Right(),rPt.X() ) )
1571  {
1572  if ( pbRow ) *pbRow = false;
1573  pRet = pFrame;
1574  break;
1575  }
1576  if ( ::IsSame( pFrame->getFrameArea().Top(), rPt.Y() ) ||
1577  ::IsSame( pFrame->getFrameArea().Bottom(),rPt.Y() ) )
1578  {
1579  if ( pbRow ) *pbRow = true;
1580  pRet = pFrame;
1581  break;
1582  }
1583  }
1584  }
1585 
1586  pFrame = pFrame->GetUpper();
1587  }
1588  } while ( pFrame );
1589  }
1590 
1591  // robust:
1592  OSL_ENSURE( !pRet || pRet->IsCellFrame(), "lcl_FindFrame() is supposed to find a cell frame!" );
1593  return pRet && pRet->IsCellFrame() ? static_cast<const SwCellFrame*>(pRet) : nullptr;
1594 }
1595 
1596 // pbCol = 0 => Used for moving table rows/cols with mouse
1597 // pbCol != 0 => Used for selecting table/rows/cols
1598 
1599 #define ENHANCED_TABLE_SELECTION_FUZZY 10
1600 
1601 const SwFrame* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const
1602 {
1603  const SwPageFrame *pPage = static_cast<SwPageFrame*>(GetLayout()->Lower());
1604  vcl::Window* pOutWin = GetWin();
1605  SwTwips nFuzzy = COLFUZZY;
1606  if( pOutWin )
1607  {
1608  // #i32329# Enhanced table selection
1610  Size aTmp( nSize, nSize );
1611  aTmp = pOutWin->PixelToLogic( aTmp );
1612  nFuzzy = aTmp.Width();
1613  }
1614 
1615  while ( pPage && !pPage->getFrameArea().IsNear( rPt, nFuzzy ) )
1616  pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1617 
1618  const SwCellFrame *pFrame = nullptr;
1619  if ( pPage )
1620  {
1621  // We cannot search the box by GetModelPositionForViewPoint or GetContentPos.
1622  // This would lead to a performance collapse for documents
1623  // with a lot of paragraphs/tables on one page
1624  //(BrowseMode!)
1625 
1626  // check flys first
1627  if ( pPage->GetSortedObjs() )
1628  {
1629  for ( size_t i = 0; !pFrame && i < pPage->GetSortedObjs()->size(); ++i )
1630  {
1631  SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
1632  if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr )
1633  {
1634  pFrame = lcl_FindFrame( static_cast<SwFlyFrame*>(pObj),
1635  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  SET_CURR_SHELL( 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 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 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  SET_CURR_SHELL( 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  SET_CURR_SHELL( 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  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:1444
long Width() const
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
SAL_DLLPRIVATE void EndAllActionAndCall()
Terminate actions for all shells and call ChangeLink.
Definition: fews.cxx: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
bool IsNumLabel(const Point &rPt, int nMaxOffset=-1)
Definition: fetab.cxx:1983
long GetPrtLeft() const
Definition: ssfrm.cxx:47
void DeleteMark()
Definition: pam.hxx:177
void KillPams()
Definition: crsrsh.cxx:1019
sal_uLong GetIndex() const
Definition: node.hxx:282
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
const Value & back() const
bool IsFollow() const
Definition: flowfrm.hxx:166
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx: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:2087
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:560
static void GetTabBorders(const SwCursor &rCursor, SfxItemSet &rSet)
Definition: ndtbl1.cxx:927
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:188
sal_uLong StartOfSectionIndex() const
Definition: node.hxx:673
bool IsLastCellInRow() const
Definition: fetab.cxx:246
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:173
SwTableAutoFormat * FindAutoFormat(const OUString &rName) const
Find table style with the provided name, return nullptr when not found.
Definition: tblafmt.cxx:996
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:1265
sal_uLong GetSttIdx() const
Definition: swtable.cxx:1879
SwDocShell * GetDocShell()
Definition: doc.hxx:1350
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
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:647
SAL_DLLPRIVATE bool CheckHeadline(bool bRepeat) const
Definition: fetab.cxx:1083
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:1601
void ProtectCells()
If a table selection exists it is destroyed in case cursor is not allowed in readonly.
Definition: fetab.cxx:900
long GetWidth() const
void InsertCol(sal_uInt16 nCnt, bool bBehind)
Definition: fetab.cxx:209
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3021
static void GetTabCols(SwTabCols &rFill, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2479
SAL_DLLPRIVATE void GetTabCols_(SwTabCols &rToFill, const SwFrame *pBox) const
Definition: fetab.cxx:503
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
long GetLeftMin() const
Definition: tabcol.hxx:76
const SwRect & getFramePrintArea() const
Definition: frame.hxx:178
void SetRowSplit(const SwCursor &rCursor, const SwFormatRowSplit &rNew)
Definition: ndtbl1.cxx:318
const SwPosition * GetMark() const
Definition: pam.hxx:209
void DeleteTable()
Definition: fetab.cxx:308
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:1148
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:872
Definition: doc.hxx:186
const SwShellTableCursor * GetTableCursor() const
Definition: crsrsh.hxx:649
void GetTabRows(SwTabCols &rToFill) const
Definition: fetab.cxx:650
static std::unique_ptr< SwFormatFrameSize > GetRowHeight(const SwCursor &rCursor)
Definition: ndtbl1.cxx:408
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:1294
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
bool DeleteCol()
Definition: fetab.cxx:262
constexpr auto RULER_MOUSE_MARGINWIDTH
void SetTabRows(const SwTabCols &rNew, bool bCurColOnly, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2724
bool IsNear(const Point &rPoint, long nTolerance) const
Definition: swrect.cxx:114
SwNode & GetNode() const
Definition: ndindex.hxx:119
long SwTwips
Definition: swtypes.hxx:49
bool HasProtectedCells(const SwSelBoxes &rBoxes)
Definition: tblsel.cxx:849
SvxFrameDirection
bool IsVert() const
Definition: frame.hxx:1345
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:193
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
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:944
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:2533
void UnProtectTables(const SwPaM &rPam)
Definition: ndtbl.cxx:4472
size_type size() const
Definition: swtable.hxx:74
void ForEach_FndLineCopyCol(SwTableLines &rLines, FndPara *pFndPara)
Definition: tblsel.cxx:2097
sal_uInt16 GetCurMouseColNum(const Point &rPt) const
Definition: fetab.cxx:2049
long GetRight() const
Definition: tabcol.hxx:78
static SAL_DLLPRIVATE sal_uInt16 GetCurColNum_(const SwFrame *pFrame, SwGetCurColNumPara *pPara)
Definition: fews.cxx:598
bool DeleteRowCol(const SwSelBoxes &rBoxes, bool bColumn=false)
Definition: ndtbl.cxx:1941
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:2193
void SetTabBackground(const SvxBrushItem &rNew)
Definition: fetab.cxx:821
long YDiff(long n1, long n2) const
Definition: frame.hxx:1401
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:2547
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:527
std::unique_ptr< SvxBrushItem > makeBackgroundBrushItem(bool=true) const
Definition: format.cxx:782
void Top(const long nTop)
Definition: swrect.hxx:204
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:1476
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:1200
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
#define ERR_TBLINSCOL_ERROR
Definition: swerror.h:37
#define ENHANCED_TABLE_SELECTION_FUZZY
Definition: fetab.cxx:1599
SwIndex nContent
Definition: pam.hxx:38
void SetBoxAttr(const SwCursor &rCursor, const SfxPoolItem &rNew)
Definition: ndtbl1.cxx:1148
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:1106
bool SetTableStyle(const OUString &rStyleName)
Set table style of the current table.
Definition: fetab.cxx:1171
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:4423
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:481
bool BalanceRowHeight(bool bTstOnly, const bool bOptimize=false)
Definition: fetab.cxx:729
void SetHTMLTableLayout(std::shared_ptr< SwHTMLTableLayout > const &r)
Definition: swtable.cxx:1941
const SwTable & GetTable() const
Definition: node.hxx:497
union SwContentAtPos::@24 aFnd
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
const OUString & GetTableStyleName() const
Return the table style name of this table.
Definition: swtable.hxx:188
bool SelTableRowCol(const Point &rPt, const Point *pEnd, bool bRowDrag)
pEnd will be used during MouseMove
Definition: fetab.cxx:1775
long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1357
long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1358
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *) const
Definition: tblrwcl.cxx:2311
void Right(const long nRight)
Definition: swrect.hxx:200
size_type size() const
void SetRowHeight(const SwCursor &rCursor, const SwFormatFrameSize &rNew)
Definition: ndtbl1.cxx:383
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:1193
void InsertRow(const SwCursor &rCursor, sal_uInt16 nCnt=1, bool bBehind=true)
Definition: ndtbl.cxx:1758
void SetWidth(long n)
static Point lcl_ProjectOntoClosestTableFrame(const SwTabFrame &rTab, const Point &rPoint, bool bRowDrag)
Definition: fetab.cxx:1680
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:172
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:332
void SetBoxAlign(const SwCursor &rCursor, sal_uInt16 nAlign)
Definition: ndtbl1.cxx:1256
SwTableSortBoxes & GetTabSortBoxes()
Definition: swtable.hxx:259
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:20
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
OUString GetName() const
Definition: swtable.cxx:1827
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:893
void SetTabCols(const SwTabCols &rNew, bool bCurRowOnly)
Definition: fetab.cxx:615
bool DeleteTableSel()
Current selection, may be whole table.
Definition: fetab.cxx:1274
A helper class to save cursor state (position).
Definition: swcrsr.hxx:230
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:715
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:118
int i
static bool bCol
Definition: srtdlg.cxx:56
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:149
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
void ParkCursorInTab()
Definition: fetab.cxx:88
void SetRowsToRepeat(sal_uInt16 nNumOfRows)
Definition: fetab.cxx:998
const SwPosition * GetPoint() const
Definition: pam.hxx:207
long XDiff(long n1, long n2) const
Definition: frame.hxx:1400
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:2851
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:565
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:691
SwContentNode * GetContentNode()
Definition: node.hxx:615
SwDoc * GetDoc()
Definition: node.hxx:702
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
long GetPrtTop() const
Definition: ssfrm.cxx:53
::rtl::Reference< Content > pContent
SwTextNode * GetNumRuleNodeAtPos(const Point &rPot)
Definition: fetab.cxx:1971
bool IsCursorReadonly() const
Definition: crsrsh.cxx:3275
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
bool IsRowFrame() const
Definition: frame.hxx:1200
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:393
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
#define SET_CURR_SHELL(shell)
Definition: swtypes.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
void GetTabCols(SwTabCols &rToFill) const
Info about columns and margins.
Definition: fetab.cxx:633
SwContentNode * pNode
Definition: crsrsh.hxx:102
ring_container GetRingContainer()
Definition: ring.hxx:240
void GetBoxesOfFormula(const SwTable &rTable, SwSelBoxes &rBoxes)
Definition: cellfml.cxx:888
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:1050
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:419
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *=nullptr, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2244
A page of the document layout.
Definition: pagefrm.hxx:40
void TableCursorToCursor()
enter block mode, change normal cursor into block cursor
Definition: crsrsh.cxx:893
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:3790
static std::unique_ptr< SwFormatRowSplit > GetRowSplit(const SwCursor &rCursor)
Definition: ndtbl1.cxx:344
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
#define ERR_TBLDDECHG_ERROR
Definition: swerror.h:38
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:404
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
SwTableLines & GetTabLines()
Definition: swtable.hxx:418
void SetTabLineStyle(const SwCursor &rCursor, const Color *pColor, bool bSetLine, const editeng::SvxBorderLine *pBorderLine)
Definition: ndtbl1.cxx:849
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:409
bool SetTableAutoFormat(const SwSelBoxes &rBoxes, const SwTableAutoFormat &rNew, bool bResetDirect=false, bool isSetStyleName=false)
AutoFormat for table/table selection.
Definition: ndtbl.cxx:3699
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:2213
Point PixelToLogic(const Point &rDevicePt) const
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt) const
determines the text direction for a certain position.
Definition: node.cxx:2004
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
bool SelTable()
Definition: trvltbl.cxx:252
const OUString & GetName() const
Definition: tblafmt.hxx:208
SwTableAutoFormatTable & GetTableStyles()
Return the available table styles.
Definition: ndtbl.cxx:3863
const SwContentFrame * GetCellContent(const SwLayoutFrame &rCell_)
method to get the content of the table cell
Definition: frmtool.cxx:3769
long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1359
SwTab
Definition: fesh.hxx:180
bool IsLayoutFrame() const
Definition: frame.hxx:1148
void Left(const long nLeft)
Definition: swrect.hxx:195
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
static const SwFrame * lcl_FindFrameInTab(const SwLayoutFrame *pLay, const Point &rPt, SwTwips nFuzzy)
Definition: fetab.cxx:1383
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void Bottom(const long nBottom)
Definition: swrect.hxx:209
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:354
#define ERR_TBLSPLIT_ERROR
Definition: swerror.h:36
bool CheckSplitCells(const SwCursorShell &rShell, sal_uInt16 nDiv, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:1956
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(149)
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
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:2440
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
bool SplitTable(const SwSelBoxes &rBoxes, bool bVert, sal_uInt16 nCnt, bool bSameHeight=false)
Split up/merge Boxes in the Table.
Definition: ndtbl.cxx:2147
void Width(long nNew)
Definition: swrect.hxx:187
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
void SetTableAttr(const SfxItemSet &)
Definition: fetab.cxx:2124
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:253
bool SetColRowWidthHeight(SwTableBox &rCurrentBox, TableChgWidthHeightType eType, SwTwips nAbsDiff, SwTwips nRelDiff)
Definition: ndtbl.cxx:3947
const SwTableBox * GetBox() const
Definition: tblsel.hxx:175
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:105
bool StartsWithTable()
If document body starts with a table.
Definition: crsrsh.cxx:623
SwNodes & GetNodes()
Definition: doc.hxx:405
std::unique_ptr< SwColCache > m_pRowCache
Definition: fesh.hxx:204
size_t GetSelectedBoxesCount() const
Definition: swcrsr.hxx:277
const SwPosition * End() const
Definition: pam.hxx:217
bool IsRightToLeft() const
Definition: frame.hxx:965
void ClearFEShellTabCols(SwDoc &rDoc, SwTabFrame const *const pFrame)
Definition: fetab.cxx:2084
bool IsMouseTableRightToLeft(const Point &rPt) const
Definition: fetab.cxx:2307
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
bool BalanceRowHeight(const SwCursor &rCursor, bool bTstOnly, const bool bOptimize)
Adjustment of Rowheights.
Definition: ndtbl1.cxx:430
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:1700
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1360
void SetTabCols(const SwTabCols &rNew, bool bCurRowOnly, const SwCellFrame *pBoxFrame)
Definition: ndtbl.cxx:2668
bool SelTableRowOrCol(bool bRow, bool bRowSimple=false)
Definition: trvltbl.cxx:126
void ClearMark()
Definition: crsrsh.cxx:936
void SetRowsToRepeat(SwTable &rTable, sal_uInt16 nSet)
Definition: ndtbl.cxx:2871
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:350
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:2300
bool IsVertical() const
Definition: frame.hxx:951
SAL_DLLPRIVATE void GetTabRows_(SwTabCols &rToFill, const SwFrame *pBox) const
Definition: fetab.cxx:568
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1355
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:1120
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:1281
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:39
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:2069
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...
size_t GetCurTabColNum() const
Definition: fetab.cxx:1316
bool DeleteRow(bool bCompleteTable=false)
Definition: fetab.cxx:313
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1277
static bool IsSame(long nA, long nB)
Definition: fetab.cxx:69
TableChgMode GetTableChgMode() const
Definition: swtable.hxx:328
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:1407
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:2273
long GetLeft() const
Definition: tabcol.hxx:77
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:836
void SetBoxDirection(const SvxFrameDirectionItem &rNew)
Definition: fetab.cxx:792
size_t Count() const
Definition: tabcol.hxx:64
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:28
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5413
bool GetTableAutoFormat(SwTableAutoFormat &rGet)
Definition: fetab.cxx:1247
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:393
bool HasTableAnyProtection(const SwPosition *pPos, const OUString *pTableName, bool *pFullTableProtection)
Definition: ndtbl.cxx:4513
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:507
Base class of the Writer document model elements.
Definition: node.hxx:79