LibreOffice Module sw (master)  1
WW8TableInfo.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 <iostream>
21 #include <set>
22 #include <stdio.h>
23 #include "WW8TableInfo.hxx"
24 #include <fmtfsize.hxx>
25 #include "attributeoutputbase.hxx"
26 #include <swtable.hxx>
27 #include <frmfmt.hxx>
28 #include <pam.hxx>
29 #include <ndtxt.hxx>
30 #include <dbgoutsw.hxx>
31 #include <sal/log.hxx>
32 #include <osl/diagnose.h>
33 
34 namespace ww8
35 {
36 
38 : mpParent(pParent)
39 , mnDepth(0)
40 , mnCell(0)
41 , mnRow(0)
42 , mnShadowsBefore(0)
43 , mnShadowsAfter(0)
44 , mbEndOfLine(false)
45 , mbFinalEndOfLine(false)
46 , mbEndOfCell(false)
47 , mbFirstInTable(false)
48 , mbVertMerge(false)
49 , mpTableBox(nullptr)
50 , mpTable(nullptr)
51 {
52 }
53 
55 {
56 }
57 
58 void WW8TableNodeInfoInner::setDepth(sal_uInt32 nDepth)
59 {
60  mnDepth = nDepth;
61 }
62 
63 void WW8TableNodeInfoInner::setCell(sal_uInt32 nCell)
64 {
65  mnCell = nCell;
66 }
67 
68 void WW8TableNodeInfoInner::setRow(sal_uInt32 nRow)
69 {
70  mnRow = nRow;
71 }
72 
73 void WW8TableNodeInfoInner::setShadowsBefore(sal_uInt32 nShadowsBefore)
74 {
75  mnShadowsBefore = nShadowsBefore;
76 }
77 
78 void WW8TableNodeInfoInner::setShadowsAfter(sal_uInt32 nShadowsAfter)
79 {
80  mnShadowsAfter = nShadowsAfter;
81 }
82 
84 {
85  mbEndOfLine = bEndOfLine;
86 }
87 
88 void WW8TableNodeInfoInner::setFinalEndOfLine(bool bFinalEndOfLine)
89 {
90  mbFinalEndOfLine = bFinalEndOfLine;
91 }
92 
94 {
95  mbEndOfCell = bEndOfCell;
96 }
97 
99 {
100  mbFirstInTable = bFirstInTable;
101 }
102 
104 
105 {
106  mbVertMerge = bVertMerge;
107 }
108 
110 {
111  mpTableBox = pTableBox;
112 }
113 
115 {
116  mpTable = pTable;
117 }
118 
120 {
121  maRect = rRect;
122 }
123 
125 {
126  const SwNode * pResult = nullptr;
127 
128  if (mpParent != nullptr)
129  pResult = mpParent->getNode();
130 
131  return pResult;
132 }
133 
135 {
136  TableBoxVectorPtr pResult(new TableBoxVector);
137 
138  WW8TableCellGrid::Pointer_t pCellGrid =
140 
141  if (pCellGrid.get() == nullptr)
142  {
143  const SwTableLine * pTabLine = getTableBox()->GetUpper();
144  const SwTableBoxes & rTableBoxes = pTabLine->GetTabBoxes();
145 
146  sal_uInt8 nBoxes = rTableBoxes.size();
147  if (nBoxes > MAXTABLECELLS)
148  nBoxes = MAXTABLECELLS;
149  for ( sal_uInt8 n = 0; n < nBoxes; n++ )
150  {
151  pResult->push_back(rTableBoxes[n]);
152  }
153  }
154  else
155  pResult = pCellGrid->getTableBoxesOfRow(this);
156 
157  return pResult;
158 }
159 
161 {
162  GridColsPtr pResult(new GridCols);
163  WidthsPtr pWidths;
164 
165  // Check which columns should be checked - only the current row,
166  // or all the rows together
167  if (calculateColumnsFromAllRows)
168  {
169  // Calculate the width of all the columns based on ALL the rows.
170  // The difference is that this kind of draws vertical lines,
171  // so that if the rows look like this:
172  //
173  // ------------------------
174  // | | |
175  // ------------------------
176  // | | |
177  // ------------------------
178  // | | |
179  // ------------------------
180 
181  // then the actual column widths will be broken down like this:
182  //
183  // ------------------------
184  // | | | | |
185  // ------------------------
186 
187  // See the example at
188  // http://officeopenxml.com/WPtableGrid.php
189  // Under "Word 2007 Example"
190  pWidths = getColumnWidthsBasedOnAllRows();
191  }
192  else
193  {
194  // Calculate the width of all the columns based on the current row
195  pWidths = getWidthsOfRow();
196  }
197 
198  const SwFrameFormat *pFormat = getTable()->GetFrameFormat();
199  OSL_ENSURE(pFormat,"Impossible");
200  if (!pFormat)
201  return pResult;
202 
203  const SwFormatFrameSize &rSize = pFormat->GetFrameSize();
204  unsigned long nTableSz = static_cast<unsigned long>(rSize.GetWidth());
205 
206  long nPageSize = 0;
207  bool bRelBoxSize = false;
208 
209  rBase.GetTablePageSize( this, nPageSize, bRelBoxSize );
210 
211  SwTwips nSz = 0;
212  for (const auto& rWidth : *pWidths)
213  {
214  nSz += rWidth;
215  SwTwips nCalc = nSz;
216  if ( bRelBoxSize )
217  nCalc = ( nCalc * nPageSize ) / nTableSz;
218 
219  pResult->push_back( nCalc );
220  }
221 
222  return pResult;
223 }
224 
226 {
227  WidthsPtr pWidths;
228 
229  WW8TableCellGrid::Pointer_t pCellGrid =
231 
232  if (pCellGrid.get() == nullptr)
233  {
234  const SwTable * pTable = getTable();
235  const SwTableLines& rTableLines = pTable->GetTabLines();
236  const size_t nNumOfLines = rTableLines.size();
237 
238  // Go over all the rows - and for each row - calculate where
239  // there is a separator between columns
240  WidthsPtr pSeparators(new Widths);
241  for ( size_t nLineIndex = 0; nLineIndex < nNumOfLines; ++nLineIndex )
242  {
243  const SwTableLine *pCurrentLine = rTableLines[nLineIndex];
244  const SwTableBoxes & rTabBoxes = pCurrentLine->GetTabBoxes();
245  size_t nBoxes = rTabBoxes.size();
246  if (nBoxes > MAXTABLECELLS)
247  nBoxes = MAXTABLECELLS;
248 
249  sal_uInt32 nSeparatorPosition = 0;
250  for (size_t nBoxIndex = 0; nBoxIndex < nBoxes; ++nBoxIndex)
251  {
252  const SwFrameFormat* pBoxFormat = rTabBoxes[ nBoxIndex ]->GetFrameFormat();
253  const SwFormatFrameSize& rLSz = pBoxFormat->GetFrameSize();
254  nSeparatorPosition += rLSz.GetWidth();
255  pSeparators->push_back(nSeparatorPosition);
256  }
257  }
258 
259  // Sort the separator positions and remove any duplicates
260  std::sort(pSeparators->begin(), pSeparators->end());
261  std::vector<sal_uInt32>::iterator it = std::unique(pSeparators->begin(), pSeparators->end());
262  pSeparators->erase(it, pSeparators->end());
263 
264  // Calculate the widths based on the position of the unique & sorted
265  // column separators
266  pWidths = std::make_shared<Widths>();
267  sal_uInt32 nPreviousWidth = 0;
268  for (const sal_uInt32 nCurrentWidth : *pSeparators)
269  {
270  pWidths->push_back(nCurrentWidth - nPreviousWidth);
271  nPreviousWidth = nCurrentWidth;
272  }
273  }
274  else
275  {
276  pWidths = pCellGrid->getWidthsOfRow(this);
277  }
278 
279  return pWidths;
280 }
281 
283 {
284  WidthsPtr pWidths;
285 
286  WW8TableCellGrid::Pointer_t pCellGrid =
288 
289  if (pCellGrid.get() == nullptr)
290  {
291  const SwTableBox * pTabBox = getTableBox();
292  const SwTableLine * pTabLine = pTabBox->GetUpper();
293  const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
294 
295  pWidths = std::make_shared<Widths>();
296  // number of cell written
297  sal_uInt32 nBoxes = rTabBoxes.size();
298  if (nBoxes > MAXTABLECELLS)
299  nBoxes = MAXTABLECELLS;
300 
301  for (sal_uInt32 n = 0; n < nBoxes; n++)
302  {
303  const SwFrameFormat* pBoxFormat = rTabBoxes[ n ]->GetFrameFormat();
304  const SwFormatFrameSize& rLSz = pBoxFormat->GetFrameSize();
305 
306  pWidths->push_back(rLSz.GetWidth());
307  }
308  }
309  else
310  pWidths = pCellGrid->getWidthsOfRow(this);
311 
312  return pWidths;
313 }
314 
316 {
317  RowSpansPtr pResult(new RowSpans);
318 
319  WW8TableCellGrid::Pointer_t pCellGrid =
321 
322  if (pCellGrid.get() == nullptr)
323  {
324  const SwTableBox * pTabBox = getTableBox();
325  const SwTableLine * pTabLine = pTabBox->GetUpper();
326  const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
327 
328  sal_uInt32 nBoxes = rTabBoxes.size();
329  if (nBoxes > MAXTABLECELLS)
330  nBoxes = MAXTABLECELLS;
331 
332  for (sal_uInt32 n = 0; n < nBoxes; ++n)
333  {
334  pResult->push_back(rTabBoxes[n]->getRowSpan());
335  }
336  }
337  else
338  pResult = pCellGrid->getRowSpansOfRow(this);
339 
340  return pResult;
341  }
342 
343 
344 #ifdef DBG_UTIL
346 {
347  static char buffer[256];
348  snprintf(buffer, sizeof(buffer),
349  "<tableinner depth=\"%" SAL_PRIuUINT32 "\""
350  " cell=\"%" SAL_PRIuUINT32 "\""
351  " row=\"%" SAL_PRIuUINT32 "\""
352  " endOfCell=\"%s\""
353  " endOfLine=\"%s\""
354  " shadowsBefore=\"%" SAL_PRIuUINT32 "\""
355  " shadowsAfter=\"%" SAL_PRIuUINT32 "\""
356  " vertMerge=\"%s\"/>",
357  mnDepth, mnCell, mnRow,
358  mbEndOfCell ? "yes" : "no",
359  mbEndOfLine ? "yes" : "no",
362  mbVertMerge ? "yes" : "no");
363 
364  return std::string(buffer);
365 }
366 #endif
367 
369  const SwNode * pNode)
370 : mpParent(pParent),
371  mnDepth(0),
372  mpNode(pNode),
373  mpNext(nullptr),
374  mpNextNode(nullptr)
375 {
376 }
377 
379 {
380 }
381 
382 #ifdef DBG_UTIL
383 std::string WW8TableNodeInfo::toString() const
384 {
385  static char buffer[1024];
386  snprintf(buffer, sizeof(buffer),
387  "<tableNodeInfo p=\"%p\" depth=\"%" SAL_PRIuUINT32 "\">"
388  ,this, getDepth());
389 
390  std::string sResult(buffer);
391 
392  for (const auto& rInner : mInners)
393  {
394  WW8TableNodeInfoInner::Pointer_t pInner = rInner.second;
395  sResult += pInner->toString();
396  }
397  sResult += dbg_out(*mpNode);
398  sResult += "</tableNodeInfo>";
399 
400  return sResult;
401 }
402 #endif
403 
404 void WW8TableNodeInfo::setDepth(sal_uInt32 nDepth)
405 {
406  mnDepth = nDepth;
407 
408  Inners_t::iterator aIt = mInners.find(mnDepth);
409 
410  if (aIt == mInners.end())
411  mInners[mnDepth] = std::make_shared<ww8::WW8TableNodeInfoInner>(this);
412 
413  mInners[mnDepth]->setDepth(mnDepth);
414 }
415 
416 void WW8TableNodeInfo::setEndOfLine(bool bEndOfLine)
417 {
419  pInner->setEndOfLine(bEndOfLine);
420 
421 #ifdef DBG_UTIL
422  SAL_INFO( "sw.ww8", "<endOfLine depth=\"" << mnDepth << "\">" << toString() << "</endOfLine>" );
423 #endif
424 }
425 
426 void WW8TableNodeInfo::setEndOfCell(bool bEndOfCell)
427 {
429  pInner->setEndOfCell(bEndOfCell);
430 
431 #ifdef DBG_UTIL
432  SAL_INFO( "sw.ww8", "<endOfCell depth=\"" << mnDepth << "\">" << toString() << "</endOfCell>" );
433 #endif
434 }
435 
436 void WW8TableNodeInfo::setFirstInTable(bool bFirstInTable)
437 {
439 
440  pInner->setFirstInTable(bFirstInTable);
441 
442 #ifdef DBG_UTIL
443  SAL_INFO( "sw.ww8", "<firstInTable depth=\"" << mnDepth << "\">" << toString() << "</firstInTable>" );
444 #endif
445 }
446 
447 void WW8TableNodeInfo::setVertMerge(bool bVertMerge)
448 {
450 
451  pInner->setVertMerge(bVertMerge);
452 
453 #ifdef DBG_UTIL
454  SAL_INFO( "sw.ww8", "<vertMerge depth=\"" << mnDepth << "\">" << toString() << "</vertMerge>" );
455 #endif
456 }
457 
459 {
460  getInnerForDepth(mnDepth)->setTableBox(pTableBox);
461 }
462 
464 {
465  getInnerForDepth(mnDepth)->setTable(pTable);
466 }
467 
469 {
470  mpNext = pNext;
471 
472 #ifdef DBG_UTIL
473  SAL_INFO( "sw.ww8", "<setnext><from>" << toString() << "</from><to>" << pNext->toString() << "</to></setnext>" );
474 #endif
475 }
476 
478 {
479  mpNextNode = pNode;
480 }
481 
483 {
484  getInnerForDepth(mnDepth)->setRect(rRect);
485 }
486 
487 void WW8TableNodeInfo::setCell(sal_uInt32 nCell)
488 {
489  getInnerForDepth(mnDepth)->setCell(nCell);
490 }
491 
492 void WW8TableNodeInfo::setRow(sal_uInt32 nRow)
493 {
494  getInnerForDepth(mnDepth)->setRow(nRow);
495 }
496 
497 void WW8TableNodeInfo::setShadowsBefore(sal_uInt32 nShadowsBefore)
498 {
499  getInnerForDepth(mnDepth)->setShadowsBefore(nShadowsBefore);
500 }
501 
502 void WW8TableNodeInfo::setShadowsAfter(sal_uInt32 nShadowsAfter)
503 {
504  getInnerForDepth(mnDepth)->setShadowsAfter(nShadowsAfter);
505 }
506 
507 
508 sal_uInt32 WW8TableNodeInfo::getDepth() const
509 {
510  if (!mInners.empty())
511  return mInners.begin()->second->getDepth();
512 
513  return mnDepth;
514 }
515 
516 
518 {
519  return getInnerForDepth(mnDepth)->getTableBox();
520 }
521 
522 sal_uInt32 WW8TableNodeInfo::getCell() const
523 {
524  return getInnerForDepth(mnDepth)->getCell();
525 }
526 
527 sal_uInt32 WW8TableNodeInfo::getRow() const
528 {
529  return getInnerForDepth(mnDepth)->getRow();
530 }
531 
533 {
535 
536  if (!mInners.empty())
537  pResult = mInners.begin()->second;
538 
539  return pResult;
540 }
541 
543 {
545 
546  Inners_t::const_iterator aIt = mInners.find(nDepth);
547  if (aIt != mInners.end())
548  {
549  pResult = aIt->second;
550  }
551 
552  return pResult;
553 }
554 
556 {
557 }
558 
560 {
561 }
562 
565 {
566  SwTableCellInfo aTableCellInfo(pTable);
567 
568  while (aTableCellInfo.getNext())
569  {
570  SwRect aRect = aTableCellInfo.getRect();
571 
572  SAL_INFO( "sw.ww8", "<CellFrame>" );
573  SAL_INFO( "sw.ww8", "<rect top=\"" << aRect.Top() << "\" bottom=\"" << aRect.Bottom()
574  << "\" left=\"" << aRect.Left() << "\" right=\"" << aRect.Right() << "\"/>" );
575  const SwTableBox * pTableBox = aTableCellInfo.getTableBox();
576  const SwStartNode * pSttNd = pTableBox->GetSttNd();
577 
578  if (pSttNd != nullptr)
579  {
580  SwPaM aPam(*pSttNd, 0);
581 
582  bool bDone = false;
583  do
584  {
585  SwNode & rNode = aPam.GetPoint()->nNode.GetNode();
586 
587  insertTableNodeInfo(&rNode, pTable, pTableBox, 0, 0, 1, & aRect);
588 
589  if (rNode.IsEndNode())
590  {
591  SwEndNode * pEndNode = rNode.GetEndNode();
592  SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
593 
594  if (pTmpSttNd == pSttNd)
595  bDone = true;
596  }
597 
598  aPam.GetPoint()->nNode++;
599  }
600  while (!bDone);
601  }
602 
603  SAL_INFO( "sw.ww8", "</CellFrame>" );
604  }
605 
606  return reorderByLayout(pTable, rLastRowEnds);
607 }
608 
610 {
611  SAL_INFO( "sw.ww8", "<processSwTable>" );
612 
613  WW8TableNodeInfo * pPrev = nullptr;
614  RowEndInners_t aLastRowEnds;
615 
616  if (pTable->IsTableComplex() && pTable->HasLayout())
617  {
618  pPrev = processSwTableByLayout(pTable, aLastRowEnds);
619 #ifdef DBG_UTIL
620  SAL_INFO( "sw.ww8", getCellGridForTable(pTable)->toString());
621 #endif
622  }
623  else
624  {
625  const SwTableLines & rLines = pTable->GetTabLines();
626 
627  for (size_t n = 0; n < rLines.size(); ++n)
628  {
629  const SwTableLine * pLine = rLines[n];
630 
631  pPrev = processTableLine(pTable, pLine, static_cast<sal_uInt32>(n), 1, pPrev, aLastRowEnds);
632  }
633 
634  }
635 
636  if (pPrev)
637  {
638  SwTableNode * pTableNode = pTable->GetTableNode();
639  SwEndNode * pEndNode = pTableNode->EndOfSectionNode();
640  pPrev->setNextNode(pEndNode);
641  assert(!aLastRowEnds.empty());
642  for (auto &a : aLastRowEnds)
643  {
644  assert(a.second->isEndOfLine());
645  a.second->setFinalEndOfLine(true);
646  }
647  }
648  SAL_INFO( "sw.ww8", "</processSwTable>" );
649 }
650 
653  const SwTableLine * pTableLine,
654  sal_uInt32 nRow,
655  sal_uInt32 nDepth,
656  WW8TableNodeInfo * pPrev,
657  RowEndInners_t &rLastRowEnds)
658 {
659  SAL_INFO( "sw.ww8", "<processTableLine row=\"" << nRow << "\" depth=\"" << nDepth << "\">" );
660 
661  const SwTableBoxes & rBoxes = pTableLine->GetTabBoxes();
662 
663  WW8TableNodeInfo::Pointer_t pTextNodeInfo;
664 
665  for (size_t n = 0; n < rBoxes.size(); ++n)
666  {
667  const SwTableBox * pBox = rBoxes[n];
668 
669  pPrev = processTableBox(pTable, pBox, nRow, static_cast<sal_uInt32>(n), nDepth, n == rBoxes.size() - 1, pPrev, rLastRowEnds);
670  }
671 
672  SAL_INFO( "sw.ww8", "</processTableLine>" );
673 
674  return pPrev;
675 }
676 
679  const SwTable * pTable,
680  const SwTableBox * pBoxToSet,
681  sal_uInt32 nRow,
682  sal_uInt32 nCell,
683  sal_uInt32 nDepth)
684 {
685  SAL_INFO( "sw.ww8", "<processTableBoxLines depth=\"" << nDepth << "\" row=\"" << nRow
686  << "\" cell=\"" << nCell << "\">" );
687 
688  const SwTableLines & rLines = pBox->GetTabLines();
689  WW8TableNodeInfo::Pointer_t pNodeInfo;
690 
691  if (!rLines.empty())
692  {
693  for (size_t n = 0; n < rLines.size(); ++n)
694  {
695  const SwTableLine * pLine = rLines[n];
696  const SwTableBoxes & rBoxes = pLine->GetTabBoxes();
697 
698  for (size_t nBox = 0; nBox < rBoxes.size(); ++nBox)
699  pNodeInfo = processTableBoxLines(rBoxes[nBox], pTable, pBoxToSet, nRow, nCell, nDepth);
700  }
701  }
702  else
703  {
704  const SwStartNode * pSttNd = pBox->GetSttNd();
705  const SwEndNode * pEndNd = pSttNd->EndOfSectionNode();
706  SwPaM aPaM(*pSttNd, 0);
707  SwPaM aEndPaM(*pEndNd, 0);
708 
709  bool bDone = false;
710  while (!bDone)
711  {
712  SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
713 
714  pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBoxToSet, nRow, nCell, nDepth);
715 
716  if (aPaM.GetPoint()->nNode == aEndPaM.GetPoint()->nNode)
717  bDone = true;
718  else
719  aPaM.GetPoint()->nNode++;
720  }
721  }
722 
723  SAL_INFO( "sw.ww8", "</processTableBoxLines>" );
724 
725  return pNodeInfo;
726 }
727 
728 static void updateFinalEndOfLine(RowEndInners_t &rLastRowEnds, WW8TableNodeInfo const * pEndOfCellInfo)
729 {
730  sal_Int32 nDepth = pEndOfCellInfo->getDepth();
731  WW8TableNodeInfoInner::Pointer_t pInner = pEndOfCellInfo->getInnerForDepth(nDepth);
732 
733  auto aIt = rLastRowEnds.find(nDepth);
734  if (aIt == rLastRowEnds.end() || (pInner->getRow() > aIt->second->getRow()))
735  rLastRowEnds[nDepth] = pInner.get();
736 }
737 
738 WW8TableNodeInfo *
740  const SwTableBox * pBox,
741  sal_uInt32 nRow,
742  sal_uInt32 nCell,
743  sal_uInt32 nDepth,
744  bool bEndOfLine,
745  WW8TableNodeInfo * pPrev,
746  RowEndInners_t &rLastRowEnds)
747 {
748  SAL_INFO( "sw.ww8", "<processTableBox row=\"" << nRow << "\" cell=\"" << nCell
749  << "\" depth=\"" << nDepth << "\">" );
750 
751  WW8TableNodeInfo::Pointer_t pNodeInfo;
752  const SwTableLines & rLines = pBox->GetTabLines();
753  const SwStartNode * pSttNd = pBox->GetSttNd();
754  WW8TableNodeInfo::Pointer_t pEndOfCellInfo;
755 
756  if (!rLines.empty())
757  {
758  pNodeInfo = processTableBoxLines(pBox, pTable, pBox, nRow, nCell, nDepth);
759  pNodeInfo->setEndOfCell(true);
760  if (bEndOfLine)
761  {
762  pNodeInfo->setEndOfLine(true);
763  updateFinalEndOfLine(rLastRowEnds, pNodeInfo.get());
764  }
765 
766  for (size_t n = 0; n < rLines.size(); n++)
767  {
768  const SwTableLine * pLine = rLines[n];
769 
770  pPrev = processTableLine(pTable, pLine, n, 1, pPrev, rLastRowEnds);
771  }
772  }
773  else
774  {
775  SwPaM aPaM(*pSttNd, 0);
776 
777  bool bDone = false;
778  sal_uInt32 nDepthInsideCell = 0;
779 
780  do
781  {
782  SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
783 
784  if (rNode.IsStartNode())
785  {
786  if (nDepthInsideCell > 0)
787  pEndOfCellInfo.reset();
788 
789  nDepthInsideCell++;
790  }
791 
792  pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBox, nRow, nCell, nDepth);
793 
794  if (pPrev)
795  pPrev->setNext(pNodeInfo.get());
796 
797  pPrev = pNodeInfo.get();
798 
799  if (nDepthInsideCell == 1 && rNode.IsTextNode())
800  pEndOfCellInfo = pNodeInfo;
801 
802  if (rNode.IsEndNode())
803  {
804  nDepthInsideCell--;
805 
806  if (nDepthInsideCell == 0 && !pEndOfCellInfo)
807  pEndOfCellInfo = pNodeInfo;
808 
809  SwEndNode * pEndNode = rNode.GetEndNode( );
810  SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
811  if (pTmpSttNd == pSttNd)
812  bDone = true;
813  }
814 
815  aPaM.GetPoint()->nNode++;
816  }
817  while (!bDone);
818 
819  if (pEndOfCellInfo.get() != nullptr)
820  {
821  pEndOfCellInfo->setEndOfCell(true);
822 
823  if (bEndOfLine)
824  {
825  pEndOfCellInfo->setEndOfLine(true);
826  updateFinalEndOfLine(rLastRowEnds, pEndOfCellInfo.get());
827  }
828  }
829  }
830 
831  SAL_INFO( "sw.ww8", "</processTableBox>" );
832 
833  return pPrev;
834 }
835 
837 (const SwNode * pNode,
838  const SwTable * pTable,
839  const SwTableBox * pTableBox,
840  sal_uInt32 nRow,
841  sal_uInt32 nCell,
842  sal_uInt32 nDepth,
843  SwRect const * pRect)
844 {
845  WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode);
846 
847  if (pNodeInfo.get() == nullptr)
848  {
849  pNodeInfo =
850  std::make_shared<ww8::WW8TableNodeInfo>(this, pNode);
851  mMap.emplace(pNode, pNodeInfo);
852  }
853 
854  pNodeInfo->setDepth(nDepth + pNodeInfo->getDepth());
855 
856  pNodeInfo->setTable(pTable);
857  pNodeInfo->setTableBox(pTableBox);
858 
859  pNodeInfo->setCell(nCell);
860  pNodeInfo->setRow(nRow);
861 
862  if (pNode->IsTextNode())
863  {
864  FirstInTableMap_t::const_iterator aIt = mFirstInTableMap.find(pTable);
865  if (aIt == mFirstInTableMap.end())
866  {
867  mFirstInTableMap[pTable] = pNode;
868  pNodeInfo->setFirstInTable(true);
869  }
870  }
871 
872  if (pRect)
873  {
874  WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable);
875 
876  pCellGrid->insert(*pRect, pNodeInfo.get());
877  pNodeInfo->setRect(*pRect);
878  }
879 
880 #ifdef DBG_UTIL
881  SAL_INFO( "sw.ww8", pNodeInfo->toString());
882 #endif
883  return pNodeInfo;
884 }
885 
887 (const SwTable * pTable, bool bCreate)
888 {
890  CellGridMap_t::iterator aIt = mCellGridMap.find(pTable);
891 
892  if (aIt == mCellGridMap.end())
893  {
894  if (bCreate)
895  {
896  pResult = std::make_shared<ww8::WW8TableCellGrid>();
897  mCellGridMap[pTable] = pResult;
898  }
899  }
900  else
901  pResult = mCellGridMap[pTable];
902 
903  return pResult;
904 }
905 
907 (const SwNode * pNode)
908 {
910  Map_t::iterator aIt = mMap.find(pNode);
911 
912  if (aIt != mMap.end())
913  pResult = (*aIt).second;
914 
915  return pResult;
916 }
917 
919 {
920  const SwNode * pResult = nullptr;
921 
923 
924  if (pNodeInfo.get() != nullptr)
925  {
926  WW8TableNodeInfo * pNextInfo = pNodeInfo->getNext();
927 
928  if (pNextInfo != nullptr)
929  pResult = pNextInfo->getNode();
930  else
931  {
932  const SwNode * pNextNode = pNodeInfo->getNextNode();
933 
934  if (pNextNode != nullptr)
935  pResult = pNextNode;
936  }
937  }
938 
939  return pResult;
940 }
941 
943 {
944  bool bRet = false;
945 
946  if (rInfo.mpNode != nullptr)
947  {
948  if (mpNode == nullptr)
949  {
950  bRet = true;
951  }
952  else
953  {
954  if (mpNode->GetIndex() < rInfo.mpNode->GetIndex())
955  bRet = true;
956  }
957  }
958 
959  return bRet;
960 }
961 
962 bool CellInfo::operator < (const CellInfo & aCellInfo) const
963 {
964  bool aRet = false;
965 
966  if (top() < aCellInfo.top())
967  aRet = true;
968  else if (top() == aCellInfo.top())
969  {
970  if (left() < aCellInfo.left())
971  aRet = true;
972  else if (left() == aCellInfo.left())
973  {
974  if (width() < aCellInfo.width())
975  aRet = true;
976  else if (width() == aCellInfo.width())
977  {
978  if (height() < aCellInfo.height())
979  aRet = true;
980  else if (height() == aCellInfo.height())
981  {
982  if (aCellInfo.getTableNodeInfo())
983  {
984  if (m_pNodeInfo == nullptr)
985  aRet = true;
986  else
987  {
988  aRet = *m_pNodeInfo < *aCellInfo.getTableNodeInfo();
989  }
990  }
991  }
992  }
993  }
994  }
995 
996  return aRet;
997 }
998 
999 #ifdef DBG_UTIL
1000 std::string CellInfo::toString() const
1001 {
1002  static char sBuffer[256];
1003 
1004  snprintf(sBuffer, sizeof(sBuffer),
1005  "<cellinfo left=\"%ld\""
1006  " right=\"%ld\""
1007  " top=\"%ld\""
1008  " bottom=\"%ld\""
1009  " node=\"%p\"/>",
1010  left(),
1011  right(),
1012  top(),
1013  bottom(),
1014  m_pNodeInfo);
1015 
1016  return sBuffer;
1017 }
1018 #endif
1019 
1021 {
1023 
1024 #ifdef DBG_UTIL
1025  SAL_INFO( "sw.ww8", pCellGrid->toString());
1026 #endif
1027 
1028  pCellGrid->addShadowCells();
1029  return pCellGrid->connectCells(rLastRowEnds);
1030 }
1031 
1033 {
1034 }
1035 
1037 {
1038 }
1039 
1041 {
1043 
1044  RowTops_t::iterator aIt = m_aRowTops.find(nTop);
1045 
1046  if (aIt == m_aRowTops.end())
1047  {
1048  if (bCreate)
1049  {
1050  pResult = std::make_shared<ww8::WW8TableCellGridRow>();
1051  m_aRows[nTop] = pResult;
1052  m_aRowTops.insert(nTop);
1053  }
1054  }
1055  else
1056  pResult = m_aRows[nTop];
1057 
1058  return pResult;
1059 }
1060 
1061 WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsBegin() const
1062 {
1063  return m_aRowTops.begin();
1064 }
1065 
1066 WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsEnd() const
1067 {
1068  return m_aRowTops.end();
1069 }
1070 
1071 CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsBegin(long nTop)
1072 {
1073  return getRow(nTop)->begin();
1074 }
1075 
1076 CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsEnd(long nTop)
1077 {
1078  return getRow(nTop)->end();
1079 }
1080 
1082  WW8TableNodeInfo * pNodeInfo,
1083  const unsigned long * pFormatFrameWidth)
1084 {
1085  CellInfo aCellInfo(rRect, pNodeInfo);
1086 
1087  if (pFormatFrameWidth != nullptr)
1088  aCellInfo.setFormatFrameWidth(*pFormatFrameWidth);
1089 
1090  WW8TableCellGridRow::Pointer_t pRow = getRow(rRect.Top());
1091  pRow->insert(aCellInfo);
1092 }
1093 
1095 {
1096  SAL_INFO( "sw.ww8", "<addShadowCells>" );
1097 
1098  RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1099 
1100  while (aTopsIt != getRowTopsEnd())
1101  {
1102  CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1103  CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
1104 
1105  RowSpansPtr pRowSpans(new RowSpans);
1106 
1107  bool bBeginningOfCell = true;
1108  bool bVertMerge = false;
1109  SwRect aRect = aCellIt->getRect();
1110  long nRowSpan = 1;
1111  while (aCellIt != aCellEndIt)
1112  {
1113  WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
1114 
1115  if (bBeginningOfCell)
1116  {
1117  RowTops_t::const_iterator aRowSpanIt(aTopsIt);
1118  ++aRowSpanIt;
1119 
1120  if (aRowSpanIt != getRowTopsEnd() &&
1121  *aRowSpanIt < aCellIt->bottom())
1122  {
1123  aRect.Top(*aRowSpanIt);
1124  unsigned long nFormatFrameWidth = aCellIt->getFormatFrameWidth();
1125  insert(aRect, nullptr, &nFormatFrameWidth);
1126 
1127  bVertMerge = true;
1128  }
1129  else
1130  bVertMerge = false;
1131 
1132  nRowSpan = 1;
1133  while (aRowSpanIt != getRowTopsEnd() &&
1134  *aRowSpanIt < aCellIt->bottom())
1135  {
1136  ++aRowSpanIt;
1137  nRowSpan++;
1138  }
1139 
1140  if (pNodeInfo)
1141  pRowSpans->push_back(nRowSpan);
1142  else
1143  pRowSpans->push_back(-nRowSpan);
1144  }
1145 
1146  if (pNodeInfo)
1147  {
1148  pNodeInfo->setVertMerge(bVertMerge);
1149  }
1150 
1151  ++aCellIt;
1152  if (aCellIt != aCellEndIt)
1153  {
1154  bBeginningOfCell = (aRect.Left() != aCellIt->left());
1155  aRect = aCellIt->getRect();
1156  }
1157  }
1158 
1159  WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
1160  if (pRow.get() != nullptr)
1161  pRow->setRowSpans(pRowSpans);
1162 
1163  ++aTopsIt;
1164  }
1165  SAL_INFO( "sw.ww8", "</addShadowCells>" );
1166 }
1167 
1169 {
1170  RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1171  sal_uInt32 nRow = 0;
1172  WW8TableNodeInfo * pLastNodeInfo = nullptr;
1173 
1174  while (aTopsIt != getRowTopsEnd())
1175  {
1176  CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1177  CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
1178  GridColsPtr pWidths(new Widths);
1179  TableBoxVectorPtr pTableBoxes(new TableBoxVector);
1180 
1181  sal_uInt32 nShadows = 0;
1182  sal_uInt32 nCell = 0;
1183  bool bBeginningOfCell = true;
1184  WW8TableNodeInfo * pEndOfCellInfo = nullptr;
1185  sal_uInt32 nDepthInCell = 0;
1186  while (aCellIt != aCellEndIt)
1187  {
1188  long nCellX = aCellIt->left();
1189  WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
1190  if (pNodeInfo)
1191  {
1192  const SwNode * pNode = pNodeInfo->getNode();
1193 
1194  if (pNode->IsStartNode())
1195  {
1196  nDepthInCell++;
1197  pEndOfCellInfo = nullptr;
1198  }
1199 
1200  if (nDepthInCell == 1 && pNode->IsTextNode())
1201  pEndOfCellInfo = pNodeInfo;
1202 
1203  pNodeInfo->setShadowsBefore(nShadows);
1204  pNodeInfo->setCell(nCell);
1205  pNodeInfo->setRow(nRow);
1206  if (pLastNodeInfo)
1207  {
1208  pLastNodeInfo->setNext(pNodeInfo);
1209  pLastNodeInfo->setNextNode(pNode);
1210  }
1211  pLastNodeInfo = pNodeInfo;
1212  nShadows = 0;
1213 
1214  if (pNode->IsEndNode())
1215  {
1216  nDepthInCell--;
1217 
1218  if (nDepthInCell == 0 && !pEndOfCellInfo)
1219  pEndOfCellInfo = pNodeInfo;
1220  }
1221  }
1222  else
1223  {
1224  nShadows++;
1225  }
1226 
1227  if (bBeginningOfCell)
1228  {
1229  pWidths->push_back(aCellIt->getFormatFrameWidth());
1230 
1231  if (pNodeInfo)
1232  pTableBoxes->push_back(pNodeInfo->getTableBox());
1233  else
1234  pTableBoxes->push_back(nullptr);
1235  }
1236 
1237  ++aCellIt;
1238  bBeginningOfCell = false;
1239 
1240  if (aCellIt != aCellEndIt && aCellIt->left() != nCellX)
1241  {
1242  nCell++;
1243  bBeginningOfCell = true;
1244 
1245  if (pEndOfCellInfo)
1246  {
1247  pEndOfCellInfo->setEndOfCell(true);
1248  }
1249 
1250  pEndOfCellInfo = nullptr;
1251  }
1252  }
1253 
1254  pLastNodeInfo->setShadowsAfter(nShadows);
1255 
1256  if (!pEndOfCellInfo)
1257  {
1258  pEndOfCellInfo = pLastNodeInfo;
1259  }
1260 
1261  pEndOfCellInfo->setEndOfCell(true);
1262  pLastNodeInfo->setEndOfLine(true);
1263  updateFinalEndOfLine(rLastRowEnds, pLastNodeInfo);
1264 
1265  WW8TableCellGridRow::Pointer_t pRow(getRow(*aTopsIt));
1266  pRow->setTableBoxVector(pTableBoxes);
1267  pRow->setWidths(pWidths);
1268 
1269  ++aTopsIt;
1270  nRow++;
1271  }
1272 
1273  return pLastNodeInfo;
1274 }
1275 
1276 #ifdef DBG_UTIL
1278 {
1279  std::string sResult = "<WW8TableCellGrid>";
1280 
1281  RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1282  static char sBuffer[1024];
1283  while (aTopsIt != getRowTopsEnd())
1284  {
1285  sprintf(sBuffer, "<row y=\"%ld\">", *aTopsIt);
1286  sResult += sBuffer;
1287 
1288  CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1289  CellInfoMultiSet::const_iterator aCellsEnd = getCellsEnd(*aTopsIt);
1290 
1291  while (aCellIt != aCellsEnd)
1292  {
1293  snprintf(sBuffer, sizeof(sBuffer), "<cellInfo top=\"%ld\" bottom=\"%ld\" left=\"%ld\" right=\"%ld\">",
1294  aCellIt->top(), aCellIt->bottom(), aCellIt->left(), aCellIt->right());
1295  sResult += sBuffer;
1296 
1297  WW8TableNodeInfo * pInfo = aCellIt->getTableNodeInfo();
1298  if (pInfo)
1299  sResult += pInfo->toString();
1300  else
1301  sResult += "<shadow/>\n";
1302 
1303  sResult += "</cellInfo>\n";
1304  ++aCellIt;
1305  }
1306 
1307  WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
1308  WidthsPtr pWidths = pRow->getWidths();
1309  if (pWidths != nullptr)
1310  {
1311  sResult += "<widths>";
1312 
1313  Widths::const_iterator aItEnd = pWidths->end();
1314  for (Widths::const_iterator aIt = pWidths->begin();
1315  aIt != aItEnd;
1316  ++aIt)
1317  {
1318  if (aIt != pWidths->begin())
1319  sResult += ", ";
1320 
1321  snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
1322  sResult += sBuffer;
1323  }
1324 
1325  sResult += "</widths>";
1326  }
1327 
1328  RowSpansPtr pRowSpans = pRow->getRowSpans();
1329  if (pRowSpans.get() != nullptr)
1330  {
1331  sResult += "<rowspans>";
1332 
1333  RowSpans::const_iterator aItEnd = pRowSpans->end();
1334  for (RowSpans::const_iterator aIt = pRowSpans->begin();
1335  aIt != aItEnd;
1336  ++aIt)
1337  {
1338  if (aIt != pRowSpans->begin())
1339  sResult += ", ";
1340 
1341  snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
1342  sResult += sBuffer;
1343  }
1344 
1345  sResult += "</rowspans>";
1346  }
1347 
1348  sResult += "</row>\n";
1349  ++aTopsIt;
1350  }
1351 
1352  sResult += "</WW8TableCellGrid>\n";
1353 
1354  return sResult;
1355 }
1356 #endif
1357 
1359 (WW8TableNodeInfoInner const * pNodeInfoInner)
1360 {
1361  TableBoxVectorPtr pResult;
1363  getRow(pNodeInfoInner->getRect().Top(), false);
1364 
1365  if (pRow.get() != nullptr)
1366  {
1367  pResult = pRow->getTableBoxVector();
1368  }
1369 
1370  return pResult;
1371 }
1372 
1374 (WW8TableNodeInfoInner const * pNodeInfoInner)
1375 {
1376  GridColsPtr pResult;
1377 
1379  getRow(pNodeInfoInner->getRect().Top(), false);
1380 
1381  if (pRow.get() != nullptr)
1382  {
1383  pResult = pRow->getWidths();
1384  }
1385 
1386  return pResult;
1387 }
1388 
1390 (WW8TableNodeInfoInner const * pNodeInfoInner)
1391 {
1392  RowSpansPtr pResult;
1393 
1395  getRow(pNodeInfoInner->getRect().Top(), false);
1396 
1397  if (pRow.get() != nullptr)
1398  {
1399  pResult = pRow->getRowSpans();
1400  }
1401 
1402  return pResult;
1403 }
1404 
1406 : m_pCellInfos(new CellInfoMultiSet)
1407 {
1408 }
1409 
1411 {
1412 }
1413 
1414 void WW8TableCellGridRow::insert(const CellInfo & rCellInfo)
1415 {
1416  m_pCellInfos->insert(rCellInfo);
1417 
1418 #ifdef DBG_UTIL
1419  SAL_INFO( "sw.ww8", "<gridRowInsert>" << rCellInfo.toString() << "</gridRowInsert>" );
1420 #endif
1421 }
1422 
1423 CellInfoMultiSet::const_iterator WW8TableCellGridRow::begin() const
1424 {
1425  return m_pCellInfos->begin();
1426 }
1427 
1428 CellInfoMultiSet::const_iterator WW8TableCellGridRow::end() const
1429 {
1430  return m_pCellInfos->end();
1431 }
1432 
1434 {
1435  if (pTableBoxVector->size() > MAXTABLECELLS)
1436  pTableBoxVector->resize(MAXTABLECELLS);
1437  m_pTableBoxVector = pTableBoxVector;
1438 }
1439 
1441 {
1442  m_pWidths = pWidths;
1443 }
1444 
1446 {
1447  m_pRowSpans = pRowSpans;
1448 }
1449 
1450 
1451 CellInfo::CellInfo(const SwRect & aRect, WW8TableNodeInfo * pNodeInfo)
1452 : m_aRect(aRect), m_pNodeInfo(pNodeInfo), m_nFormatFrameWidth(0)
1453 {
1454  if (pNodeInfo != nullptr)
1455  {
1456  const SwTableBox * pBox = pNodeInfo->getTableBox();
1457  const SwFrameFormat * pFrameFormat = pBox->GetFrameFormat();
1458  const SwFormatFrameSize & rSize = pFrameFormat->GetFrameSize();
1459 
1460  m_nFormatFrameWidth = rSize.GetWidth();
1461  }
1462 }
1463 
1464 }
1465 
1466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long width() const
void setNext(WW8TableNodeInfo *pNext)
bool IsTableComplex() const
Definition: swtable.cxx:1445
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
WW8TableNodeInfo::Pointer_t processTableBoxLines(const SwTableBox *pBox, const SwTable *pTable, const SwTableBox *pBoxToSet, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth)
void setTableBox(const SwTableBox *pTableBox)
std::map< sal_uInt32, WW8TableNodeInfoInner *, std::greater< sal_uInt32 > > RowEndInners_t
sal_uLong GetIndex() const
Definition: node.hxx:282
std::vector< const SwTableBox * > TableBoxVector
long right() const
void setEndOfLine(bool bEndOfLine)
const SwNode * getNode() const
bool HasLayout() const
Definition: swtable.cxx:2748
WW8TableNodeInfo * connectCells(RowEndInners_t &rLastRowEnds)
void setRect(const SwRect &rRect)
long height() const
SwNodeIndex nNode
Definition: pam.hxx:37
void setEndOfCell(bool bEndOfCell)
long GetWidth() const
bool operator<(const WW8TableNodeInfo &rInfo) const
const SwNode * mpNode
sal_uInt32 getDepth() const
TableBoxVectorPtr getTableBoxesOfRow()
WW8TableCellGridRow::Pointer_t getRow(long nTop, bool bCreate=true)
std::vector< sal_Int32 > RowSpans
sal_Int32 const mnRow
void setCell(sal_uInt32 nCell)
void setRect(const SwRect &rRect)
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
SwNode & GetNode() const
Definition: ndindex.hxx:118
long SwTwips
Definition: swtypes.hxx:49
TableBoxVectorPtr getTableBoxesOfRow(WW8TableNodeInfoInner const *pNodeInfo)
void setTable(const SwTable *pTable)
sal_uInt32 getCell() const
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
WW8TableNodeInfo(WW8TableInfo *pParent, const SwNode *pTextNode)
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
std::shared_ptr< Widths > WidthsPtr
long bottom() const
size_type size() const
Definition: swtable.hxx:74
void Top(const long nTop)
Definition: swrect.hxx:202
WW8TableNodeInfo::Pointer_t insertTableNodeInfo(const SwNode *pNode, const SwTable *pTable, const SwTableBox *pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth, SwRect const *pRect=nullptr)
CellInfoMultiSet::const_iterator getCellsBegin(long nTop)
EdgeEntry * mpNext
const SwTableBox * mpTableBox
void GetTablePageSize(ww8::WW8TableNodeInfoInner const *pTableTextNodeInfoInner, long &rPageSize, bool &rRelBoxSize)
Definition: wrtww8.cxx:2461
bool IsStartNode() const
Definition: node.hxx:624
const SwNode * getNextNode(const SwNode *pNode)
void setTableBoxVector(TableBoxVectorPtr const &pTableBoxVector)
WW8TableNodeInfo * processTableLine(const SwTable *pTable, const SwTableLine *pTableLine, sal_uInt32 nRow, sal_uInt32 nDepth, WW8TableNodeInfo *pPrev, RowEndInners_t &rLastRowEnds)
void setFormatFrameWidth(unsigned long nFormatFrameWidth)
void setShadowsAfter(sal_uInt32 nShadowsAfter)
void Right(const long nRight)
Definition: swrect.hxx:198
void setFirstInTable(bool bFirstInTable)
static void updateFinalEndOfLine(RowEndInners_t &rLastRowEnds, WW8TableNodeInfo const *pEndOfCellInfo)
std::vector< sal_uInt32 > GridCols
void setRow(sal_uInt32 nRow)
WW8TableNodeInfo * reorderByLayout(const SwTable *pTable, RowEndInners_t &rLastRowEnds)
void setWidths(WidthsPtr const &pGridCols)
WW8TableNodeInfoInner(WW8TableNodeInfo *pParent)
void setRowSpans(RowSpansPtr const &pRowSpans)
const SwTableBox * getTableBox() const
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
sal_Int32 mnDepth
Style of a layout element.
Definition: frmfmt.hxx:57
WW8TableNodeInfo * processSwTableByLayout(const SwTable *pTable, RowEndInners_t &rLastRowEnds)
std::vector< sal_uInt32 > Widths
WW8TableInfo * getParent() const
const SwTableBox * getTableBox() const
WW8TableNodeInfoInner::Pointer_t getFirstInner() const
std::shared_ptr< TableBoxVector > TableBoxVectorPtr
SwEndNode * GetEndNode()
Definition: node.hxx:583
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
void setEndOfCell(bool bEndOfCell)
const SwPosition * GetPoint() const
Definition: pam.hxx:207
bool empty() const
Definition: swtable.hxx:73
const SwNode * getNode() const
WW8TableNodeInfo * mpNext
CellInfoMultiSet::const_iterator begin() const
WidthsPtr getColumnWidthsBasedOnAllRows()
RowSpansPtr getRowSpansOfRow(WW8TableNodeInfoInner const *pNodeInfo)
WW8TableNodeInfo * getNext() const
std::multiset< CellInfo > CellInfoMultiSet
void setFirstInTable(bool bFirstInTable)
std::shared_ptr< GridCols > GridColsPtr
const char * dbg_out(const void *pVoid)
Definition: dbgoutsw.cxx:75
long left() const
WW8TableNodeInfo * processTableBox(const SwTable *pTable, const SwTableBox *pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth, bool bEndOfLine, WW8TableNodeInfo *pPrev, RowEndInners_t &rLastRowEnds)
void processSwTable(const SwTable *pTable)
WW8TableNodeInfoInner::Pointer_t getInnerForDepth(sal_uInt32 nDepth) const
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
bool IsEndNode() const
Definition: node.hxx:632
const SwNode * mpNextNode
std::string toString() const
void setShadowsAfter(sal_uInt32 nShadowsAfter)
void setFinalEndOfLine(bool bEndOfLine)
const SwTableBox * getTableBox() const
Definition: swtable.cxx:2733
void insert(const CellInfo &rCellInfo)
RowTops_t::const_iterator getRowTopsBegin() const
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
void setNextNode(const SwNode *pNode)
RowTops_t::const_iterator getRowTopsEnd() const
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
void setDepth(sal_uInt32 nDepth)
SwTableLines & GetTabLines()
Definition: swtable.hxx:418
GridColsPtr getGridColsOfRow(AttributeOutputBase &rBase, bool calculateColumnsFromAllRows=false)
void setCell(sal_uInt32 nCell)
CellInfoMultiSet::const_iterator end() const
void setDepth(sal_uInt32 nDepth)
void Left(const long nLeft)
Definition: swrect.hxx:193
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:354
std::vector< SwTableBox * > SwTableBoxes
Definition: swtable.hxx:103
WW8TableNodeInfo * getTableNodeInfo() const
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
std::string toString() const
std::string toString() const
CellInfo(const SwRect &aRect, WW8TableNodeInfo *pNodeInfo)
void setVertMerge(bool bVertMerge)
WW8TableCellGrid::Pointer_t getCellGridForTable(const SwTable *pTable, bool bCreate=true)
long top() const
unsigned char sal_uInt8
unsigned long m_nFormatFrameWidth
std::shared_ptr< WW8TableCellGrid > Pointer_t
SwRect getRect() const
Definition: swtable.cxx:2723
#define SAL_INFO(area, stream)
void setShadowsBefore(sal_uInt32 nShadowsBefore)
void setRow(sal_uInt32 nRow)
WW8TableNodeInfo::Pointer_t getTableNodeInfo(const SwNode *pNode)
void setEndOfLine(bool bEndOfLine)
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
void setShadowsBefore(sal_uInt32 nShadowsBefore)
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
void insert(const SwRect &rRect, WW8TableNodeInfo *pNodeInfo, unsigned long const *pFormatFrameWidth=nullptr)
const SwTable * getTable() const
WW8TableNodeInfo * mpParent
std::shared_ptr< CellInfoMultiSet > m_pCellInfos
CellInfoMultiSet::const_iterator getCellsEnd(long nTop)
TableBoxVectorPtr m_pTableBoxVector
Ends a section of nodes in the document model.
Definition: node.hxx:333
std::shared_ptr< WW8TableCellGridRow > Pointer_t
std::shared_ptr< RowSpans > RowSpansPtr
void setTableBox(const SwTableBox *pTableBox)
SwTableLine * GetUpper()
Definition: swtable.hxx:421
const SwRect & getRect() const
bool IsTextNode() const
Definition: node.hxx:636
std::shared_ptr< WW8TableNodeInfo > Pointer_t
void setTable(const SwTable *pTable)
WidthsPtr getWidthsOfRow(WW8TableNodeInfoInner const *pNodeInfo)
sal_uInt32 getRow() const
void setVertMerge(bool bVertMerge)
bool operator<(const CellInfo &aCellInfo) const
WW8TableNodeInfo *const m_pNodeInfo
const unsigned int MAXTABLECELLS
OUString toString(OptionInfo const *info)
SwTableNode * GetTableNode() const
Definition: swtable.cxx:1927
Base class of the Writer document model elements.
Definition: node.hxx:79