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