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