diff options
author | Caolán McNamara <cmc@openoffice.org> | 2010-05-31 22:58:51 +0100 |
---|---|---|
committer | Caolán McNamara <cmc@openoffice.org> | 2010-05-31 22:58:51 +0100 |
commit | 0a4d98f9019562d174c575331a6f41b0b6ae30c9 (patch) | |
tree | 2f7fbf327bac4bef94d1bb03cdbca51e9b6d9ecf /sw/source | |
parent | e472521ce24bb9f7e205a5f7255c022d44fcb2e2 (diff) | |
parent | 8f943e727b1158cc8c11d74ea521ac1c2f9cb974 (diff) |
cmcfixes74: merge with DEV300 m80
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/table/swtable.cxx | 157 | ||||
-rw-r--r-- | sw/source/filter/ww8/WW8TableInfo.cxx | 910 | ||||
-rw-r--r-- | sw/source/filter/ww8/WW8TableInfo.hxx | 175 | ||||
-rw-r--r-- | sw/source/filter/ww8/attributeoutputbase.hxx | 9 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.cxx | 268 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 5 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 11 | ||||
-rw-r--r-- | sw/source/ui/app/apphdl.cxx | 30 |
8 files changed, 1401 insertions, 164 deletions
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx index a755dd59e3..9144738a68 100644 --- a/sw/source/core/table/swtable.cxx +++ b/sw/source/core/table/swtable.cxx @@ -2726,3 +2726,160 @@ void SwTableBox_Impl::SetNewCol( Color** ppCol, const Color* pNewCol ) } } +struct SwTableCellInfo::Impl +{ + const SwTable * m_pTable; + const SwCellFrm * m_pCellFrm; + const SwTabFrm * m_pTabFrm; + typedef ::std::set<const SwTableBox *> TableBoxes_t; + TableBoxes_t m_HandledTableBoxes; + +public: + Impl() + : m_pTable(NULL), m_pCellFrm(NULL), m_pTabFrm(NULL) + { + } + + ~Impl() {} + + void setTable(const SwTable * pTable) { + m_pTable = pTable; + SwFrmFmt * pFrmFmt = m_pTable->GetFrmFmt(); + SwClientIter aIter(*pFrmFmt); + + m_pTabFrm = + static_cast<const SwTabFrm *>(aIter.First(TYPE(SwTabFrm))); + + if (m_pTabFrm->IsFollow()) + m_pTabFrm = m_pTabFrm->FindMaster(true); + } + const SwTable * getTable() const { return m_pTable; } + + const SwCellFrm * getCellFrm() const { return m_pCellFrm; } + + const SwFrm * getNextFrmInTable(const SwFrm * pFrm); + const SwCellFrm * getNextCellFrm(const SwFrm * pFrm); + const SwCellFrm * getNextTableBoxsCellFrm(const SwFrm * pFrm); + bool getNext(); +}; + +const SwFrm * SwTableCellInfo::Impl::getNextFrmInTable(const SwFrm * pFrm) +{ + const SwFrm * pResult = NULL; + + if (((! pFrm->IsTabFrm()) || pFrm == m_pTabFrm) && pFrm->GetLower()) + pResult = pFrm->GetLower(); + else if (pFrm->GetNext()) + pResult = pFrm->GetNext(); + else + { + while (pFrm->GetUpper() != NULL) + { + pFrm = pFrm->GetUpper(); + + if (pFrm->IsTabFrm()) + { + m_pTabFrm = static_cast<const SwTabFrm *>(pFrm)->GetFollow(); + pResult = m_pTabFrm; + break; + } + else if (pFrm->GetNext()) + { + pResult = pFrm->GetNext(); + break; + } + } + } + + return pResult; +} + +const SwCellFrm * SwTableCellInfo::Impl::getNextCellFrm(const SwFrm * pFrm) +{ + const SwCellFrm * pResult = NULL; + + while ((pFrm = getNextFrmInTable(pFrm)) != NULL) + { + if (pFrm->IsCellFrm()) + { + pResult = static_cast<const SwCellFrm *>(pFrm); + break; + } + } + + return pResult; +} + +const SwCellFrm * SwTableCellInfo::Impl::getNextTableBoxsCellFrm(const SwFrm * pFrm) +{ + const SwCellFrm * pResult = NULL; + + while ((pFrm = getNextCellFrm(pFrm)) != NULL) + { + const SwCellFrm * pCellFrm = static_cast<const SwCellFrm *>(pFrm); + const SwTableBox * pTabBox = pCellFrm->GetTabBox(); + TableBoxes_t::const_iterator aIt = m_HandledTableBoxes.find(pTabBox); + + if (aIt == m_HandledTableBoxes.end()) + { + pResult = pCellFrm; + m_HandledTableBoxes.insert(pTabBox); + break; + } + } + + return pResult; +} + +const SwCellFrm * SwTableCellInfo::getCellFrm() const +{ + return m_pImpl->getCellFrm(); +} + +bool SwTableCellInfo::Impl::getNext() +{ + if (m_pCellFrm == NULL) + { + if (m_pTabFrm != NULL) + m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pTabFrm); + } + else + m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pCellFrm); + + return m_pCellFrm != NULL; +} + +SwTableCellInfo::SwTableCellInfo(const SwTable * pTable) +{ + m_pImpl.reset(new Impl()); + m_pImpl->setTable(pTable); +} + +SwTableCellInfo::~SwTableCellInfo() +{ +} + +bool SwTableCellInfo::getNext() +{ + return m_pImpl->getNext(); +} + +SwRect SwTableCellInfo::getRect() const +{ + SwRect aRet; + + if (getCellFrm() != NULL) + aRet = getCellFrm()->Frm(); + + return aRet; +} + +const SwTableBox * SwTableCellInfo::getTableBox() const +{ + const SwTableBox * pRet = NULL; + + if (getCellFrm() != NULL) + pRet = getCellFrm()->GetTabBox(); + + return pRet; +} diff --git a/sw/source/filter/ww8/WW8TableInfo.cxx b/sw/source/filter/ww8/WW8TableInfo.cxx index f0d65a7544..6b5b385428 100644 --- a/sw/source/filter/ww8/WW8TableInfo.cxx +++ b/sw/source/filter/ww8/WW8TableInfo.cxx @@ -29,9 +29,13 @@ #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" @@ -45,8 +49,11 @@ WW8TableNodeInfoInner::WW8TableNodeInfoInner(WW8TableNodeInfo * pParent) : mpParent(pParent) , mnCell(0) , mnRow(0) +, mnShadowsBefore(0) +, mnShadowsAfter(0) , mbEndOfLine(false) , mbEndOfCell(false) +, mbVertMerge(false) , mpTableBox(NULL) , mpTable(NULL) { @@ -71,6 +78,16 @@ 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; @@ -81,6 +98,11 @@ void WW8TableNodeInfoInner::setEndOfCell(bool bEndOfCell) mbEndOfCell = bEndOfCell; } +void WW8TableNodeInfoInner::setVertMerge(bool bVertMerge) +{ + mbVertMerge = bVertMerge; +} + void WW8TableNodeInfoInner::setTableBox(const SwTableBox * pTableBox) { mpTableBox = pTableBox; @@ -91,6 +113,11 @@ void WW8TableNodeInfoInner::setTable(const SwTable * pTable) mpTable = pTable; } +void WW8TableNodeInfoInner::setRect(const SwRect & rRect) +{ + maRect = rRect; +} + sal_uInt32 WW8TableNodeInfoInner::getDepth() const { return mnDepth; @@ -106,6 +133,16 @@ 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; @@ -126,6 +163,127 @@ const SwNode * WW8TableNodeInfoInner::getNode() const 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; @@ -136,30 +294,42 @@ 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_PRIxUINT32 "\"" - " cell=\"%" SAL_PRIxUINT32 "\"" - " row=\"%" SAL_PRIxUINT32 "\"" + "<tableinner depth=\"%" SAL_PRIuUINT32 "\"" + " cell=\"%" SAL_PRIuUINT32 "\"" + " row=\"%" SAL_PRIuUINT32 "\"" " endOfCell=\"%s\"" - " endOfLine=\"%s\"/>", + " endOfLine=\"%s\"" + " shadowsBefore=\"%" SAL_PRIuUINT32 "\"" + " shadowsAfter=\"%" SAL_PRIuUINT32 "\"" + " vertMerge=\"%s\"/>", mnDepth, mnCell, mnRow, mbEndOfCell ? "yes" : "no", - mbEndOfLine ? "yes" : "no"); + mbEndOfLine ? "yes" : "no", + mnShadowsBefore, + mnShadowsAfter, + mbVertMerge ? "yes" : "no"); return string(buffer); } // WW8TableTextNodeInfo -WW8TableNodeInfo::WW8TableNodeInfo(const SwNode * pNode) -: - mnDepth(0), - mpNode(pNode), - mpNext(NULL), - mpNextNode(NULL) +WW8TableNodeInfo::WW8TableNodeInfo(WW8TableInfo * pParent, + const SwNode * pNode) +: mpParent(pParent), + mnDepth(0), + mpNode(pNode), + mpNext(NULL), + mpNextNode(NULL) { } @@ -171,8 +341,8 @@ WW8TableNodeInfo::~WW8TableNodeInfo() { static char buffer[1024]; snprintf(buffer, sizeof(buffer), - "<tableNodeInfo depth=\"%" SAL_PRIxUINT32 "\">" - , getDepth()); + "<tableNodeInfo p=\"%p\" depth=\"%" SAL_PRIuUINT32 "\">" + ,this, getDepth()); ::std::string sResult(buffer); @@ -191,7 +361,7 @@ WW8TableNodeInfo::~WW8TableNodeInfo() sResult += dbg_out(*mpNode); #endif - sResult +="</tableNodeInfo>"; + sResult += "</tableNodeInfo>"; return sResult; } @@ -230,6 +400,17 @@ void WW8TableNodeInfo::setEndOfCell(bool bEndOfCell) #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); @@ -251,9 +432,14 @@ void WW8TableNodeInfo::setNext(WW8TableNodeInfo * pNext) #endif } -void WW8TableNodeInfo::setNextNode(SwNode * pNode) +void WW8TableNodeInfo::setNextNode(const SwNode * pNode) +{ + mpNextNode = pNode; +} + +void WW8TableNodeInfo::setRect(const SwRect & rRect) { - mpNode = pNode; + getInnerForDepth(mnDepth)->setRect(rRect); } void WW8TableNodeInfo::setCell(sal_uInt32 nCell) @@ -266,6 +452,21 @@ 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) @@ -294,11 +495,16 @@ WW8TableNodeInfo * WW8TableNodeInfo::getNext() const return mpNext; } -SwNode * WW8TableNodeInfo::getNextNode() const +const SwNode * WW8TableNodeInfo::getNextNode() const { return mpNextNode; } +const SwRect & WW8TableNodeInfo::getRect() const +{ + return getInnerForDepth(mnDepth)->getRect(); +} + bool WW8TableNodeInfo::isEndOfLine() const { return getInnerForDepth(mnDepth)->isEndOfLine(); @@ -357,31 +563,101 @@ 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 - const SwTableLines & rLines = pTable->GetTabLines(); - WW8TableNodeInfo * pPrev = NULL; - - for (USHORT n = 0; n < rLines.Count(); n++) + + 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 SwTableLine * pLine = rLines[n]; + 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); + } - 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 @@ -414,7 +690,7 @@ WW8TableInfo::processTableLine(const SwTable * pTable, #endif return pPrev; -} +} WW8TableNodeInfo::Pointer_t WW8TableInfo::processTableBoxLines(const SwTableBox * pBox, @@ -471,7 +747,6 @@ WW8TableInfo::processTableBoxLines(const SwTableBox * pBox, return pNodeInfo; } - WW8TableNodeInfo * WW8TableInfo::processTableBox(const SwTable * pTable, const SwTableBox * pBox, @@ -573,13 +848,15 @@ WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo const SwTableBox * pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, - sal_uInt32 nDepth) + sal_uInt32 nDepth, + SwRect * pRect) { WW8TableNodeInfo::Pointer_t pNodeInfo = getTableNodeInfo(pNode); if (pNodeInfo.get() == NULL) { - pNodeInfo = WW8TableNodeInfo::Pointer_t(new WW8TableNodeInfo(pNode)); + pNodeInfo = + WW8TableNodeInfo::Pointer_t(new WW8TableNodeInfo(this, pNode)); mMap.insert(Map_t::value_type(pNode, pNodeInfo)); } @@ -590,7 +867,15 @@ WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo pNodeInfo->setCell(nCell); pNodeInfo->setRow(nRow); - + + 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 @@ -598,6 +883,26 @@ WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo 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) { @@ -624,7 +929,7 @@ const SwNode * WW8TableInfo::getNextNode(const SwNode * pNode) pResult = pNextInfo->getNode(); else { - SwNode * pNextNode = pNodeInfo->getNextNode(); + const SwNode * pNextNode = pNodeInfo->getNextNode(); if (pNextNode != NULL) pResult = pNextNode; @@ -634,4 +939,547 @@ const SwNode * WW8TableInfo::getNextNode(const SwNode * pNode) 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(); + } +} + } diff --git a/sw/source/filter/ww8/WW8TableInfo.hxx b/sw/source/filter/ww8/WW8TableInfo.hxx index 620fa620e4..ee838dcb54 100644 --- a/sw/source/filter/ww8/WW8TableInfo.hxx +++ b/sw/source/filter/ww8/WW8TableInfo.hxx @@ -33,18 +33,29 @@ #include <functional> #include <boost/shared_ptr.hpp> #include <sal/types.h> +#include <swrect.hxx> class SwTable; class SwTableLine; class SwTableBox; class SwNode; class SwWW8Writer; +class AttributeOutputBase; namespace ww8 { using namespace ::std; class WW8TableNodeInfo; +typedef boost::shared_ptr<SwRect> SwRectPtr; +typedef ::std::vector<const SwTableBox *> TableBoxVector; +typedef boost::shared_ptr<TableBoxVector> TableBoxVectorPtr; +typedef ::std::vector<sal_uInt32> GridCols; +typedef boost::shared_ptr<GridCols> GridColsPtr; +typedef ::std::vector<sal_uInt32> RowSpans; +typedef boost::shared_ptr<RowSpans> RowSpansPtr; +typedef ::std::vector<sal_uInt32> Widths; +typedef boost::shared_ptr<Widths> WidthsPtr; class WW8TableNodeInfoInner { @@ -52,10 +63,14 @@ class WW8TableNodeInfoInner sal_uInt32 mnDepth; sal_uInt32 mnCell; sal_uInt32 mnRow; + sal_uInt32 mnShadowsBefore; + sal_uInt32 mnShadowsAfter; bool mbEndOfLine; bool mbEndOfCell; + bool mbVertMerge; const SwTableBox * mpTableBox; const SwTable * mpTable; + SwRect maRect; public: typedef boost::shared_ptr<WW8TableNodeInfoInner> Pointer_t; @@ -66,52 +81,77 @@ public: void setDepth(sal_uInt32 nDepth); void setCell(sal_uInt32 nCell); void setRow(sal_uInt32 nRow); + void setShadowsBefore(sal_uInt32 nShadowsBefore); + void setShadowsAfter(sal_uInt32 nShadowsAfter); void setEndOfLine(bool bEndOfLine); void setEndOfCell(bool bEndOfCell); + void setVertMerge(bool bVertMErge); void setTableBox(const SwTableBox * pTableBox); void setTable(const SwTable * pTable); + void setRect(const SwRect & rRect); sal_uInt32 getDepth() const; sal_uInt32 getCell() const; sal_uInt32 getRow() const; + sal_uInt32 getShadowsBefore() const; + sal_uInt32 getShadowsAfter() const; bool isEndOfCell() const; bool isEndOfLine() const; + bool isVertMerge() const; const SwTableBox * getTableBox() const; const SwTable * getTable() const; + const SwRect & getRect() const; const SwNode * getNode() const; + TableBoxVectorPtr getTableBoxesOfRow(); + WidthsPtr getWidthsOfRow(); + GridColsPtr getGridColsOfRow(AttributeOutputBase & rBase); + RowSpansPtr getRowSpansOfRow(); + string toString() const; }; - + +class CellInfo; +typedef ::std::multiset<CellInfo, less<CellInfo> > CellInfoMultiSet; +typedef boost::shared_ptr<CellInfoMultiSet> CellInfoMultiSetPtr; + +class WW8TableInfo; class WW8TableNodeInfo { public: - typedef map<sal_uInt32, WW8TableNodeInfoInner::Pointer_t, greater<sal_uInt32> > Inners_t; + typedef map<sal_uInt32, WW8TableNodeInfoInner::Pointer_t, + greater<sal_uInt32> > Inners_t; private: + WW8TableInfo * mpParent; sal_uInt32 mnDepth; const SwNode * mpNode; Inners_t mInners; WW8TableNodeInfo * mpNext; - SwNode * mpNextNode; - + const SwNode * mpNextNode; + public: typedef boost::shared_ptr<WW8TableNodeInfo> Pointer_t; - WW8TableNodeInfo(const SwNode * pTxtNode); + WW8TableNodeInfo(WW8TableInfo * pParent, const SwNode * pTxtNode); virtual ~WW8TableNodeInfo(); void setDepth(sal_uInt32 nDepth); void setEndOfLine(bool bEndOfLine); void setEndOfCell(bool bEndOfCell); + void setVertMerge(bool bVertMerge); void setTableBox(const SwTableBox *pTableBox); void setTable(const SwTable * pTable); void setCell(sal_uInt32 nCell); void setRow(sal_uInt32 nRow); + void setShadowsBefore(sal_uInt32 nShadowsBefore); + void setShadowsAfter(sal_uInt32 nShadowsAfter); void setNext(WW8TableNodeInfo * pNext); - void setNextNode(SwNode * pNode); + void setNextNode(const SwNode * pNode); + void setRect(const SwRect & rRect); + WW8TableInfo * getParent() const; sal_uInt32 getDepth() const; bool isEndOfLine() const; bool isEndOfCell() const; @@ -119,7 +159,8 @@ public: const SwTableBox * getTableBox() const; const SwTable * getTable() const; WW8TableNodeInfo * getNext() const; - SwNode * getNextNode() const; + const SwNode * getNextNode() const; + const SwRect & getRect() const; const Inners_t & getInners() const; const WW8TableNodeInfoInner::Pointer_t getFirstInner() const; @@ -129,6 +170,8 @@ public: sal_uInt32 getRow() const; ::std::string toString() const; + + bool operator < (const WW8TableNodeInfo & rInfo) const; }; struct hashNode @@ -137,10 +180,77 @@ struct hashNode { return reinterpret_cast<size_t>(pNode); } }; +struct hashTable +{ + size_t operator()(const SwTable * pTable) const + { return reinterpret_cast<size_t>(pTable); } +}; + +class WW8TableCellGridRow +{ + CellInfoMultiSetPtr m_pCellInfos; + TableBoxVectorPtr m_pTableBoxVector; + WidthsPtr m_pWidths; + RowSpansPtr m_pRowSpans; + +public: + typedef boost::shared_ptr<WW8TableCellGridRow> Pointer_t; + WW8TableCellGridRow(); + ~WW8TableCellGridRow(); + + void insert(const CellInfo & rCellInfo); + CellInfoMultiSet::const_iterator begin() const; + CellInfoMultiSet::const_iterator end() const; + + void setTableBoxVector(TableBoxVectorPtr pTableBoxVector); + void setWidths(WidthsPtr pGridCols); + void setRowSpans(RowSpansPtr pRowSpans); + + TableBoxVectorPtr getTableBoxVector() const; + WidthsPtr getWidths() const; + RowSpansPtr getRowSpans() const; +}; + +class WW8TableCellGrid +{ + typedef ::std::set<long> RowTops_t; + typedef ::std::map<long, WW8TableCellGridRow::Pointer_t> Rows_t; + + RowTops_t m_aRowTops; + Rows_t m_aRows; + + WW8TableCellGridRow::Pointer_t getRow(long nTop, bool bCreate = true); + RowTops_t::const_iterator getRowTopsBegin() const; + RowTops_t::const_iterator getRowTopsEnd() const; + CellInfoMultiSet::const_iterator getCellsBegin(long nTop); + CellInfoMultiSet::const_iterator getCellsEnd(long nTop); + +public: + typedef ::boost::shared_ptr<WW8TableCellGrid> Pointer_t; + + WW8TableCellGrid(); + ~WW8TableCellGrid(); + + void insert(const SwRect & rRect, WW8TableNodeInfo * pNodeInfo, + unsigned long * pFmtFrmWidth = NULL); + void addShadowCells(); + WW8TableNodeInfo * connectCells(); + + string toString(); + + TableBoxVectorPtr getTableBoxesOfRow(WW8TableNodeInfoInner * pNodeInfo); + WidthsPtr getWidthsOfRow(WW8TableNodeInfoInner * pNodeInfo); + RowSpansPtr getRowSpansOfRow(WW8TableNodeInfoInner * pNodeInfo); +}; + class WW8TableInfo { + friend class WW8TableNodeInfoInner; typedef hash_map<const SwNode *, WW8TableNodeInfo::Pointer_t, hashNode > Map_t; + typedef hash_map<const SwTable *, WW8TableCellGrid::Pointer_t, hashTable > CellGridMap_t; + Map_t mMap; + CellGridMap_t mCellGridMap; WW8TableNodeInfo * processTableLine(const SwTable * pTable, @@ -169,7 +279,11 @@ class WW8TableInfo const SwTableBox * pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, - sal_uInt32 nDepth); + sal_uInt32 nDepth, + SwRect * pRect = NULL); + + WW8TableCellGrid::Pointer_t getCellGridForTable(const SwTable * pTable, + bool bCreate = true); public: typedef boost::shared_ptr<WW8TableInfo> Pointer_t; @@ -178,9 +292,54 @@ public: virtual ~WW8TableInfo(); void processSwTable(const SwTable * pTable); + WW8TableNodeInfo * processSwTableByLayout(const SwTable * pTable); WW8TableNodeInfo::Pointer_t getTableNodeInfo(const SwNode * pNode); const SwNode * getNextNode(const SwNode * pNode); + + WW8TableNodeInfo * reorderByLayout(const SwTable * pTable); }; +class CellInfo +{ + SwRect m_aRect; + WW8TableNodeInfo * m_pNodeInfo; + unsigned long m_nFmtFrmWidth; + +public: + CellInfo(const SwRect & aRect, WW8TableNodeInfo * pNodeInfo); + + CellInfo(const CellInfo & aRectAndTableInfo) + : m_aRect(aRectAndTableInfo.m_aRect), + m_pNodeInfo(aRectAndTableInfo.m_pNodeInfo), + m_nFmtFrmWidth(aRectAndTableInfo.m_nFmtFrmWidth) + { + } + + ~CellInfo() {} + + bool operator < (const CellInfo & aCellInfo) const; + + long top() const { return m_aRect.Top(); } + long bottom() const { return m_aRect.Bottom(); } + long left() const { return m_aRect.Left(); } + long right() const { return m_aRect.Right(); } + long width() const { return m_aRect.Width(); } + long height() const { return m_aRect.Height(); } + SwRect getRect() const { return m_aRect; } + WW8TableNodeInfo * getTableNodeInfo() const + { return m_pNodeInfo; } + unsigned long getFmtFrmWidth() const + { + return m_nFmtFrmWidth; + } + + void setFmtFrmWidth(unsigned long nFmtFrmWidth) + { + m_nFmtFrmWidth = nFmtFrmWidth; + } + + ::std::string toString() const; +}; + } #endif // WW8_TABLE_INFO_HXX diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index 47a42b2079..fd5ac96d8d 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -552,9 +552,7 @@ protected: virtual bool AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark ); - std::vector<SwTwips> GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); - - void GetTablePageSize( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ); + ww8::GridColsPtr GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); public: AttributeOutputBase() {} @@ -571,6 +569,11 @@ public: /// Output frames. void OutputFlyFrame( const sw::Frame& rFmt ); + + void GetTablePageSize + ( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, + sal_uInt32& rPageSize, bool& rRelBoxSize ); + }; #endif // _ATTRIBUTEOUTPUTBASE_HXX_ diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 630ee29429..1baf7dac31 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -1914,28 +1914,29 @@ void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTa } } -static sal_uInt16 lcl_TCFlags(const SwTableBox * pBox) +static sal_uInt16 lcl_TCFlags(const SwTableBox * pBox, long nRowSpan) { sal_uInt16 nFlags = 0; - long nRowSpan = pBox->getRowSpan(); - if (nRowSpan > 1) nFlags |= (3 << 5); else if (nRowSpan < 0) nFlags |= (1 << 5); - const SwFrmFmt * pFmt = pBox->GetFrmFmt(); - switch (pFmt->GetVertOrient().GetVertOrient()) + if (pBox != NULL) { - case text::VertOrientation::CENTER: - nFlags |= (1 << 7); - break; - case text::VertOrientation::BOTTOM: - nFlags |= (2 << 7); - break; - default: - break; + const SwFrmFmt * pFmt = pBox->GetFrmFmt(); + switch (pFmt->GetVertOrient().GetVertOrient()) + { + case text::VertOrientation::CENTER: + nFlags |= (1 << 7); + break; + case text::VertOrientation::BOTTOM: + nFlags |= (2 << 7); + break; + default: + break; + } } return nFlags; @@ -2093,9 +2094,6 @@ void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { - const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); - const SwTableLine * pTabLine = pTabBox->GetUpper(); - const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); const SwTable * pTable = pTableTextNodeInfoInner->getTable(); if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() ) @@ -2107,11 +2105,11 @@ void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); } + ww8::TableBoxVectorPtr pTableBoxes = + pTableTextNodeInfoInner->getTableBoxesOfRow(); // number of cell written - sal_uInt32 nBoxes = rTabBoxes.Count(); - if ( nBoxes > 32 ) - nBoxes = 32; - + sal_uInt32 nBoxes = pTableBoxes->size(); + // sprm header m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable ); sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20; @@ -2161,86 +2159,71 @@ void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t } } - sal_uInt32 n = 0; - m_rWW8Export.InsUInt16( nTblOffset ); - - std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner ); - for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(), end = gridCols.end(); it != end; ++it ) - { - m_rWW8Export.InsUInt16( static_cast<USHORT>( *it ) + nTblOffset ); - } + m_rWW8Export.InsUInt16( nTblOffset ); + + ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner ); + for ( ww8::GridCols::const_iterator it = pGridCols->begin(), + end = pGridCols->end(); it != end; ++it ) + { + m_rWW8Export.InsUInt16( static_cast<USHORT>( *it ) + nTblOffset ); + } + + /* TCs */ + ww8::RowSpansPtr pRowSpans = pTableTextNodeInfoInner->getRowSpansOfRow(); + ww8::RowSpans::const_iterator aItRowSpans = pRowSpans->begin(); + ww8::TableBoxVector::const_iterator aIt; + ww8::TableBoxVector::const_iterator aItEnd = pTableBoxes->end(); - /* TCs */ - for ( n = 0; n < nBoxes; n++ ) +#ifdef DEBUG + size_t nRowSpans = pRowSpans->size(); + size_t nTableBoxes = pTableBoxes->size(); + (void) nRowSpans; + (void) nTableBoxes; +#endif + + for( aIt = pTableBoxes->begin(); aIt != aItEnd; ++aIt, ++aItRowSpans) { #ifdef DEBUG sal_uInt16 npOCount = m_rWW8Export.pO->Count(); #endif - SwTableBox * pTabBox1 = rTabBoxes[n]; - const SwFrmFmt & rBoxFmt = *(pTabBox1->GetFrmFmt()); + const SwTableBox * pTabBox1 = *aIt; + const SwFrmFmt * pBoxFmt = NULL; + if (pTabBox1 != NULL) + pBoxFmt = pTabBox1->GetFrmFmt(); + if ( m_rWW8Export.bWrtWW8 ) { - sal_uInt16 nFlags = lcl_TCFlags(pTabBox1); - m_rWW8Export.InsUInt16( nFlags ); + sal_uInt16 nFlags = + lcl_TCFlags(pTabBox1, *aItRowSpans); + m_rWW8Export.InsUInt16( nFlags ); } static BYTE aNullBytes[] = { 0x0, 0x0 }; m_rWW8Export.pO->Insert( aNullBytes, 2, m_rWW8Export.pO->Count() ); // dummy - m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, rBoxFmt.GetBox() ); // 8/16 Byte + if (pBoxFmt != NULL) + { + const SvxBoxItem & rBoxItem = pBoxFmt->GetBox(); + + m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, &rBoxItem ); // 8/16 Byte + } + else + m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, NULL); // 8/16 Byte #ifdef DEBUG - ::std::clog << "<tclength>" << m_rWW8Export.pO->Count() - npOCount << "</tclength>" - << ::std::endl; + ::std::clog << "<tclength>" << m_rWW8Export.pO->Count() - npOCount << "</tclength>" + << ::std::endl; #endif } } -std::vector<SwTwips> AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { - std::vector<SwTwips> gridCols; - - const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); - const SwTableLine * pTabLine = pTabBox->GetUpper(); - const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); - const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); - - // number of cell written - sal_uInt32 nBoxes = rTabBoxes.Count(); - if ( nBoxes > 32 ) - nBoxes = 32; - - const SwFrmFmt *pFmt = pTable->GetFrmFmt(); - ASSERT(pFmt,"Impossible"); - if (!pFmt) - return gridCols; - - const SwFmtFrmSize &rSize = pFmt->GetFrmSize(); - unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth()); - - sal_uInt32 nPageSize = 0; - bool bRelBoxSize = false; - - GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); - - SwTwips nSz = 0; - for ( sal_uInt32 n = 0; n < nBoxes; n++ ) - { - const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt(); - const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize(); - nSz += rLSz.GetWidth(); - SwTwips nCalc = nSz; - if ( bRelBoxSize ) - nCalc = ( nCalc * nPageSize ) / nTblSz; - - gridCols.push_back( nCalc ); - } - - return gridCols; + return pTableTextNodeInfoInner->getGridColsOfRow(*this); } - -void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ) + +void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ) { sal_uInt32 nPageSize = 0; @@ -2455,18 +2438,7 @@ void MSWordExportBase::WriteText() } else { - ::std::clog << "<already-done><which>" << dbg_out(*pNd) - << "</which><nodes>" << ::std::endl; - - SwNodeDeque::const_iterator aEnd = aNodeDeque.end(); - - for (SwNodeDeque::const_iterator aIt = aNodeDeque.begin(); - aIt != aEnd; aIt++) - { - ::std::clog << dbg_out(**aIt) << ::std::endl; - } - - ::std::clog << "</nodes></already-done>" << ::std::endl; + ::std::clog << "<already-done>" << dbg_out(*pNd) << "</already-done>" << ::std::endl; } #endif @@ -2522,6 +2494,10 @@ void MSWordExportBase::WriteText() AppendSection( pAktPageDesc, pParentFmt, nRstLnNum ); } } + else if ( pNd->IsStartNode() ) + { + OutputStartNode( *pNd->GetStartNode() ); + } else if ( pNd->IsEndNode() ) { OutputEndNode( *pNd->GetEndNode() ); @@ -3684,6 +3660,30 @@ void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren + sal_uInt32 nShadowsBefore = pNodeInfoInner->getShadowsBefore(); + if (nShadowsBefore > 0) + { + ww8::WW8TableNodeInfoInner::Pointer_t + pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL)); + + pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth()); + pTmpNodeInfoInner->setEndOfCell(true); + + for (sal_uInt32 n = 0; n < nShadowsBefore; ++n) + { + m_rWW8Export.WriteCR(pTmpNodeInfoInner); + + m_rWW8Export.pO->Insert( (BYTE*)&nStyle, 2, + m_rWW8Export.pO->Count() ); // Style # + TableInfoCell(pTmpNodeInfoInner); + m_rWW8Export.pPapPlc->AppendFkpEntry + ( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); + + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren + } + } + if (pNodeInfoInner->isEndOfCell()) { #ifdef DEBUG @@ -3699,6 +3699,28 @@ void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren } + sal_uInt32 nShadowsAfter = pNodeInfoInner->getShadowsAfter(); + if (nShadowsAfter > 0) + { + ww8::WW8TableNodeInfoInner::Pointer_t + pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL)); + + pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth()); + pTmpNodeInfoInner->setEndOfCell(true); + + for (sal_uInt32 n = 0; n < nShadowsAfter; ++n) + { + m_rWW8Export.WriteCR(pTmpNodeInfoInner); + + m_rWW8Export.pO->Insert( (BYTE*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # + TableInfoCell(pTmpNodeInfoInner); + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); + + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren + } + } + if (pNodeInfoInner->isEndOfLine()) { #ifdef DEBUG @@ -3719,6 +3741,37 @@ void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer #endif } +void MSWordExportBase::OutputStartNode( const SwStartNode & rNode) +{ +#ifdef DEBUG + ::std::clog << "<OutWW8_SwStartNode>" << dbg_out(&rNode) << ::std::endl; +#endif + + ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = + mpTableInfo->getTableNodeInfo( &rNode ); + + if (pNodeInfo.get() != NULL) + { +#ifdef DEBUG + ::std::clog << pNodeInfo->toString() << ::std::endl; +#endif + + const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners(); + ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aIt(aInners.rbegin()); + ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aEnd(aInners.rend()); + while (aIt != aEnd) + { + ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; + + AttrOutput().TableNodeInfoInner(pInner); + aIt++; + } + } +#ifdef DEBUG + ::std::clog << "</OutWW8_SwStartNode>" << ::std::endl; +#endif +} + void MSWordExportBase::OutputEndNode( const SwEndNode &rNode ) { #ifdef DEBUG @@ -3727,25 +3780,22 @@ void MSWordExportBase::OutputEndNode( const SwEndNode &rNode ) ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode ); - if (pNodeInfo) - { - if (pNodeInfo.get() != NULL) - { -#ifdef DEBUG - ::std::clog << pNodeInfo->toString() << ::std::endl; + if (pNodeInfo.get() != NULL) + { +#ifdef DEBUG + ::std::clog << pNodeInfo->toString() << ::std::endl; #endif - - const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners(); - ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin()); - ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end()); - while (aIt != aEnd) - { - ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; - AttrOutput().TableNodeInfoInner(pInner); - aIt++; - } - } - } + + const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners(); + ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin()); + ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end()); + while (aIt != aEnd) + { + ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; + AttrOutput().TableNodeInfoInner(pInner); + aIt++; + } + } #ifdef DEBUG ::std::clog << "</OutWW8_SwEndNode>" << ::std::endl; #endif diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 52fb08213e..43211a962e 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -763,6 +763,9 @@ protected: virtual bool DisallowInheritingOutlineNumbering(const SwFmt &rFmt) = 0; protected: + /// Output SwStartNode + virtual void OutputStartNode( const SwStartNode& ); + /// Output SwEndNode virtual void OutputEndNode( const SwEndNode& ); @@ -1017,7 +1020,7 @@ public: const SwPageDesc* pNewPgDesc = 0 ); void Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow); - void Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ); + void Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem * rBox ); BYTE TransCol( const Color& rCol ); bool TransBrush(const Color& rCol, WW8_SHD& rShd); WW8_BRC TranslateBorderLine(const SvxBorderLine& pLine, diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index 61e8d6016c..89a4673b42 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -4297,17 +4297,24 @@ void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow) // ( Tabellenumrandungen fransen sonst aus ) // Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben -void WW8Export::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ) +void WW8Export::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem * pBox ) { // moeglich und vielleicht besser waere 0xffff static const USHORT aBorders[] = { BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT }; + static const SvxBorderLine aBorderLine; + const USHORT* pBrd = aBorders; for( int i = 0; i < 4; ++i, ++pBrd ) { - const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); + const SvxBorderLine* pLn; + if (pBox != NULL) + pLn = pBox->GetLine( *pBrd ); + else + pLn = & aBorderLine; + Out_BorderLine(rO, pLn, 0, 0, false); } } diff --git a/sw/source/ui/app/apphdl.cxx b/sw/source/ui/app/apphdl.cxx index 708d6ceed3..d57e22b985 100644 --- a/sw/source/ui/app/apphdl.cxx +++ b/sw/source/ui/app/apphdl.cxx @@ -765,16 +765,26 @@ void SwModule::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) DELETEZ(pWebToolbarConfig) ; DELETEZ(pAuthorNames) ; DELETEZ(pDBConfig); - pColorConfig->RemoveListener(this); - DELETEZ(pColorConfig); - pAccessibilityOptions->RemoveListener(this); - DELETEZ(pAccessibilityOptions); - pCTLOptions->RemoveListener(this); - DELETEZ(pCTLOptions); - pUserOptions->RemoveListener(this); - DELETEZ(pUserOptions); - pUndoOptions->RemoveListener(this); - DELETEZ(pUndoOptions); + if (pColorConfig != 0) { + pColorConfig->RemoveListener(this); + DELETEZ(pColorConfig); + } + if (pAccessibilityOptions != 0) { + pAccessibilityOptions->RemoveListener(this); + DELETEZ(pAccessibilityOptions); + } + if (pCTLOptions != 0) { + pCTLOptions->RemoveListener(this); + DELETEZ(pCTLOptions); + } + if (pUserOptions != 0) { + pUserOptions->RemoveListener(this); + DELETEZ(pUserOptions); + } + if (pUndoOptions != 0) { + pUndoOptions->RemoveListener(this); + DELETEZ(pUndoOptions); + } } } } |