diff options
Diffstat (limited to 'sw/source/filter/ww8/WW8TableInfo.cxx')
-rw-r--r-- | sw/source/filter/ww8/WW8TableInfo.cxx | 1517 |
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(); + } +} + +} |