/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #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(); OSL_ENSURE(pFmt,"Impossible"); if (!pFmt) return pResult; const SwFmtFrmSize &rSize = pFmt->GetFrmSize(); unsigned long nTblSz = static_cast(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 > MAXTABLECELLS ) nBoxes = MAXTABLECELLS; 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 > MAXTABLECELLS) nBoxes = MAXTABLECELLS; 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; } #ifdef DBG_UTIL ::std::string WW8TableNodeInfoInner::toString() const { static char buffer[256]; snprintf(buffer, sizeof(buffer), "", mnDepth, mnCell, mnRow, mbEndOfCell ? "yes" : "no", mbEndOfLine ? "yes" : "no", mnShadowsBefore, mnShadowsAfter, mbVertMerge ? "yes" : "no"); return string(buffer); } #endif WW8TableNodeInfo::WW8TableNodeInfo(WW8TableInfo * pParent, const SwNode * pNode) : mpParent(pParent), mnDepth(0), mpNode(pNode), mpNext(NULL), mpNextNode(NULL) { } WW8TableNodeInfo::~WW8TableNodeInfo() { } #ifdef DBG_UTIL ::std::string WW8TableNodeInfo::toString() const { static char buffer[1024]; snprintf(buffer, sizeof(buffer), "" ,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++; } sResult += dbg_out(*mpNode); sResult += ""; return sResult; } #endif 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 DBG_UTIL ::std::clog << "" << toString() << "" << ::std::endl; #endif } void WW8TableNodeInfo::setEndOfCell(bool bEndOfCell) { WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth); pInner->setEndOfCell(bEndOfCell); #ifdef DBG_UTIL ::std::clog << "" << toString() << "" << ::std::endl; #endif } void WW8TableNodeInfo::setFirstInTable(bool bFirstInTable) { WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth); pInner->setFirstInTable(bFirstInTable); #ifdef DBG_UTIL ::std::clog << "" << toString() << "" << ::std::endl; #endif } void WW8TableNodeInfo::setVertMerge(bool bVertMerge) { WW8TableNodeInfoInner::Pointer_t pInner = getInnerForDepth(mnDepth); pInner->setVertMerge(bVertMerge); #ifdef DBG_UTIL ::std::clog << "" << toString() << "" << ::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 DBG_UTIL ::std::clog << "" << toString() << "" << pNext->toString() << "" << ::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.empty()) return mInners.begin()->second->getDepth(); return mnDepth; } const SwNode * WW8TableNodeInfo::getNode() const { return mpNode; } const SwTableBox * WW8TableNodeInfo::getTableBox() const { return getInnerForDepth(mnDepth)->getTableBox(); } WW8TableNodeInfo * WW8TableNodeInfo::getNext() const { return mpNext; } const SwNode * WW8TableNodeInfo::getNextNode() const { return mpNextNode; } 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.empty()) 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 DBG_UTIL static char sBuffer[1024]; ::std::clog << "" << ::std::endl; snprintf(sBuffer, sizeof(sBuffer), "", 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 DBG_UTIL ::std::clog << "" << ::std::endl; #endif } pPrev = reorderByLayout(pTable); return pPrev; } void WW8TableInfo::processSwTable(const SwTable * pTable) { #ifdef DBG_UTIL ::std::clog << "" << ::std::endl; #endif WW8TableNodeInfo * pPrev = NULL; if (pTable->IsTblComplex() && pTable->HasLayout()) { pPrev = processSwTableByLayout(pTable); #ifdef DBG_UTIL WW8TableCellGrid::Pointer_t pCellGrid(getCellGridForTable(pTable)); ::std::clog << pCellGrid->toString() << ::std::endl; #endif } else { const SwTableLines & rLines = pTable->GetTabLines(); for (sal_uInt16 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 DBG_UTIL ::std::clog << "" << ::std::endl; #endif } WW8TableNodeInfo * WW8TableInfo::processTableLine(const SwTable * pTable, const SwTableLine * pTableLine, sal_uInt32 nRow, sal_uInt32 nDepth, WW8TableNodeInfo * pPrev) { #ifdef DBG_UTIL ::std::clog << "" << ::std::endl; #endif const SwTableBoxes & rBoxes = pTableLine->GetTabBoxes(); WW8TableNodeInfo::Pointer_t pTextNodeInfo; for (sal_uInt16 n = 0; n < rBoxes.Count(); n++) { const SwTableBox * pBox = rBoxes[n]; pPrev = processTableBox(pTable, pBox, nRow, n, nDepth, n == rBoxes.Count() - 1, pPrev); } #ifdef DBG_UTIL ::std::clog << "" << ::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 DBG_UTIL ::std::clog << "" << ::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 (sal_uInt16 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 DBG_UTIL ::std::clog << "" << ::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 DBG_UTIL ::std::clog << "" << ::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 DBG_UTIL ::std::clog << "" << ::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 DBG_UTIL ::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; } #ifdef DBG_UTIL ::std::string CellInfo::toString() const { static char sBuffer[256]; snprintf(sBuffer, sizeof(sBuffer), "", left(), right(), top(), bottom(), m_pNodeInfo); return sBuffer; } #endif WW8TableNodeInfo * WW8TableInfo::reorderByLayout(const SwTable * pTable) { WW8TableNodeInfo * pPrev = NULL; WW8TableCellGrid::Pointer_t pCellGrid = getCellGridForTable(pTable); #ifdef DBG_UTIL ::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 DBG_UTIL ::std::clog << "" << ::std::endl; #endif RowTops_t::const_iterator aTopsIt = getRowTopsBegin(); while (aTopsIt != getRowTopsEnd()) { #ifdef DBG_UTIL 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 DBG_UTIL ::std::clog << "" << ::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; } #ifdef DBG_UTIL ::std::string WW8TableCellGrid::toString() { string sResult = ""; RowTops_t::const_iterator aTopsIt = getRowTopsBegin(); static char sBuffer[1024]; while (aTopsIt != getRowTopsEnd()) { sprintf(sBuffer, "", *aTopsIt); sResult += sBuffer; CellInfoMultiSet::const_iterator aCellIt = getCellsBegin(*aTopsIt); CellInfoMultiSet::const_iterator aCellsEnd = getCellsEnd(*aTopsIt); while (aCellIt != aCellsEnd) { snprintf(sBuffer, sizeof(sBuffer), "", aCellIt->top(), aCellIt->bottom(), aCellIt->left(), aCellIt->right()); sResult += sBuffer; WW8TableNodeInfo * pInfo = aCellIt->getTableNodeInfo(); if (pInfo != NULL) sResult += pInfo->toString(); else sResult += "\n"; sResult += "\n"; ++aCellIt; } WW8TableCellGridRow::Pointer_t pRow = getRow(*aTopsIt); WidthsPtr pWidths = pRow->getWidths(); if (pWidths != NULL) { sResult += ""; 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 += ""; } RowSpansPtr pRowSpans = pRow->getRowSpans(); if (pRowSpans.get() != NULL) { sResult += ""; 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 += ""; } sResult += "\n"; ++aTopsIt; } sResult += "\n"; return sResult; } #endif 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 DBG_UTIL ::std::clog << "" << rCellInfo.toString() << "" << ::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(); } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */