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