summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/WW8TableInfo.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/WW8TableInfo.cxx')
-rw-r--r--sw/source/filter/ww8/WW8TableInfo.cxx1517
1 files changed, 1517 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/WW8TableInfo.cxx b/sw/source/filter/ww8/WW8TableInfo.cxx
new file mode 100644
index 000000000000..8ca7c8d71571
--- /dev/null
+++ b/sw/source/filter/ww8/WW8TableInfo.cxx
@@ -0,0 +1,1517 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <iostream>
+#include <set>
+#include <stdio.h>
+#include "WW8TableInfo.hxx"
+#include "fmtfsize.hxx"
+#include "attributeoutputbase.hxx"
+#include "swtable.hxx"
+#include "frmfmt.hxx"
+#include "pam.hxx"
+#include "ndtxt.hxx"
+#include "dbgoutsw.hxx"
+
+namespace ww8
+{
+
+// WW8TableNodeInfoInner
+
+WW8TableNodeInfoInner::WW8TableNodeInfoInner(WW8TableNodeInfo * pParent)
+: mpParent(pParent)
+, mnCell(0)
+, mnRow(0)
+, mnShadowsBefore(0)
+, mnShadowsAfter(0)
+, mbEndOfLine(false)
+, mbEndOfCell(false)
+, mbFirstInTable(false)
+, mbVertMerge(false)
+, mpTableBox(NULL)
+, mpTable(NULL)
+{
+}
+
+WW8TableNodeInfoInner::~WW8TableNodeInfoInner()
+{
+}
+
+void WW8TableNodeInfoInner::setDepth(sal_uInt32 nDepth)
+{
+ mnDepth = nDepth;
+}
+
+void WW8TableNodeInfoInner::setCell(sal_uInt32 nCell)
+{
+ mnCell = nCell;
+}
+
+void WW8TableNodeInfoInner::setRow(sal_uInt32 nRow)
+{
+ mnRow = nRow;
+}
+
+void WW8TableNodeInfoInner::setShadowsBefore(sal_uInt32 nShadowsBefore)
+{
+ mnShadowsBefore = nShadowsBefore;
+}
+
+void WW8TableNodeInfoInner::setShadowsAfter(sal_uInt32 nShadowsAfter)
+{
+ mnShadowsAfter = nShadowsAfter;
+}
+
+void WW8TableNodeInfoInner::setEndOfLine(bool bEndOfLine)
+{
+ mbEndOfLine = bEndOfLine;
+}
+
+void WW8TableNodeInfoInner::setEndOfCell(bool bEndOfCell)
+{
+ mbEndOfCell = bEndOfCell;
+}
+
+void WW8TableNodeInfoInner::setFirstInTable(bool bFirstInTable)
+{
+ mbFirstInTable = bFirstInTable;
+}
+
+void WW8TableNodeInfoInner::setVertMerge(bool bVertMerge)
+
+{
+ mbVertMerge = bVertMerge;
+}
+
+void WW8TableNodeInfoInner::setTableBox(const SwTableBox * pTableBox)
+{
+ mpTableBox = pTableBox;
+}
+
+void WW8TableNodeInfoInner::setTable(const SwTable * pTable)
+{
+ mpTable = pTable;
+}
+
+void WW8TableNodeInfoInner::setRect(const SwRect & rRect)
+{
+ maRect = rRect;
+}
+
+sal_uInt32 WW8TableNodeInfoInner::getDepth() const
+{
+ return mnDepth;
+}
+
+sal_uInt32 WW8TableNodeInfoInner::getCell() const
+{
+ return mnCell;
+}
+
+sal_uInt32 WW8TableNodeInfoInner::getRow() const
+{
+ return mnRow;
+}
+
+sal_uInt32 WW8TableNodeInfoInner::getShadowsBefore() const
+{
+ return mnShadowsBefore;
+}
+
+sal_uInt32 WW8TableNodeInfoInner::getShadowsAfter() const
+{
+ return mnShadowsAfter;
+}
+
+bool WW8TableNodeInfoInner::isEndOfCell() const
+{
+ return mbEndOfCell;
+}
+
+bool WW8TableNodeInfoInner::isEndOfLine() const
+{
+ return mbEndOfLine;
+}
+
+bool WW8TableNodeInfoInner::isFirstInTable() const
+{
+ return mbFirstInTable;
+}
+
+const SwNode * WW8TableNodeInfoInner::getNode() const
+{
+ const SwNode * pResult = NULL;
+
+ if (mpParent != NULL)
+ pResult = mpParent->getNode();
+
+ return pResult;
+}
+
+TableBoxVectorPtr WW8TableNodeInfoInner::getTableBoxesOfRow()
+{
+ TableBoxVectorPtr pResult(new TableBoxVector);
+
+ WW8TableCellGrid::Pointer_t pCellGrid =
+ mpParent->getParent()->getCellGridForTable(getTable(), false);
+
+ if (pCellGrid.get() == NULL)
+ {
+ const SwTableLine * pTabLine = getTableBox()->GetUpper();
+ const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();
+
+ sal_uInt8 nBoxes = rTblBoxes.Count();
+ for ( sal_uInt8 n = 0; n < nBoxes; n++ )
+ {
+ pResult->push_back(rTblBoxes[n]);
+ }
+ }
+ else
+ pResult = pCellGrid->getTableBoxesOfRow(this);
+
+ return pResult;
+}
+
+GridColsPtr WW8TableNodeInfoInner::getGridColsOfRow(AttributeOutputBase & rBase)
+{
+ GridColsPtr pResult(new GridCols);
+ WidthsPtr pWidths(getWidthsOfRow());
+
+ const SwFrmFmt *pFmt = getTable()->GetFrmFmt();
+ ASSERT(pFmt,"Impossible");
+ if (!pFmt)
+ return pResult;
+
+ const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
+ unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
+
+ sal_uInt32 nPageSize = 0;
+ bool bRelBoxSize = false;
+
+ rBase.GetTablePageSize
+ ( this, nPageSize, bRelBoxSize );
+
+ SwTwips nSz = 0;
+ Widths::const_iterator aWidthsEnd = pWidths->end();
+ for ( Widths::const_iterator aIt = pWidths->begin();
+ aIt != aWidthsEnd;
+ aIt++)
+ {
+ nSz += *aIt;
+ SwTwips nCalc = nSz;
+ if ( bRelBoxSize )
+ nCalc = ( nCalc * nPageSize ) / nTblSz;
+
+ pResult->push_back( nCalc );
+ }
+
+ return pResult;
+}
+
+WidthsPtr WW8TableNodeInfoInner::getWidthsOfRow()
+{
+ WidthsPtr pWidths;
+
+ WW8TableCellGrid::Pointer_t pCellGrid =
+ mpParent->getParent()->getCellGridForTable(getTable(), false);
+
+ if (pCellGrid.get() == NULL)
+ {
+ const SwTableBox * pTabBox = getTableBox();
+ const SwTableLine * pTabLine = pTabBox->GetUpper();
+ const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
+
+ pWidths = WidthsPtr(new Widths);
+ // number of cell written
+ sal_uInt32 nBoxes = rTabBoxes.Count();
+ if ( nBoxes > 32 )
+ nBoxes = 32;
+
+ for (sal_uInt32 n = 0; n < nBoxes; n++)
+ {
+ const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt();
+ const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize();
+
+ pWidths->push_back(rLSz.GetWidth());
+ }
+ }
+ else
+ pWidths = pCellGrid->getWidthsOfRow(this);
+
+ return pWidths;
+}
+
+RowSpansPtr WW8TableNodeInfoInner::getRowSpansOfRow()
+{
+ RowSpansPtr pResult(new RowSpans);
+
+ WW8TableCellGrid::Pointer_t pCellGrid =
+ mpParent->getParent()->getCellGridForTable(getTable(), false);
+
+ if (pCellGrid.get() == NULL)
+ {
+ const SwTableBox * pTabBox = getTableBox();
+ const SwTableLine * pTabLine = pTabBox->GetUpper();
+ const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
+
+ sal_uInt32 nBoxes = rTabBoxes.Count();
+ if (nBoxes > 32)
+ nBoxes = 32;
+
+ for (sal_uInt32 n = 0; n < nBoxes; ++n)
+ {
+ pResult->push_back(rTabBoxes[n]->getRowSpan());
+ }
+ }
+ else
+ pResult = pCellGrid->getRowSpansOfRow(this);
+
+ return pResult;
+ }
+
+const SwTableBox * WW8TableNodeInfoInner::getTableBox() const
+{
+ return mpTableBox;
+}
+
+const SwTable * WW8TableNodeInfoInner::getTable() const
+{
+ return mpTable;
+}
+
+const SwRect & WW8TableNodeInfoInner::getRect() const
+{
+ return maRect;
+}
+
+string WW8TableNodeInfoInner::toString() const
+{
+ static char buffer[256];
+ snprintf(buffer, sizeof(buffer),
+ "<tableinner depth=\"%" SAL_PRIuUINT32 "\""
+ " cell=\"%" SAL_PRIuUINT32 "\""
+ " row=\"%" SAL_PRIuUINT32 "\""
+ " endOfCell=\"%s\""
+ " endOfLine=\"%s\""
+ " shadowsBefore=\"%" SAL_PRIuUINT32 "\""
+ " shadowsAfter=\"%" SAL_PRIuUINT32 "\""
+ " vertMerge=\"%s\"/>",
+ mnDepth, mnCell, mnRow,
+ mbEndOfCell ? "yes" : "no",
+ mbEndOfLine ? "yes" : "no",
+ mnShadowsBefore,
+ mnShadowsAfter,
+ mbVertMerge ? "yes" : "no");
+
+ return string(buffer);
+}
+// WW8TableTextNodeInfo
+
+WW8TableNodeInfo::WW8TableNodeInfo(WW8TableInfo * pParent,
+ const SwNode * pNode)
+: mpParent(pParent),
+ mnDepth(0),
+ mpNode(pNode),
+ mpNext(NULL),
+ mpNextNode(NULL)
+{
+}
+
+WW8TableNodeInfo::~WW8TableNodeInfo()
+{
+}
+
+::std::string WW8TableNodeInfo::toString() const
+{
+ static char buffer[1024];
+ snprintf(buffer, sizeof(buffer),
+ "<tableNodeInfo p=\"%p\" depth=\"%" SAL_PRIuUINT32 "\">"
+ ,this, getDepth());
+
+ ::std::string sResult(buffer);
+
+ Inners_t::const_iterator aIt(mInners.begin());
+ Inners_t::const_iterator aEnd(mInners.end());
+
+ while (aIt != aEnd)
+ {
+ WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
+ sResult += pInner->toString();
+
+ aIt++;
+ }
+#ifdef DEBUG
+ sResult += dbg_out(*mpNode);
+#endif
+ sResult += "</tableNodeInfo>";
+
+ return sResult;
+}
+void WW8TableNodeInfo::setDepth(sal_uInt32 nDepth)
+{
+ mnDepth = nDepth;
+
+ Inners_t::iterator aIt = mInners.find(mnDepth);
+
+ if (aIt == mInners.end())
+ mInners[mnDepth] = WW8TableNodeInfoInner::Pointer_t(new WW8TableNodeInfoInner(this));
+
+ mInners[mnDepth]->setDepth(mnDepth);
+}
+
+void WW8TableNodeInfo::setEndOfLine(bool bEndOfLine)
+{
+ WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
+ pInner->setEndOfLine(bEndOfLine);
+
+#ifdef DEBUG
+ ::std::clog << "<endOfLine depth=\"" << mnDepth << "\">"
+ << toString() << "</endOfLine>" << ::std::endl;
+#endif
+}
+
+void WW8TableNodeInfo::setEndOfCell(bool bEndOfCell)
+{
+ WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
+ pInner->setEndOfCell(bEndOfCell);
+
+#ifdef DEBUG
+ ::std::clog << "<endOfCell depth=\"" << mnDepth << "\">"
+ << toString() << "</endOfCell>" << ::std::endl;
+#endif
+}
+
+void WW8TableNodeInfo::setFirstInTable(bool bFirstInTable)
+{
+ WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
+
+ pInner->setFirstInTable(bFirstInTable);
+
+#ifdef DEBUG
+ ::std::clog << "<firstInTable depth=\"" << mnDepth << "\">"
+ << toString() << "</firstInTable>" << ::std::endl;
+#endif
+}
+
+void WW8TableNodeInfo::setVertMerge(bool bVertMerge)
+{
+ WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth);
+
+ pInner->setVertMerge(bVertMerge);
+
+
+#ifdef DEBUG
+ ::std::clog << "<vertMerge depth=\"" << mnDepth << "\">"
+ << toString() << "</vertMerge>" << ::std::endl;
+#endif
+}
+
+void WW8TableNodeInfo::setTableBox(const SwTableBox * pTableBox)
+{
+ getInnerForDepth(mnDepth)->setTableBox(pTableBox);
+}
+
+void WW8TableNodeInfo::setTable(const SwTable * pTable)
+{
+ getInnerForDepth(mnDepth)->setTable(pTable);
+}
+
+void WW8TableNodeInfo::setNext(WW8TableNodeInfo * pNext)
+{
+ mpNext = pNext;
+
+#ifdef DEBUG
+ ::std::clog << "<setnext><from>" << toString() << "</from><to>"
+ << pNext->toString() << "</to></setnext>"
+ << ::std::endl;
+#endif
+}
+
+void WW8TableNodeInfo::setNextNode(const SwNode * pNode)
+{
+ mpNextNode = pNode;
+}
+
+void WW8TableNodeInfo::setRect(const SwRect & rRect)
+{
+ getInnerForDepth(mnDepth)->setRect(rRect);
+}
+
+void WW8TableNodeInfo::setCell(sal_uInt32 nCell)
+{
+ getInnerForDepth(mnDepth)->setCell(nCell);
+}
+
+void WW8TableNodeInfo::setRow(sal_uInt32 nRow)
+{
+ getInnerForDepth(mnDepth)->setRow(nRow);
+}
+
+void WW8TableNodeInfo::setShadowsBefore(sal_uInt32 nShadowsBefore)
+{
+ getInnerForDepth(mnDepth)->setShadowsBefore(nShadowsBefore);
+}
+
+void WW8TableNodeInfo::setShadowsAfter(sal_uInt32 nShadowsAfter)
+{
+ getInnerForDepth(mnDepth)->setShadowsAfter(nShadowsAfter);
+}
+
+WW8TableInfo * WW8TableNodeInfo::getParent() const
+{
+ return mpParent;
+}
+
+sal_uInt32 WW8TableNodeInfo::getDepth() const
+{
+ if (mInners.size() > 0)
+ return mInners.begin()->second->getDepth();
+
+ return mnDepth;
+}
+
+const SwNode * WW8TableNodeInfo::getNode() const
+{
+ return mpNode;
+}
+
+const SwTableBox * WW8TableNodeInfo::getTableBox() const
+{
+ return getInnerForDepth(mnDepth)->getTableBox();
+}
+
+const SwTable * WW8TableNodeInfo::getTable() const
+{
+ return getInnerForDepth(mnDepth)->getTable();
+}
+
+WW8TableNodeInfo * WW8TableNodeInfo::getNext() const
+{
+ return mpNext;
+}
+
+const SwNode * WW8TableNodeInfo::getNextNode() const
+{
+ return mpNextNode;
+}
+
+const SwRect & WW8TableNodeInfo::getRect() const
+{
+ return getInnerForDepth(mnDepth)->getRect();
+}
+
+bool WW8TableNodeInfo::isEndOfLine() const
+{
+ return getInnerForDepth(mnDepth)->isEndOfLine();
+}
+
+bool WW8TableNodeInfo::isEndOfCell() const
+{
+ return getInnerForDepth(mnDepth)->isEndOfCell();
+}
+
+sal_uInt32 WW8TableNodeInfo::getCell() const
+{
+ return getInnerForDepth(mnDepth)->getCell();
+}
+
+sal_uInt32 WW8TableNodeInfo::getRow() const
+{
+ return getInnerForDepth(mnDepth)->getRow();
+}
+
+const ww8::WW8TableNodeInfo::Inners_t & WW8TableNodeInfo::getInners() const
+{
+ return mInners;
+}
+
+const WW8TableNodeInfoInner::Pointer_t WW8TableNodeInfo::getFirstInner() const
+{
+ WW8TableNodeInfoInner::Pointer_t pResult;
+
+ if (mInners.size() > 0)
+ pResult = mInners.begin()->second;
+
+ return pResult;
+}
+
+const WW8TableNodeInfoInner::Pointer_t WW8TableNodeInfo::getInnerForDepth(sal_uInt32 nDepth) const
+{
+ WW8TableNodeInfoInner::Pointer_t pResult;
+
+ Inners_t::const_iterator aIt = mInners.find(nDepth);
+ if (aIt != mInners.end())
+ {
+ pResult = aIt->second;
+ }
+
+ return pResult;
+}
+
+// WW8TableInfo
+
+WW8TableInfo::WW8TableInfo()
+{
+}
+
+WW8TableInfo::~WW8TableInfo()
+{
+}
+
+WW8TableNodeInfo *
+WW8TableInfo::processSwTableByLayout(const SwTable * pTable)
+{
+ SwTableCellInfo aTableCellInfo(pTable);
+ WW8TableNodeInfo * pPrev = NULL;
+
+ while (aTableCellInfo.getNext())
+ {
+ SwRect aRect = aTableCellInfo.getRect();
+
+#ifdef DEBUG
+ static char sBuffer[1024];
+ ::std::clog << "<CellFrm>" << ::std::endl;
+
+ snprintf(sBuffer, sizeof(sBuffer),
+ "<rect top=\"%ld\" bottom=\"%ld\" left=\"%ld\" right=\"%ld\"/>",
+ aRect.Top(), aRect.Bottom(), aRect.Left(), aRect.Right());
+ ::std::clog << sBuffer << ::std::endl;
+#endif
+ const SwTableBox * pTableBox = aTableCellInfo.getTableBox();
+ const SwStartNode * pSttNd = pTableBox->GetSttNd();
+
+ if (pSttNd != NULL)
+ {
+ SwPaM aPam(*pSttNd, 0);
+
+ bool bDone = false;
+ do
+ {
+ SwNode & rNode = aPam.GetPoint()->nNode.GetNode();
+
+ insertTableNodeInfo(&rNode, pTable, pTableBox, 0, 0, 1, & aRect);
+
+ if (rNode.IsEndNode())
+ {
+ SwEndNode * pEndNode = rNode.GetEndNode();
+ SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
+
+ if (pTmpSttNd == pSttNd)
+ bDone = true;
+ }
+
+ aPam.GetPoint()->nNode++;
+ }
+ while (!bDone);
+ }
+
+#ifdef DEBUG
+ ::std::clog << "</CellFrm>" << ::std::endl;
+#endif
+ }
+
+ pPrev = reorderByLayout(pTable);
+
+ return pPrev;
+}
+
+void WW8TableInfo::processSwTable(const SwTable * pTable)
+{
+#ifdef DEBUG
+ ::std::clog << "<processSwTable>" << ::std::endl;
+#endif
+
+ WW8TableNodeInfo * pPrev = NULL;
+
+ SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
+ if (pFrmFmt != NULL && pTable->IsTblComplex())
+ {
+ pPrev = processSwTableByLayout(pTable);
+
+#ifdef DEBUG
+ WW8TableCellGrid::Pointer_t pCellGrid(getCellGridForTable(pTable));
+ ::std::clog << pCellGrid->toString() << ::std::endl;
+#endif
+ }
+ else
+ {
+ const SwTableLines & rLines = pTable->GetTabLines();
+
+ for (USHORT n = 0; n < rLines.Count(); n++)
+ {
+ const SwTableLine * pLine = rLines[n];
+
+ pPrev = processTableLine(pTable, pLine, n, 1, pPrev);
+ }
+
+ }
+
+ if (pPrev != NULL)
+ {
+ SwTableNode * pTableNode = pTable->GetTableNode();
+ SwEndNode * pEndNode = pTableNode->EndOfSectionNode();
+
+ pPrev->setNextNode(pEndNode);
+ }
+#ifdef DEBUG
+ ::std::clog << "</processSwTable>" << ::std::endl;
+#endif
+}
+
+WW8TableNodeInfo *
+WW8TableInfo::processTableLine(const SwTable * pTable,
+ const SwTableLine * pTableLine,
+ sal_uInt32 nRow,
+ sal_uInt32 nDepth, WW8TableNodeInfo * pPrev)
+{
+#ifdef DEBUG
+ ::std::clog << "<processTableLine row=\"" << nRow << "\" depth=\""
+ << nDepth << "\">" << ::std::endl;
+#endif
+
+ const SwTableBoxes & rBoxes = pTableLine->GetTabBoxes();
+
+ WW8TableNodeInfo::Pointer_t pTextNodeInfo;
+
+ for (USHORT n = 0; n < rBoxes.Count(); n++)
+ {
+ const SwTableBox * pBox = rBoxes[n];
+
+ pPrev = processTableBox(pTable, pBox, nRow, n, nDepth, n == rBoxes.Count() - 1, pPrev);
+ }
+
+#ifdef DEBUG
+ ::std::clog << "</processTableLine>" << ::std::endl;
+#endif
+
+ return pPrev;
+}
+
+WW8TableNodeInfo::Pointer_t
+WW8TableInfo::processTableBoxLines(const SwTableBox * pBox,
+ const SwTable * pTable,
+ const SwTableBox * pBoxToSet,
+ sal_uInt32 nRow,
+ sal_uInt32 nCell,
+ sal_uInt32 nDepth)
+{
+#ifdef DEBUG
+ ::std::clog << "<processTableBoxLines depth=\"" << nDepth
+ << "\" row=\"" << nRow << "\" cell=\"" << nCell << "\">" << ::std::endl;
+#endif
+
+ const SwTableLines & rLines = pBox->GetTabLines();
+ WW8TableNodeInfo::Pointer_t pNodeInfo;
+
+ if (rLines.Count() > 0)
+ {
+ for (sal_uInt32 n = 0; n < rLines.Count(); n++)
+ {
+ const SwTableLine * pLine = rLines[n];
+ const SwTableBoxes & rBoxes = pLine->GetTabBoxes();
+
+ for (USHORT nBox = 0; nBox < rBoxes.Count(); nBox++)
+ pNodeInfo = processTableBoxLines(rBoxes[nBox], pTable, pBoxToSet, nRow, nCell, nDepth);
+ }
+ }
+ else
+ {
+ const SwStartNode * pSttNd = pBox->GetSttNd();
+ const SwEndNode * pEndNd = pSttNd->EndOfSectionNode();
+ SwPaM aPaM(*pSttNd, 0);
+ SwPaM aEndPaM(*pEndNd, 0);
+
+ bool bDone = false;
+ while (!bDone)
+ {
+ SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
+
+ pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBoxToSet, nRow, nCell, nDepth);
+
+ if (aPaM.GetPoint()->nNode == aEndPaM.GetPoint()->nNode)
+ bDone = true;
+ else
+ aPaM.GetPoint()->nNode++;
+ }
+ }
+
+#ifdef DEBUG
+ ::std::clog << "</processTableBoxLines>" << ::std::endl;
+#endif
+
+ return pNodeInfo;
+}
+
+WW8TableNodeInfo *
+WW8TableInfo::processTableBox(const SwTable * pTable,
+ const SwTableBox * pBox,
+ sal_uInt32 nRow,
+ sal_uInt32 nCell,
+ sal_uInt32 nDepth,
+ bool bEndOfLine,
+ WW8TableNodeInfo * pPrev)
+{
+#ifdef DEBUG
+ ::std::clog << "<processTableBox row=\"" << nRow << "\" cell=\"" << nCell
+ << "\" depth=\"" << nDepth << "\">" << ::std::endl;
+#endif
+
+ WW8TableNodeInfo::Pointer_t pNodeInfo;
+ const SwTableLines & rLines = pBox->GetTabLines();
+ const SwStartNode * pSttNd = pBox->GetSttNd();
+ WW8TableNodeInfo::Pointer_t pEndOfCellInfo;
+
+ if (rLines.Count() > 0)
+ {
+ pNodeInfo = processTableBoxLines(pBox, pTable, pBox, nRow, nCell, nDepth);
+ pNodeInfo->setEndOfCell(true);
+ if (bEndOfLine)
+ pNodeInfo->setEndOfLine(true);
+
+ for (sal_uInt32 n = 0; n < rLines.Count(); n++)
+ {
+ const SwTableLine * pLine = rLines[n];
+
+ pPrev = processTableLine(pTable, pLine, n, 1, pPrev);
+ }
+ }
+ else
+ {
+ SwPaM aPaM(*pSttNd, 0);
+
+ bool bDone = false;
+ sal_uInt32 nDepthInsideCell = 0;
+
+ do
+ {
+ SwNode & rNode = aPaM.GetPoint()->nNode.GetNode();
+
+ if (rNode.IsStartNode())
+ {
+ if (nDepthInsideCell > 0)
+ pEndOfCellInfo.reset();
+
+ nDepthInsideCell++;
+ }
+
+ pNodeInfo = insertTableNodeInfo(&rNode, pTable, pBox, nRow, nCell, nDepth);
+
+ if (pPrev != NULL)
+ pPrev->setNext(pNodeInfo.get());
+
+ pPrev = pNodeInfo.get();
+
+ if (nDepthInsideCell == 1 && rNode.IsTxtNode())
+ pEndOfCellInfo = pNodeInfo;
+
+ if (rNode.IsEndNode())
+ {
+ nDepthInsideCell--;
+
+ if (nDepthInsideCell == 0 && pEndOfCellInfo.get() == NULL)
+ pEndOfCellInfo = pNodeInfo;
+
+ SwEndNode * pEndNode = rNode.GetEndNode( );
+ SwStartNode * pTmpSttNd = pEndNode->StartOfSectionNode();
+ if (pTmpSttNd == pSttNd)
+ bDone = true;
+ }
+
+ aPaM.GetPoint()->nNode++;
+ }
+ while (!bDone);
+
+ if (pEndOfCellInfo.get() != NULL)
+ {
+ pEndOfCellInfo->setEndOfCell(true);
+
+ if (bEndOfLine)
+ pEndOfCellInfo->setEndOfLine(true);
+ }
+ }
+
+#ifdef DEBUG
+ ::std::clog << "</processTableBox>" << ::std::endl;
+#endif
+
+ return pPrev;
+}
+
+WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo
+(const SwNode * pNode,
+ const SwTable * pTable,
+ const SwTableBox * pTableBox,
+ sal_uInt32 nRow,
+ sal_uInt32 nCell,
+ sal_uInt32 nDepth,
+ SwRect * pRect)
+{
+ WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode);
+
+ if (pNodeInfo.get() == NULL)
+ {
+ pNodeInfo =
+ WW8TableNodeInfo::Pointer_t(new WW8TableNodeInfo(this, pNode));
+ mMap.insert(Map_t::value_type(pNode, pNodeInfo));
+ }
+
+ pNodeInfo->setDepth(nDepth + pNodeInfo->getDepth());
+
+ pNodeInfo->setTable(pTable);
+ pNodeInfo->setTableBox(pTableBox);
+
+ pNodeInfo->setCell(nCell);
+ pNodeInfo->setRow(nRow);
+
+ if (pNode->IsTxtNode())
+ {
+ FirstInTableMap_t::const_iterator aIt = mFirstInTableMap.find(pTable);
+ if (aIt == mFirstInTableMap.end())
+ {
+ mFirstInTableMap[pTable] = pNode;
+ pNodeInfo->setFirstInTable(true);
+ }
+ }
+
+ if (pRect)
+ {
+ WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable);
+
+ pCellGrid->insert(*pRect, pNodeInfo.get());
+ pNodeInfo->setRect(*pRect);
+ }
+
+#ifdef DEBUG
+ ::std::clog << pNodeInfo->toString() << ::std::endl;
+#endif
+
+ return pNodeInfo;
+}
+
+WW8TableCellGrid::Pointer_t WW8TableInfo::getCellGridForTable
+(const SwTable * pTable, bool bCreate)
+{
+ WW8TableCellGrid::Pointer_t pResult;
+ CellGridMap_t::iterator aIt = mCellGridMap.find(pTable);
+
+ if (aIt == mCellGridMap.end())
+ {
+ if (bCreate)
+ {
+ pResult = WW8TableCellGrid::Pointer_t(new WW8TableCellGrid);
+ mCellGridMap[pTable] = pResult;
+ }
+ }
+ else
+ pResult = mCellGridMap[pTable];
+
+ return pResult;
+}
+
+WW8TableNodeInfo::Pointer_t WW8TableInfo::getTableNodeInfo
+(const SwNode * pNode)
+{
+ WW8TableNodeInfo::Pointer_t pResult;
+ Map_t::iterator aIt = mMap.find(pNode);
+
+ if (aIt != mMap.end())
+ pResult = (*aIt).second;
+
+ return pResult;
+}
+
+const SwNode * WW8TableInfo::getNextNode(const SwNode * pNode)
+{
+ const SwNode * pResult = NULL;
+
+ WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode);
+
+ if (pNodeInfo.get() != NULL)
+ {
+ WW8TableNodeInfo * pNextInfo = pNodeInfo->getNext();
+
+ if (pNextInfo != NULL)
+ pResult = pNextInfo->getNode();
+ else
+ {
+ const SwNode * pNextNode = pNodeInfo->getNextNode();
+
+ if (pNextNode != NULL)
+ pResult = pNextNode;
+ }
+ }
+
+ return pResult;
+}
+
+bool WW8TableNodeInfo::operator < (const WW8TableNodeInfo & rInfo) const
+{
+ bool bRet = false;
+
+ if (rInfo.mpNode != NULL)
+ {
+ if (mpNode == NULL)
+ {
+ bRet = true;
+ }
+ else
+ {
+ if (mpNode->GetIndex() < rInfo.mpNode->GetIndex())
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+bool CellInfo::operator < (const CellInfo & aCellInfo) const
+{
+ bool aRet = false;
+
+ if (top() < aCellInfo.top())
+ aRet = true;
+ else if (top() == aCellInfo.top())
+ {
+ if (left() < aCellInfo.left())
+ aRet = true;
+ else if (left() == aCellInfo.left())
+ {
+ if (width() < aCellInfo.width())
+ aRet = true;
+ else if (width() == aCellInfo.width())
+ {
+ if (height() < aCellInfo.height())
+ aRet = true;
+ else if (height() == aCellInfo.height())
+ {
+ if (aCellInfo.getTableNodeInfo() != NULL)
+ {
+ if (m_pNodeInfo == NULL)
+ aRet = true;
+ else
+ {
+ aRet = *m_pNodeInfo < *aCellInfo.getTableNodeInfo();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return aRet;
+}
+
+::std::string CellInfo::toString() const
+{
+ static char sBuffer[256];
+
+ snprintf(sBuffer, sizeof(sBuffer),
+ "<cellinfo left=\"%ld\""
+ " right=\"%ld\""
+ " top=\"%ld\""
+ " bottom=\"%ld\""
+ " node=\"%p\"/>",
+ left(),
+ right(),
+ top(),
+ bottom(),
+ m_pNodeInfo);
+
+ return sBuffer;
+}
+
+WW8TableNodeInfo * WW8TableInfo::reorderByLayout(const SwTable * pTable)
+{
+ WW8TableNodeInfo * pPrev = NULL;
+ WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable);
+
+#ifdef DEBUG
+ ::std::clog << pCellGrid->toString() << ::std::endl;
+#endif
+
+ pCellGrid->addShadowCells();
+ pPrev = pCellGrid->connectCells();
+
+ return pPrev;
+}
+
+WW8TableCellGrid::WW8TableCellGrid()
+{
+}
+
+WW8TableCellGrid::~WW8TableCellGrid()
+{
+}
+
+WW8TableCellGridRow::Pointer_t WW8TableCellGrid::getRow(long nTop, bool bCreate)
+{
+ WW8TableCellGridRow::Pointer_t pResult;
+
+ RowTops_t::iterator aIt = m_aRowTops.find(nTop);
+
+ if (aIt == m_aRowTops.end())
+ {
+ if (bCreate)
+ {
+ pResult = WW8TableCellGridRow::Pointer_t(new WW8TableCellGridRow);
+ m_aRows[nTop] = pResult;
+ m_aRowTops.insert(nTop);
+ }
+ }
+ else
+ pResult = m_aRows[nTop];
+
+ return pResult;
+}
+
+WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsBegin() const
+{
+ return m_aRowTops.begin();
+}
+
+WW8TableCellGrid::RowTops_t::const_iterator WW8TableCellGrid::getRowTopsEnd() const
+{
+ return m_aRowTops.end();
+}
+
+CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsBegin(long nTop)
+{
+ return getRow(nTop)->begin();
+}
+
+CellInfoMultiSet::const_iterator WW8TableCellGrid::getCellsEnd(long nTop)
+{
+ return getRow(nTop)->end();
+}
+
+void WW8TableCellGrid::insert(const SwRect & rRect,
+ WW8TableNodeInfo * pNodeInfo,
+ unsigned long * pFmtFrmWidth)
+{
+ CellInfo aCellInfo(rRect, pNodeInfo);
+
+ if (pFmtFrmWidth != NULL)
+ aCellInfo.setFmtFrmWidth(*pFmtFrmWidth);
+
+ WW8TableCellGridRow::Pointer_t pRow = getRow(rRect.Top());
+ pRow->insert(aCellInfo);
+}
+
+void WW8TableCellGrid::addShadowCells()
+{
+#ifdef DEBUG
+ ::std::clog << "<addShadowCells>" << ::std::endl;
+#endif
+
+ RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
+
+ while (aTopsIt != getRowTopsEnd())
+ {
+#ifdef DEBUG
+ long nTop = *aTopsIt;
+ (void) nTop;
+#endif
+ CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
+ CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
+
+ RowSpansPtr pRowSpans(new RowSpans);
+
+ bool bBeginningOfCell = true;
+ bool bVertMerge = false;
+ SwRect aRect = aCellIt->getRect();
+ long nRowSpan = 1;
+ while (aCellIt != aCellEndIt)
+ {
+ WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
+
+ if (bBeginningOfCell)
+ {
+ RowTops_t::const_iterator aRowSpanIt(aTopsIt);
+ aRowSpanIt++;
+
+ if (aRowSpanIt != getRowTopsEnd() &&
+ *aRowSpanIt < aCellIt->bottom())
+ {
+ aRect.Top(*aRowSpanIt);
+ unsigned long nFmtFrmWidth = aCellIt->getFmtFrmWidth();
+ insert(aRect, NULL, &nFmtFrmWidth);
+
+ bVertMerge = true;
+ }
+ else
+ bVertMerge = false;
+
+ nRowSpan = 1;
+ while (aRowSpanIt != getRowTopsEnd() &&
+ *aRowSpanIt < aCellIt->bottom())
+ {
+ aRowSpanIt++;
+ nRowSpan++;
+ }
+
+ if (pNodeInfo != NULL)
+ pRowSpans->push_back(nRowSpan);
+ else
+ pRowSpans->push_back(-nRowSpan);
+ }
+
+ if (pNodeInfo != NULL)
+ {
+ pNodeInfo->setVertMerge(bVertMerge);
+ }
+
+ aCellIt++;
+
+ bBeginningOfCell = (aRect.Left() != aCellIt->left());
+ aRect = aCellIt->getRect();
+ }
+
+ WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
+ if (pRow.get() != NULL)
+ pRow->setRowSpans(pRowSpans);
+
+ aTopsIt++;
+ }
+#ifdef DEBUG
+ ::std::clog << "</addShadowCells>" << ::std::endl;
+#endif
+}
+
+WW8TableNodeInfo * WW8TableCellGrid::connectCells()
+{
+ RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
+ sal_uInt32 nRow = 0;
+ WW8TableNodeInfo * pLastNodeInfo = NULL;
+
+ while (aTopsIt != getRowTopsEnd())
+ {
+ CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
+ CellInfoMultiSet::const_iterator aCellEndIt = getCellsEnd(*aTopsIt);
+ GridColsPtr pWidths(new Widths);
+ TableBoxVectorPtr pTableBoxes(new TableBoxVector);
+
+ sal_uInt32 nShadows = 0;
+ sal_uInt32 nCell = 0;
+ bool bBeginningOfCell = true;
+ WW8TableNodeInfo * pEndOfCellInfo = NULL;
+ sal_uInt32 nDepthInCell = 0;
+ while (aCellIt != aCellEndIt)
+ {
+ long nCellX = aCellIt->left();
+ WW8TableNodeInfo * pNodeInfo = aCellIt->getTableNodeInfo();
+ if (pNodeInfo != NULL)
+ {
+ const SwNode * pNode = pNodeInfo->getNode();
+
+ if (pNode->IsStartNode())
+ {
+ nDepthInCell++;
+ pEndOfCellInfo = NULL;
+ }
+
+ if (nDepthInCell == 1 && pNode->IsTxtNode())
+ pEndOfCellInfo = pNodeInfo;
+
+ pNodeInfo->setShadowsBefore(nShadows);
+ pNodeInfo->setCell(nCell);
+ pNodeInfo->setRow(nRow);
+ if (pLastNodeInfo != NULL)
+ {
+ pLastNodeInfo->setNext(pNodeInfo);
+ pLastNodeInfo->setNextNode(pNode);
+ }
+ pLastNodeInfo = pNodeInfo;
+ nShadows = 0;
+
+ if (pNode->IsEndNode())
+ {
+ nDepthInCell--;
+
+ if (nDepthInCell == 0 && pEndOfCellInfo == NULL)
+ pEndOfCellInfo = pNodeInfo;
+ }
+ }
+ else
+ {
+ nShadows++;
+ }
+
+ if (bBeginningOfCell)
+ {
+ pWidths->push_back(aCellIt->getFmtFrmWidth());
+
+ if (pNodeInfo != NULL)
+ pTableBoxes->push_back(pNodeInfo->getTableBox());
+ else
+ pTableBoxes->push_back(NULL);
+ }
+
+ aCellIt++;
+ bBeginningOfCell = false;
+
+ if (aCellIt != aCellEndIt && aCellIt->left() != nCellX)
+ {
+ nCell++;
+ bBeginningOfCell = true;
+
+ if (pEndOfCellInfo != NULL)
+ {
+ pEndOfCellInfo->setEndOfCell(true);
+ }
+
+ pEndOfCellInfo = NULL;
+ }
+ }
+
+ pLastNodeInfo->setShadowsAfter(nShadows);
+
+ if (pEndOfCellInfo == NULL)
+ {
+ pEndOfCellInfo = pLastNodeInfo;
+ }
+
+ pEndOfCellInfo->setEndOfCell(true);
+ pLastNodeInfo->setEndOfLine(true);
+
+ WW8TableCellGridRow::Pointer_t pRow(getRow(*aTopsIt));
+ pRow->setTableBoxVector(pTableBoxes);
+ pRow->setWidths(pWidths);
+
+ nShadows = 0;
+
+ aTopsIt++;
+ nRow++;
+ }
+
+ return pLastNodeInfo;
+}
+
+string WW8TableCellGrid::toString()
+{
+ string sResult = "<WW8TableCellGrid>";
+
+ RowTops_t::const_iterator aTopsIt = getRowTopsBegin();
+ static char sBuffer[1024];
+ while (aTopsIt != getRowTopsEnd())
+ {
+ sprintf(sBuffer, "<row y=\"%ld\">", *aTopsIt);
+ sResult += sBuffer;
+
+ CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt);
+ CellInfoMultiSet::const_iterator aCellsEnd = getCellsEnd(*aTopsIt);
+
+ while (aCellIt != aCellsEnd)
+ {
+ snprintf(sBuffer, sizeof(sBuffer), "<cellInfo top=\"%ld\" bottom=\"%ld\" left=\"%ld\" right=\"%ld\">",
+ aCellIt->top(), aCellIt->bottom(), aCellIt->left(), aCellIt->right());
+ sResult += sBuffer;
+
+ WW8TableNodeInfo * pInfo = aCellIt->getTableNodeInfo();
+ if (pInfo != NULL)
+ sResult += pInfo->toString();
+ else
+ sResult += "<shadow/>\n";
+
+ sResult += "</cellInfo>\n";
+ aCellIt++;
+ }
+
+ WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt);
+ WidthsPtr pWidths = pRow->getWidths();
+ if (pWidths != NULL)
+ {
+ sResult += "<widths>";
+
+ Widths::const_iterator aItEnd = pWidths->end();
+ for (Widths::const_iterator aIt = pWidths->begin();
+ aIt != aItEnd;
+ aIt++)
+ {
+ if (aIt != pWidths->begin())
+ sResult += ", ";
+
+ snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
+ sResult += sBuffer;
+ }
+
+ sResult += "</widths>";
+ }
+
+ RowSpansPtr pRowSpans = pRow->getRowSpans();
+ if (pRowSpans.get() != NULL)
+ {
+ sResult += "<rowspans>";
+
+ RowSpans::const_iterator aItEnd = pRowSpans->end();
+ for (RowSpans::const_iterator aIt = pRowSpans->begin();
+ aIt != aItEnd;
+ aIt++)
+ {
+ if (aIt != pRowSpans->begin())
+ sResult += ", ";
+
+ snprintf(sBuffer, sizeof(sBuffer), "%" SAL_PRIxUINT32 "", *aIt);
+ sResult += sBuffer;
+ }
+
+ sResult += "</rowspans>";
+ }
+
+ sResult += "</row>\n";
+ aTopsIt++;
+ }
+
+ sResult += "</WW8TableCellGrid>\n";
+
+ return sResult;
+}
+
+TableBoxVectorPtr WW8TableCellGrid::getTableBoxesOfRow
+(WW8TableNodeInfoInner * pNodeInfoInner)
+{
+ TableBoxVectorPtr pResult;
+ WW8TableCellGridRow::Pointer_t pRow =
+ getRow(pNodeInfoInner->getRect().Top(), false);
+
+ if (pRow.get() != NULL)
+ {
+ pResult = pRow->getTableBoxVector();
+ }
+
+ return pResult;
+}
+
+WidthsPtr WW8TableCellGrid::getWidthsOfRow
+(WW8TableNodeInfoInner * pNodeInfoInner)
+{
+ GridColsPtr pResult;
+
+ WW8TableCellGridRow::Pointer_t pRow =
+ getRow(pNodeInfoInner->getRect().Top(), false);
+
+ if (pRow.get() != NULL)
+ {
+ pResult = pRow->getWidths();
+ }
+
+ return pResult;
+}
+
+RowSpansPtr WW8TableCellGrid::getRowSpansOfRow
+(WW8TableNodeInfoInner * pNodeInfoInner)
+{
+ RowSpansPtr pResult;
+
+ WW8TableCellGridRow::Pointer_t pRow =
+ getRow(pNodeInfoInner->getRect().Top(), false);
+
+ if (pRow.get() != NULL)
+ {
+ pResult = pRow->getRowSpans();
+ }
+
+ return pResult;
+}
+
+WW8TableCellGridRow::WW8TableCellGridRow()
+: m_pCellInfos(new CellInfoMultiSet)
+{
+}
+
+WW8TableCellGridRow::~WW8TableCellGridRow()
+{
+}
+
+void WW8TableCellGridRow::insert(const CellInfo & rCellInfo)
+{
+ m_pCellInfos->insert(rCellInfo);
+
+#ifdef DEBUG
+ ::std::clog << "<gridRowInsert>"
+ << rCellInfo.toString()
+ << "</gridRowInsert>"
+ << ::std::endl;
+#endif
+}
+
+CellInfoMultiSet::const_iterator WW8TableCellGridRow::begin() const
+{
+ return m_pCellInfos->begin();
+}
+
+CellInfoMultiSet::const_iterator WW8TableCellGridRow::end() const
+{
+ return m_pCellInfos->end();
+}
+
+void WW8TableCellGridRow::setTableBoxVector(TableBoxVectorPtr pTableBoxVector)
+{
+ m_pTableBoxVector = pTableBoxVector;
+}
+
+void WW8TableCellGridRow::setWidths(WidthsPtr pWidths)
+{
+ m_pWidths = pWidths;
+}
+
+void WW8TableCellGridRow::setRowSpans(RowSpansPtr pRowSpans)
+{
+ m_pRowSpans = pRowSpans;
+}
+
+TableBoxVectorPtr WW8TableCellGridRow::getTableBoxVector() const
+{
+ return m_pTableBoxVector;
+}
+
+WidthsPtr WW8TableCellGridRow::getWidths() const
+{
+ return m_pWidths;
+}
+
+RowSpansPtr WW8TableCellGridRow::getRowSpans() const
+{
+ return m_pRowSpans;
+}
+
+CellInfo::CellInfo(const SwRect & aRect, WW8TableNodeInfo * pNodeInfo)
+: m_aRect(aRect), m_pNodeInfo(pNodeInfo), m_nFmtFrmWidth(0)
+{
+ if (pNodeInfo != NULL)
+ {
+ const SwTableBox * pBox = pNodeInfo->getTableBox();
+ const SwFrmFmt * pFrmFmt = pBox->GetFrmFmt();
+ const SwFmtFrmSize & rSize = pFrmFmt->GetFrmSize();
+
+ m_nFmtFrmWidth = rSize.GetWidth();
+ }
+}
+
+}