bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / WW8TableInfo.cxx
blobb58fee87f2a526958c9c6e128f91f9cdea15849f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <iostream>
22 #include <set>
23 #include <stdio.h>
24 #include "WW8TableInfo.hxx"
25 #include "fmtfsize.hxx"
26 #include "attributeoutputbase.hxx"
27 #include "swtable.hxx"
28 #include "frmfmt.hxx"
29 #include "pam.hxx"
30 #include "ndtxt.hxx"
31 #include "dbgoutsw.hxx"
33 namespace ww8
36 // WW8TableNodeInfoInner
38 WW8TableNodeInfoInner::WW8TableNodeInfoInner(WW8TableNodeInfo * pParent)
39 : mpParent(pParent)
40 , mnCell(0)
41 , mnRow(0)
42 , mnShadowsBefore(0)
43 , mnShadowsAfter(0)
44 , mbEndOfLine(false)
45 , mbEndOfCell(false)
46 , mbFirstInTable(false)
47 , mbVertMerge(false)
48 , mpTableBox(NULL)
49 , mpTable(NULL)
53 WW8TableNodeInfoInner::~WW8TableNodeInfoInner()
57 void WW8TableNodeInfoInner::setDepth(sal_uInt32 nDepth)
59 mnDepth = nDepth;
62 void WW8TableNodeInfoInner::setCell(sal_uInt32 nCell)
64 mnCell = nCell;
67 void WW8TableNodeInfoInner::setRow(sal_uInt32 nRow)
69 mnRow = nRow;
72 void WW8TableNodeInfoInner::setShadowsBefore(sal_uInt32 nShadowsBefore)
74 mnShadowsBefore = nShadowsBefore;
77 void WW8TableNodeInfoInner::setShadowsAfter(sal_uInt32 nShadowsAfter)
79 mnShadowsAfter = nShadowsAfter;
82 void WW8TableNodeInfoInner::setEndOfLine(bool bEndOfLine)
84 mbEndOfLine = bEndOfLine;
87 void WW8TableNodeInfoInner::setEndOfCell(bool bEndOfCell)
89 mbEndOfCell = bEndOfCell;
92 void WW8TableNodeInfoInner::setFirstInTable(bool bFirstInTable)
94 mbFirstInTable = bFirstInTable;
97 void WW8TableNodeInfoInner::setVertMerge(bool bVertMerge)
100 mbVertMerge = bVertMerge;
103 void WW8TableNodeInfoInner::setTableBox(const SwTableBox * pTableBox)
105 mpTableBox = pTableBox;
108 void WW8TableNodeInfoInner::setTable(const SwTable * pTable)
110 mpTable = pTable;
113 void WW8TableNodeInfoInner::setRect(const SwRect & rRect)
115 maRect = rRect;
118 sal_uInt32 WW8TableNodeInfoInner::getDepth() const
120 return mnDepth;
123 sal_uInt32 WW8TableNodeInfoInner::getCell() const
125 return mnCell;
128 sal_uInt32 WW8TableNodeInfoInner::getRow() const
130 return mnRow;
133 sal_uInt32 WW8TableNodeInfoInner::getShadowsBefore() const
135 return mnShadowsBefore;
138 sal_uInt32 WW8TableNodeInfoInner::getShadowsAfter() const
140 return mnShadowsAfter;
143 bool WW8TableNodeInfoInner::isEndOfCell() const
145 return mbEndOfCell;
148 bool WW8TableNodeInfoInner::isEndOfLine() const
150 return mbEndOfLine;
153 bool WW8TableNodeInfoInner::isFirstInTable() const
155 return mbFirstInTable;
158 const SwNode * WW8TableNodeInfoInner::getNode() const
160 const SwNode * pResult = NULL;
162 if (mpParent != NULL)
163 pResult = mpParent->getNode();
165 return pResult;
168 TableBoxVectorPtr WW8TableNodeInfoInner::getTableBoxesOfRow()
170 TableBoxVectorPtr pResult(new TableBoxVector);
172 WW8TableCellGrid::Pointer_t pCellGrid =
173 mpParent->getParent()->getCellGridForTable(getTable(), false);
175 if (pCellGrid.get() == NULL)
177 const SwTableLine * pTabLine = getTableBox()->GetUpper();
178 const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();
180 sal_uInt8 nBoxes = rTblBoxes.size();
181 for ( sal_uInt8 n = 0; n < nBoxes; n++ )
183 pResult->push_back(rTblBoxes[n]);
186 else
187 pResult = pCellGrid->getTableBoxesOfRow(this);
189 return pResult;
192 GridColsPtr WW8TableNodeInfoInner::getGridColsOfRow(AttributeOutputBase & rBase)
194 GridColsPtr pResult(new GridCols);
195 WidthsPtr pWidths(getWidthsOfRow());
197 const SwFrmFmt *pFmt = getTable()->GetFrmFmt();
198 OSL_ENSURE(pFmt,"Impossible");
199 if (!pFmt)
200 return pResult;
202 const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
203 unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
205 sal_uInt32 nPageSize = 0;
206 bool bRelBoxSize = false;
208 rBase.GetTablePageSize
209 ( this, nPageSize, bRelBoxSize );
211 SwTwips nSz = 0;
212 Widths::const_iterator aWidthsEnd = pWidths->end();
213 for ( Widths::const_iterator aIt = pWidths->begin();
214 aIt != aWidthsEnd;
215 ++aIt)
217 nSz += *aIt;
218 SwTwips nCalc = nSz;
219 if ( bRelBoxSize )
220 nCalc = ( nCalc * nPageSize ) / nTblSz;
222 pResult->push_back( nCalc );
225 return pResult;
228 WidthsPtr WW8TableNodeInfoInner::getWidthsOfRow()
230 WidthsPtr pWidths;
232 WW8TableCellGrid::Pointer_t pCellGrid =
233 mpParent->getParent()->getCellGridForTable(getTable(), false);
235 if (pCellGrid.get() == NULL)
237 const SwTableBox * pTabBox = getTableBox();
238 const SwTableLine * pTabLine = pTabBox->GetUpper();
239 const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
241 pWidths = WidthsPtr(new Widths);
242 // number of cell written
243 sal_uInt32 nBoxes = rTabBoxes.size();
244 if ( nBoxes > MAXTABLECELLS )
245 nBoxes = MAXTABLECELLS;
247 for (sal_uInt32 n = 0; n < nBoxes; n++)
249 const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt();
250 const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize();
252 pWidths->push_back(rLSz.GetWidth());
255 else
256 pWidths = pCellGrid->getWidthsOfRow(this);
258 return pWidths;
261 RowSpansPtr WW8TableNodeInfoInner::getRowSpansOfRow()
263 RowSpansPtr pResult(new RowSpans);
265 WW8TableCellGrid::Pointer_t pCellGrid =
266 mpParent->getParent()->getCellGridForTable(getTable(), false);
268 if (pCellGrid.get() == NULL)
270 const SwTableBox * pTabBox = getTableBox();
271 const SwTableLine * pTabLine = pTabBox->GetUpper();
272 const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
274 sal_uInt32 nBoxes = rTabBoxes.size();
275 if (nBoxes > MAXTABLECELLS)
276 nBoxes = MAXTABLECELLS;
278 for (sal_uInt32 n = 0; n < nBoxes; ++n)
280 pResult->push_back(rTabBoxes[n]->getRowSpan());
283 else
284 pResult = pCellGrid->getRowSpansOfRow(this);
286 return pResult;
289 const SwTableBox * WW8TableNodeInfoInner::getTableBox() const
291 return mpTableBox;
294 const SwTable * WW8TableNodeInfoInner::getTable() const
296 return mpTable;
299 const SwRect & WW8TableNodeInfoInner::getRect() const
301 return maRect;
304 #ifdef DBG_UTIL
305 ::std::string WW8TableNodeInfoInner::toString() const
307 static char buffer[256];
308 snprintf(buffer, sizeof(buffer),
309 "<tableinner depth=\"%" SAL_PRIuUINT32 "\""
310 " cell=\"%" SAL_PRIuUINT32 "\""
311 " row=\"%" SAL_PRIuUINT32 "\""
312 " endOfCell=\"%s\""
313 " endOfLine=\"%s\""
314 " shadowsBefore=\"%" SAL_PRIuUINT32 "\""
315 " shadowsAfter=\"%" SAL_PRIuUINT32 "\""
316 " vertMerge=\"%s\"/>",
317 mnDepth, mnCell, mnRow,
318 mbEndOfCell ? "yes" : "no",
319 mbEndOfLine ? "yes" : "no",
320 mnShadowsBefore,
321 mnShadowsAfter,
322 mbVertMerge ? "yes" : "no");
324 return string(buffer);
326 #endif
328 WW8TableNodeInfo::WW8TableNodeInfo(WW8TableInfo * pParent,
329 const SwNode * pNode)
330 : mpParent(pParent),
331 mnDepth(0),
332 mpNode(pNode),
333 mpNext(NULL),
334 mpNextNode(NULL)
338 WW8TableNodeInfo::~WW8TableNodeInfo()
342 #ifdef DBG_UTIL
343 ::std::string WW8TableNodeInfo::toString() const
345 static char buffer[1024];
346 snprintf(buffer, sizeof(buffer),
347 "<tableNodeInfo p=\"%p\" depth=\"%" SAL_PRIuUINT32 "\">"
348 ,this, getDepth());
350 ::std::string sResult(buffer);
352 Inners_t::const_iterator aIt(mInners.begin());
353 Inners_t::const_iterator aEnd(mInners.end());
355 while (aIt != aEnd)
357 WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
358 sResult += pInner->toString();
360 ++aIt;
362 sResult += dbg_out(*mpNode);
363 sResult += "</tableNodeInfo>";
365 return sResult;
367 #endif
369 void WW8TableNodeInfo::setDepth(sal_uInt32 nDepth)
371 mnDepth = nDepth;
373 Inners_t::iterator aIt = mInners.find(mnDepth);
375 if (aIt == mInners.end())
376 mInners[mnDepth] = WW8TableNodeInfoInner::Pointer_t(new WW8TableNodeInfoInner(this));
378 mInners[mnDepth]->setDepth(mnDepth);
381 void WW8TableNodeInfo::setEndOfLine(bool bEndOfLine)
383 WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
384 pInner->setEndOfLine(bEndOfLine);
386 #ifdef DBG_UTIL
387 SAL_INFO( "sw.ww8", "<endOfLine depth=\"" << mnDepth << "\">" << toString() << "</endOfLine>" );
388 #endif
391 void WW8TableNodeInfo::setEndOfCell(bool bEndOfCell)
393 WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
394 pInner->setEndOfCell(bEndOfCell);
396 #ifdef DBG_UTIL
397 SAL_INFO( "sw.ww8", "<endOfCell depth=\"" << mnDepth << "\">" << toString() << "</endOfCell>" );
398 #endif
401 void WW8TableNodeInfo::setFirstInTable(bool bFirstInTable)
403 WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
405 pInner->setFirstInTable(bFirstInTable);
407 #ifdef DBG_UTIL
408 SAL_INFO( "sw.ww8", "<firstInTable depth=\"" << mnDepth << "\">" << toString() << "</firstInTable>" );
409 #endif
412 void WW8TableNodeInfo::setVertMerge(bool bVertMerge)
414 WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
416 pInner->setVertMerge(bVertMerge);
418 #ifdef DBG_UTIL
419 SAL_INFO( "sw.ww8", "<vertMerge depth=\"" << mnDepth << "\">" << toString() << "</vertMerge>" );
420 #endif
423 void WW8TableNodeInfo::setTableBox(const SwTableBox * pTableBox)
425 getInnerForDepth(mnDepth)->setTableBox(pTableBox);
428 void WW8TableNodeInfo::setTable(const SwTable * pTable)
430 getInnerForDepth(mnDepth)->setTable(pTable);
433 void WW8TableNodeInfo::setNext(WW8TableNodeInfo * pNext)
435 mpNext = pNext;
437 #ifdef DBG_UTIL
438 SAL_INFO( "sw.ww8", "<setnext><from>" << toString() << "</from><to>" << pNext->toString() << "</to></setnext>" );
439 #endif
442 void WW8TableNodeInfo::setNextNode(const SwNode * pNode)
444 mpNextNode = pNode;
447 void WW8TableNodeInfo::setRect(const SwRect & rRect)
449 getInnerForDepth(mnDepth)->setRect(rRect);
452 void WW8TableNodeInfo::setCell(sal_uInt32 nCell)
454 getInnerForDepth(mnDepth)->setCell(nCell);
457 void WW8TableNodeInfo::setRow(sal_uInt32 nRow)
459 getInnerForDepth(mnDepth)->setRow(nRow);
462 void WW8TableNodeInfo::setShadowsBefore(sal_uInt32 nShadowsBefore)
464 getInnerForDepth(mnDepth)->setShadowsBefore(nShadowsBefore);
467 void WW8TableNodeInfo::setShadowsAfter(sal_uInt32 nShadowsAfter)
469 getInnerForDepth(mnDepth)->setShadowsAfter(nShadowsAfter);
472 WW8TableInfo * WW8TableNodeInfo::getParent() const
474 return mpParent;
477 sal_uInt32 WW8TableNodeInfo::getDepth() const
479 if (!mInners.empty())
480 return mInners.begin()->second->getDepth();
482 return mnDepth;
485 const SwNode * WW8TableNodeInfo::getNode() const
487 return mpNode;
490 const SwTableBox * WW8TableNodeInfo::getTableBox() const
492 return getInnerForDepth(mnDepth)->getTableBox();
495 WW8TableNodeInfo * WW8TableNodeInfo::getNext() const
497 return mpNext;
500 const SwNode * WW8TableNodeInfo::getNextNode() const
502 return mpNextNode;
505 sal_uInt32 WW8TableNodeInfo::getCell() const
507 return getInnerForDepth(mnDepth)->getCell();
510 sal_uInt32 WW8TableNodeInfo::getRow() const
512 return getInnerForDepth(mnDepth)->getRow();
515 const ww8::WW8TableNodeInfo::Inners_t & WW8TableNodeInfo::getInners() const
517 return mInners;
520 const WW8TableNodeInfoInner::Pointer_t WW8TableNodeInfo::getFirstInner() const
522 WW8TableNodeInfoInner::Pointer_t pResult;
524 if (!mInners.empty())
525 pResult = mInners.begin()->second;
527 return pResult;
530 const WW8TableNodeInfoInner::Pointer_t WW8TableNodeInfo::getInnerForDepth(sal_uInt32 nDepth) const
532 WW8TableNodeInfoInner::Pointer_t pResult;
534 Inners_t::const_iterator aIt = mInners.find(nDepth);
535 if (aIt != mInners.end())
537 pResult = aIt->second;
540 return pResult;
543 // WW8TableInfo
545 WW8TableInfo::WW8TableInfo()
549 WW8TableInfo::~WW8TableInfo()
553 WW8TableNodeInfo *
554 WW8TableInfo::processSwTableByLayout(const SwTable * pTable)
556 SwTableCellInfo aTableCellInfo(pTable);
557 WW8TableNodeInfo * pPrev = NULL;
559 while (aTableCellInfo.getNext())
561 SwRect aRect = aTableCellInfo.getRect();
563 SAL_INFO( "sw.ww8", "<CellFrm>" );
564 SAL_INFO( "sw.ww8", "<rect top=\"" << aRect.Top() << "\" bottom=\"" << aRect.Bottom()
565 << "\" left=\"" << aRect.Left() << "\" right=\"" << aRect.Right() << "\"/>" );
566 const SwTableBox * pTableBox = aTableCellInfo.getTableBox();
567 const SwStartNode * pSttNd = pTableBox->GetSttNd();
569 if (pSttNd != NULL)
571 SwPaM aPam(*pSttNd, 0);
573 bool bDone = false;
576 SwNode & rNode = aPam.GetPoint()->nNode.GetNode();
578 insertTableNodeInfo(&rNode, pTable, pTableBox, 0, 0, 1, & aRect);
580 if (rNode.IsEndNode())
582 SwEndNode * pEndNode = rNode.GetEndNode();
583 SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
585 if (pTmpSttNd == pSttNd)
586 bDone = true;
589 aPam.GetPoint()->nNode++;
591 while (!bDone);
594 SAL_INFO( "sw.ww8", "</CellFrm>" );
597 pPrev = reorderByLayout(pTable);
599 return pPrev;
602 void WW8TableInfo::processSwTable(const SwTable * pTable)
604 SAL_INFO( "sw.ww8", "<processSwTable>" );
606 WW8TableNodeInfo * pPrev = NULL;
608 if (pTable->IsTblComplex() && pTable->HasLayout())
610 pPrev = processSwTableByLayout(pTable);
612 #ifdef DBG_UTIL
613 SAL_INFO( "sw.ww8", getCellGridForTable(pTable)->toString());
614 #endif
616 else
618 const SwTableLines & rLines = pTable->GetTabLines();
620 for (sal_uInt16 n = 0; n < rLines.size(); n++)
622 const SwTableLine * pLine = rLines[n];
624 pPrev = processTableLine(pTable, pLine, n, 1, pPrev);
629 if (pPrev != NULL)
631 SwTableNode * pTableNode = pTable->GetTableNode();
632 SwEndNode * pEndNode = pTableNode->EndOfSectionNode();
634 pPrev->setNextNode(pEndNode);
636 SAL_INFO( "sw.ww8", "</processSwTable>" );
639 WW8TableNodeInfo *
640 WW8TableInfo::processTableLine(const SwTable * pTable,
641 const SwTableLine * pTableLine,
642 sal_uInt32 nRow,
643 sal_uInt32 nDepth, WW8TableNodeInfo * pPrev)
645 SAL_INFO( "sw.ww8", "<processTableLine row=\"" << nRow << "\" depth=\"" << nDepth << "\">" );
647 const SwTableBoxes & rBoxes = pTableLine->GetTabBoxes();
649 WW8TableNodeInfo::Pointer_t pTextNodeInfo;
651 for (sal_uInt16 n = 0; n < rBoxes.size(); n++)
653 const SwTableBox * pBox = rBoxes[n];
655 pPrev = processTableBox(pTable, pBox, nRow, n, nDepth, n == rBoxes.size() - 1, pPrev);
658 SAL_INFO( "sw.ww8", "</processTableLine>" );
660 return pPrev;
663 WW8TableNodeInfo::Pointer_t
664 WW8TableInfo::processTableBoxLines(const SwTableBox * pBox,
665 const SwTable * pTable,
666 const SwTableBox * pBoxToSet,
667 sal_uInt32 nRow,
668 sal_uInt32 nCell,
669 sal_uInt32 nDepth)
671 SAL_INFO( "sw.ww8", "<processTableBoxLines depth=\"" << nDepth << "\" row=\"" << nRow
672 << "\" cell=\"" << nCell << "\">" );
674 const SwTableLines & rLines = pBox->GetTabLines();
675 WW8TableNodeInfo::Pointer_t pNodeInfo;
677 if (!rLines.empty())
679 for (sal_uInt32 n = 0; n < rLines.size(); n++)
681 const SwTableLine * pLine = rLines[n];
682 const SwTableBoxes & rBoxes = pLine->GetTabBoxes();
684 for (sal_uInt16 nBox = 0; nBox < rBoxes.size(); nBox++)
685 pNodeInfo = processTableBoxLines(rBoxes[nBox], pTable, pBoxToSet, nRow, nCell, nDepth);
688 else
690 const SwStartNode * pSttNd = pBox->GetSttNd();
691 const SwEndNode * pEndNd = pSttNd->EndOfSectionNode();
692 SwPaM aPaM(*pSttNd, 0);
693 SwPaM aEndPaM(*pEndNd, 0);
695 bool bDone = false;
696 while (!bDone)
698 SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
700 pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBoxToSet, nRow, nCell, nDepth);
702 if (aPaM.GetPoint()->nNode == aEndPaM.GetPoint()->nNode)
703 bDone = true;
704 else
705 aPaM.GetPoint()->nNode++;
709 SAL_INFO( "sw.ww8", "</processTableBoxLines>" );
711 return pNodeInfo;
714 WW8TableNodeInfo *
715 WW8TableInfo::processTableBox(const SwTable * pTable,
716 const SwTableBox * pBox,
717 sal_uInt32 nRow,
718 sal_uInt32 nCell,
719 sal_uInt32 nDepth,
720 bool bEndOfLine,
721 WW8TableNodeInfo * pPrev)
723 SAL_INFO( "sw.ww8", "<processTableBox row=\"" << nRow << "\" cell=\"" << nCell
724 << "\" depth=\"" << nDepth << "\">" );
726 WW8TableNodeInfo::Pointer_t pNodeInfo;
727 const SwTableLines & rLines = pBox->GetTabLines();
728 const SwStartNode * pSttNd = pBox->GetSttNd();
729 WW8TableNodeInfo::Pointer_t pEndOfCellInfo;
731 if (!rLines.empty())
733 pNodeInfo = processTableBoxLines(pBox, pTable, pBox, nRow, nCell, nDepth);
734 pNodeInfo->setEndOfCell(true);
735 if (bEndOfLine)
736 pNodeInfo->setEndOfLine(true);
738 for (sal_uInt32 n = 0; n < rLines.size(); n++)
740 const SwTableLine * pLine = rLines[n];
742 pPrev = processTableLine(pTable, pLine, n, 1, pPrev);
745 else
747 SwPaM aPaM(*pSttNd, 0);
749 bool bDone = false;
750 sal_uInt32 nDepthInsideCell = 0;
754 SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
756 if (rNode.IsStartNode())
758 if (nDepthInsideCell > 0)
759 pEndOfCellInfo.reset();
761 nDepthInsideCell++;
764 pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBox, nRow, nCell, nDepth);
766 if (pPrev != NULL)
767 pPrev->setNext(pNodeInfo.get());
769 pPrev = pNodeInfo.get();
771 if (nDepthInsideCell == 1 && rNode.IsTxtNode())
772 pEndOfCellInfo = pNodeInfo;
774 if (rNode.IsEndNode())
776 nDepthInsideCell--;
778 if (nDepthInsideCell == 0 && pEndOfCellInfo.get() == NULL)
779 pEndOfCellInfo = pNodeInfo;
781 SwEndNode * pEndNode = rNode.GetEndNode( );
782 SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
783 if (pTmpSttNd == pSttNd)
784 bDone = true;
787 aPaM.GetPoint()->nNode++;
789 while (!bDone);
791 if (pEndOfCellInfo.get() != NULL)
793 pEndOfCellInfo->setEndOfCell(true);
795 if (bEndOfLine)
796 pEndOfCellInfo->setEndOfLine(true);
800 SAL_INFO( "sw.ww8", "</processTableBox>" );
802 return pPrev;
805 WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo
806 (const SwNode * pNode,
807 const SwTable * pTable,
808 const SwTableBox * pTableBox,
809 sal_uInt32 nRow,
810 sal_uInt32 nCell,
811 sal_uInt32 nDepth,
812 SwRect * pRect)
814 WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode);
816 if (pNodeInfo.get() == NULL)
818 pNodeInfo =
819 WW8TableNodeInfo::Pointer_t(new WW8TableNodeInfo(this, pNode));
820 mMap.insert(Map_t::value_type(pNode, pNodeInfo));
823 pNodeInfo->setDepth(nDepth + pNodeInfo->getDepth());
825 pNodeInfo->setTable(pTable);
826 pNodeInfo->setTableBox(pTableBox);
828 pNodeInfo->setCell(nCell);
829 pNodeInfo->setRow(nRow);
831 if (pNode->IsTxtNode())
833 FirstInTableMap_t::const_iterator aIt = mFirstInTableMap.find(pTable);
834 if (aIt == mFirstInTableMap.end())
836 mFirstInTableMap[pTable] = pNode;
837 pNodeInfo->setFirstInTable(true);
841 if (pRect)
843 WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable);
845 pCellGrid->insert(*pRect, pNodeInfo.get());
846 pNodeInfo->setRect(*pRect);
849 #ifdef DBG_UTIL
850 SAL_INFO( "sw.ww8", pNodeInfo->toString());
851 #endif
852 return pNodeInfo;
855 WW8TableCellGrid::Pointer_t WW8TableInfo::getCellGridForTable
856 (const SwTable * pTable, bool bCreate)
858 WW8TableCellGrid::Pointer_t pResult;
859 CellGridMap_t::iterator aIt = mCellGridMap.find(pTable);
861 if (aIt == mCellGridMap.end())
863 if (bCreate)
865 pResult = WW8TableCellGrid::Pointer_t(new WW8TableCellGrid);
866 mCellGridMap[pTable] = pResult;
869 else
870 pResult = mCellGridMap[pTable];
872 return pResult;
875 WW8TableNodeInfo::Pointer_t WW8TableInfo::getTableNodeInfo
876 (const SwNode * pNode)
878 WW8TableNodeInfo::Pointer_t pResult;
879 Map_t::iterator aIt = mMap.find(pNode);
881 if (aIt != mMap.end())
882 pResult = (*aIt).second;
884 return pResult;
887 const SwNode * WW8TableInfo::getNextNode(const SwNode * pNode)
889 const SwNode * pResult = NULL;
891 WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode);
893 if (pNodeInfo.get() != NULL)
895 WW8TableNodeInfo * pNextInfo = pNodeInfo->getNext();
897 if (pNextInfo != NULL)
898 pResult = pNextInfo->getNode();
899 else
901 const SwNode * pNextNode = pNodeInfo->getNextNode();
903 if (pNextNode != NULL)
904 pResult = pNextNode;
908 return pResult;
911 bool WW8TableNodeInfo::operator < (const WW8TableNodeInfo & rInfo) const
913 bool bRet = false;
915 if (rInfo.mpNode != NULL)
917 if (mpNode == NULL)
919 bRet = true;
921 else
923 if (mpNode->GetIndex() < rInfo.mpNode->GetIndex())
924 bRet = true;
928 return bRet;
931 bool CellInfo::operator < (const CellInfo & aCellInfo) const
933 bool aRet = false;
935 if (top() < aCellInfo.top())
936 aRet = true;
937 else if (top() == aCellInfo.top())
939 if (left() < aCellInfo.left())
940 aRet = true;
941 else if (left() == aCellInfo.left())
943 if (width() < aCellInfo.width())
944 aRet = true;
945 else if (width() == aCellInfo.width())
947 if (height() < aCellInfo.height())
948 aRet = true;
949 else if (height() == aCellInfo.height())
951 if (aCellInfo.getTableNodeInfo() != NULL)
953 if (m_pNodeInfo == NULL)
954 aRet = true;
955 else
957 aRet = *m_pNodeInfo < *aCellInfo.getTableNodeInfo();
965 return aRet;
968 #ifdef DBG_UTIL
969 ::std::string CellInfo::toString() const
971 static char sBuffer[256];
973 snprintf(sBuffer, sizeof(sBuffer),
974 "<cellinfo left=\"%ld\""
975 " right=\"%ld\""
976 " top=\"%ld\""
977 " bottom=\"%ld\""
978 " node=\"%p\"/>",
979 left(),
980 right(),
981 top(),
982 bottom(),
983 m_pNodeInfo);
985 return sBuffer;
987 #endif
989 WW8TableNodeInfo * WW8TableInfo::reorderByLayout(const SwTable * pTable)
991 WW8TableNodeInfo * pPrev = NULL;
992 WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable);
994 #ifdef DBG_UTIL
995 SAL_INFO( "sw.ww8", pCellGrid->toString());
996 #endif
998 pCellGrid->addShadowCells();
999 pPrev = pCellGrid->connectCells();
1001 return pPrev;
1004 WW8TableCellGrid::WW8TableCellGrid()
1008 WW8TableCellGrid::~WW8TableCellGrid()
1012 WW8TableCellGridRow::Pointer_t WW8TableCellGrid::getRow(long nTop, bool bCreate)
1014 WW8TableCellGridRow::Pointer_t pResult;
1016 RowTops_t::iterator aIt = m_aRowTops.find(nTop);
1018 if (aIt == m_aRowTops.end())
1020 if (bCreate)
1022 pResult = WW8TableCellGridRow::Pointer_t(new WW8TableCellGridRow);
1023 m_aRows[nTop] = pResult;
1024 m_aRowTops.insert(nTop);
1027 else
1028 pResult = m_aRows[nTop];
1030 return pResult;
1033 WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsBegin() const
1035 return m_aRowTops.begin();
1038 WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsEnd() const
1040 return m_aRowTops.end();
1043 CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsBegin(long nTop)
1045 return getRow(nTop)->begin();
1048 CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsEnd(long nTop)
1050 return getRow(nTop)->end();
1053 void WW8TableCellGrid::insert(const SwRect & rRect,
1054 WW8TableNodeInfo * pNodeInfo,
1055 unsigned long * pFmtFrmWidth)
1057 CellInfo aCellInfo(rRect, pNodeInfo);
1059 if (pFmtFrmWidth != NULL)
1060 aCellInfo.setFmtFrmWidth(*pFmtFrmWidth);
1062 WW8TableCellGridRow::Pointer_t pRow = getRow(rRect.Top());
1063 pRow->insert(aCellInfo);
1066 void WW8TableCellGrid::addShadowCells()
1068 SAL_INFO( "sw.ww8", "<addShadowCells>" );
1070 RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1072 while (aTopsIt != getRowTopsEnd())
1074 #ifdef DBG_UTIL
1075 long nTop = *aTopsIt;
1076 (void) nTop;
1077 #endif
1078 CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1079 CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
1081 RowSpansPtr pRowSpans(new RowSpans);
1083 bool bBeginningOfCell = true;
1084 bool bVertMerge = false;
1085 SwRect aRect = aCellIt->getRect();
1086 long nRowSpan = 1;
1087 while (aCellIt != aCellEndIt)
1089 WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
1091 if (bBeginningOfCell)
1093 RowTops_t::const_iterator aRowSpanIt(aTopsIt);
1094 ++aRowSpanIt;
1096 if (aRowSpanIt != getRowTopsEnd() &&
1097 *aRowSpanIt < aCellIt->bottom())
1099 aRect.Top(*aRowSpanIt);
1100 unsigned long nFmtFrmWidth = aCellIt->getFmtFrmWidth();
1101 insert(aRect, NULL, &nFmtFrmWidth);
1103 bVertMerge = true;
1105 else
1106 bVertMerge = false;
1108 nRowSpan = 1;
1109 while (aRowSpanIt != getRowTopsEnd() &&
1110 *aRowSpanIt < aCellIt->bottom())
1112 ++aRowSpanIt;
1113 nRowSpan++;
1116 if (pNodeInfo != NULL)
1117 pRowSpans->push_back(nRowSpan);
1118 else
1119 pRowSpans->push_back(-nRowSpan);
1122 if (pNodeInfo != NULL)
1124 pNodeInfo->setVertMerge(bVertMerge);
1127 ++aCellIt;
1128 if (aCellIt != aCellEndIt)
1130 bBeginningOfCell = (aRect.Left() != aCellIt->left());
1131 aRect = aCellIt->getRect();
1135 WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
1136 if (pRow.get() != NULL)
1137 pRow->setRowSpans(pRowSpans);
1139 ++aTopsIt;
1141 SAL_INFO( "sw.ww8", "</addShadowCells>" );
1144 WW8TableNodeInfo * WW8TableCellGrid::connectCells()
1146 RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1147 sal_uInt32 nRow = 0;
1148 WW8TableNodeInfo * pLastNodeInfo = NULL;
1150 while (aTopsIt != getRowTopsEnd())
1152 CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1153 CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
1154 GridColsPtr pWidths(new Widths);
1155 TableBoxVectorPtr pTableBoxes(new TableBoxVector);
1157 sal_uInt32 nShadows = 0;
1158 sal_uInt32 nCell = 0;
1159 bool bBeginningOfCell = true;
1160 WW8TableNodeInfo * pEndOfCellInfo = NULL;
1161 sal_uInt32 nDepthInCell = 0;
1162 while (aCellIt != aCellEndIt)
1164 long nCellX = aCellIt->left();
1165 WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
1166 if (pNodeInfo != NULL)
1168 const SwNode * pNode = pNodeInfo->getNode();
1170 if (pNode->IsStartNode())
1172 nDepthInCell++;
1173 pEndOfCellInfo = NULL;
1176 if (nDepthInCell == 1 && pNode->IsTxtNode())
1177 pEndOfCellInfo = pNodeInfo;
1179 pNodeInfo->setShadowsBefore(nShadows);
1180 pNodeInfo->setCell(nCell);
1181 pNodeInfo->setRow(nRow);
1182 if (pLastNodeInfo != NULL)
1184 pLastNodeInfo->setNext(pNodeInfo);
1185 pLastNodeInfo->setNextNode(pNode);
1187 pLastNodeInfo = pNodeInfo;
1188 nShadows = 0;
1190 if (pNode->IsEndNode())
1192 nDepthInCell--;
1194 if (nDepthInCell == 0 && pEndOfCellInfo == NULL)
1195 pEndOfCellInfo = pNodeInfo;
1198 else
1200 nShadows++;
1203 if (bBeginningOfCell)
1205 pWidths->push_back(aCellIt->getFmtFrmWidth());
1207 if (pNodeInfo != NULL)
1208 pTableBoxes->push_back(pNodeInfo->getTableBox());
1209 else
1210 pTableBoxes->push_back(NULL);
1213 ++aCellIt;
1214 bBeginningOfCell = false;
1216 if (aCellIt != aCellEndIt && aCellIt->left() != nCellX)
1218 nCell++;
1219 bBeginningOfCell = true;
1221 if (pEndOfCellInfo != NULL)
1223 pEndOfCellInfo->setEndOfCell(true);
1226 pEndOfCellInfo = NULL;
1230 pLastNodeInfo->setShadowsAfter(nShadows);
1232 if (pEndOfCellInfo == NULL)
1234 pEndOfCellInfo = pLastNodeInfo;
1237 pEndOfCellInfo->setEndOfCell(true);
1238 pLastNodeInfo->setEndOfLine(true);
1240 WW8TableCellGridRow::Pointer_t pRow(getRow(*aTopsIt));
1241 pRow->setTableBoxVector(pTableBoxes);
1242 pRow->setWidths(pWidths);
1244 nShadows = 0;
1246 ++aTopsIt;
1247 nRow++;
1250 return pLastNodeInfo;
1253 #ifdef DBG_UTIL
1254 ::std::string WW8TableCellGrid::toString()
1256 string sResult = "<WW8TableCellGrid>";
1258 RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
1259 static char sBuffer[1024];
1260 while (aTopsIt != getRowTopsEnd())
1262 sprintf(sBuffer, "<row y=\"%ld\">", *aTopsIt);
1263 sResult += sBuffer;
1265 CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
1266 CellInfoMultiSet::const_iterator aCellsEnd = getCellsEnd(*aTopsIt);
1268 while (aCellIt != aCellsEnd)
1270 snprintf(sBuffer, sizeof(sBuffer), "<cellInfo top=\"%ld\" bottom=\"%ld\" left=\"%ld\" right=\"%ld\">",
1271 aCellIt->top(), aCellIt->bottom(), aCellIt->left(), aCellIt->right());
1272 sResult += sBuffer;
1274 WW8TableNodeInfo * pInfo = aCellIt->getTableNodeInfo();
1275 if (pInfo != NULL)
1276 sResult += pInfo->toString();
1277 else
1278 sResult += "<shadow/>\n";
1280 sResult += "</cellInfo>\n";
1281 ++aCellIt;
1284 WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
1285 WidthsPtr pWidths = pRow->getWidths();
1286 if (pWidths != NULL)
1288 sResult += "<widths>";
1290 Widths::const_iterator aItEnd = pWidths->end();
1291 for (Widths::const_iterator aIt = pWidths->begin();
1292 aIt != aItEnd;
1293 ++aIt)
1295 if (aIt != pWidths->begin())
1296 sResult += ", ";
1298 snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
1299 sResult += sBuffer;
1302 sResult += "</widths>";
1305 RowSpansPtr pRowSpans = pRow->getRowSpans();
1306 if (pRowSpans.get() != NULL)
1308 sResult += "<rowspans>";
1310 RowSpans::const_iterator aItEnd = pRowSpans->end();
1311 for (RowSpans::const_iterator aIt = pRowSpans->begin();
1312 aIt != aItEnd;
1313 ++aIt)
1315 if (aIt != pRowSpans->begin())
1316 sResult += ", ";
1318 snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
1319 sResult += sBuffer;
1322 sResult += "</rowspans>";
1325 sResult += "</row>\n";
1326 ++aTopsIt;
1329 sResult += "</WW8TableCellGrid>\n";
1331 return sResult;
1333 #endif
1335 TableBoxVectorPtr WW8TableCellGrid::getTableBoxesOfRow
1336 (WW8TableNodeInfoInner * pNodeInfoInner)
1338 TableBoxVectorPtr pResult;
1339 WW8TableCellGridRow::Pointer_t pRow =
1340 getRow(pNodeInfoInner->getRect().Top(), false);
1342 if (pRow.get() != NULL)
1344 pResult = pRow->getTableBoxVector();
1347 return pResult;
1350 WidthsPtr WW8TableCellGrid::getWidthsOfRow
1351 (WW8TableNodeInfoInner * pNodeInfoInner)
1353 GridColsPtr pResult;
1355 WW8TableCellGridRow::Pointer_t pRow =
1356 getRow(pNodeInfoInner->getRect().Top(), false);
1358 if (pRow.get() != NULL)
1360 pResult = pRow->getWidths();
1363 return pResult;
1366 RowSpansPtr WW8TableCellGrid::getRowSpansOfRow
1367 (WW8TableNodeInfoInner * pNodeInfoInner)
1369 RowSpansPtr pResult;
1371 WW8TableCellGridRow::Pointer_t pRow =
1372 getRow(pNodeInfoInner->getRect().Top(), false);
1374 if (pRow.get() != NULL)
1376 pResult = pRow->getRowSpans();
1379 return pResult;
1382 WW8TableCellGridRow::WW8TableCellGridRow()
1383 : m_pCellInfos(new CellInfoMultiSet)
1387 WW8TableCellGridRow::~WW8TableCellGridRow()
1391 void WW8TableCellGridRow::insert(const CellInfo & rCellInfo)
1393 m_pCellInfos->insert(rCellInfo);
1395 #ifdef DBG_UTIL
1396 SAL_INFO( "sw.ww8", "<gridRowInsert>" << rCellInfo.toString() << "</gridRowInsert>" );
1397 #endif
1400 CellInfoMultiSet::const_iterator WW8TableCellGridRow::begin() const
1402 return m_pCellInfos->begin();
1405 CellInfoMultiSet::const_iterator WW8TableCellGridRow::end() const
1407 return m_pCellInfos->end();
1410 void WW8TableCellGridRow::setTableBoxVector(TableBoxVectorPtr pTableBoxVector)
1412 m_pTableBoxVector = pTableBoxVector;
1415 void WW8TableCellGridRow::setWidths(WidthsPtr pWidths)
1417 m_pWidths = pWidths;
1420 void WW8TableCellGridRow::setRowSpans(RowSpansPtr pRowSpans)
1422 m_pRowSpans = pRowSpans;
1425 TableBoxVectorPtr WW8TableCellGridRow::getTableBoxVector() const
1427 return m_pTableBoxVector;
1430 WidthsPtr WW8TableCellGridRow::getWidths() const
1432 return m_pWidths;
1435 RowSpansPtr WW8TableCellGridRow::getRowSpans() const
1437 return m_pRowSpans;
1440 CellInfo::CellInfo(const SwRect & aRect, WW8TableNodeInfo * pNodeInfo)
1441 : m_aRect(aRect), m_pNodeInfo(pNodeInfo), m_nFmtFrmWidth(0)
1443 if (pNodeInfo != NULL)
1445 const SwTableBox * pBox = pNodeInfo->getTableBox();
1446 const SwFrmFmt * pFrmFmt = pBox->GetFrmFmt();
1447 const SwFmtFrmSize & rSize = pFrmFmt->GetFrmSize();
1449 m_nFmtFrmWidth = rSize.GetWidth();
1455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */