LCOV - code coverage report
Current view: top level - sw/source/core/docnode - ndcopy.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 124 152 81.6 %
Date: 2014-11-03 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include <doc.hxx>
      20             : #include <IDocumentFieldsAccess.hxx>
      21             : #include <node.hxx>
      22             : #include <frmfmt.hxx>
      23             : #include <swtable.hxx>
      24             : #include <ndtxt.hxx>
      25             : #include <swtblfmt.hxx>
      26             : #include <cellatr.hxx>
      27             : #include <docary.hxx>
      28             : #include <ddefld.hxx>
      29             : #include <swddetbl.hxx>
      30             : #include <svtools/fmtfield.hxx>
      31             : #include <boost/foreach.hpp>
      32             : #include <vector>
      33             : 
      34             : 
      35             : #ifdef DBG_UTIL
      36             : #define CHECK_TABLE(t) (t).CheckConsistency();
      37             : #else
      38             : #define CHECK_TABLE(t)
      39             : #endif
      40             : 
      41             : 
      42             : 
      43             : // Structure for the mapping from old and new frame formats to the
      44             : // boxes and lines of a table
      45             : struct _MapTblFrmFmt
      46             : {
      47             :     const SwFrmFmt *pOld, *pNew;
      48        2234 :     _MapTblFrmFmt( const SwFrmFmt *pOldFmt, const SwFrmFmt*pNewFmt )
      49        2234 :         : pOld( pOldFmt ), pNew( pNewFmt )
      50        2234 :     {}
      51             : };
      52             : 
      53             : typedef std::vector<_MapTblFrmFmt> _MapTblFrmFmts;
      54             : 
      55       10112 : SwCntntNode* SwTxtNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
      56             : {
      57             :     // the Copy-Textnode is the Node with the Text, the Copy-Attrnode is the
      58             :     // node with the collection and hard attributes. Normally is the same
      59             :     // node, but if insert a glossary without formatting, then the Attrnode
      60             :     // is the prev node of the destionation position in dest. document.
      61       10112 :     SwTxtNode* pCpyTxtNd = (SwTxtNode*)this;
      62       10112 :     SwTxtNode* pCpyAttrNd = pCpyTxtNd;
      63             : 
      64             :     // Copy the formats to the other document
      65       10112 :     SwTxtFmtColl* pColl = 0;
      66       10112 :     if( pDoc->IsInsOnlyTextGlossary() )
      67             :     {
      68           4 :         SwNodeIndex aIdx( rIdx, -1 );
      69           4 :         if( aIdx.GetNode().IsTxtNode() )
      70             :         {
      71           4 :             pCpyAttrNd = aIdx.GetNode().GetTxtNode();
      72           4 :             pColl = &pCpyAttrNd->GetTxtColl()->GetNextTxtFmtColl();
      73           4 :         }
      74             :     }
      75       10112 :     if( !pColl )
      76       10108 :         pColl = pDoc->CopyTxtColl( *GetTxtColl() );
      77             : 
      78       10112 :     SwTxtNode* pTxtNd = pDoc->GetNodes().MakeTxtNode( rIdx, pColl );
      79             : 
      80             :     // METADATA: register copy
      81       10112 :     pTxtNd->RegisterAsCopyOf(*pCpyTxtNd);
      82             : 
      83             :     // Copy Attribute/Text
      84       10112 :     if( !pCpyAttrNd->HasSwAttrSet() )
      85             :         // An AttrSet was added for numbering, so delete it
      86        6126 :         pTxtNd->ResetAllAttr();
      87             : 
      88             :     // if Copy-Textnode unequal to Copy-Attrnode, then copy first
      89             :     // the attributes into the new Node.
      90       10112 :     if( pCpyAttrNd != pCpyTxtNd )
      91             :     {
      92           4 :         pCpyAttrNd->CopyAttr( pTxtNd, 0, 0 );
      93           4 :         if( pCpyAttrNd->HasSwAttrSet() )
      94             :         {
      95           0 :             SwAttrSet aSet( *pCpyAttrNd->GetpSwAttrSet() );
      96           0 :             aSet.ClearItem( RES_PAGEDESC );
      97           0 :             aSet.ClearItem( RES_BREAK );
      98           0 :             aSet.CopyToModify( *pTxtNd );
      99             :         }
     100             :     }
     101             : 
     102             :     // Is that enough? What about PostIts/Fields/FieldTypes?
     103             :     // #i96213# - force copy of all attributes
     104       10112 :     pCpyTxtNd->CopyText( pTxtNd, SwIndex( pCpyTxtNd ),
     105       20224 :         pCpyTxtNd->GetTxt().getLength(), true );
     106             : 
     107       10112 :     if( RES_CONDTXTFMTCOLL == pColl->Which() )
     108           0 :         pTxtNd->ChkCondColl();
     109             : 
     110       10112 :     return pTxtNd;
     111             : }
     112             : 
     113       12274 : static bool lcl_SrchNew( const _MapTblFrmFmt& rMap, const SwFrmFmt** pPara )
     114             : {
     115       12274 :     if( rMap.pOld != *pPara )
     116       12254 :         return true;
     117          20 :     *pPara = rMap.pNew;
     118          20 :     return false;
     119             : }
     120             : 
     121             : struct _CopyTable
     122             : {
     123             :     SwDoc* pDoc;
     124             :     sal_uLong nOldTblSttIdx;
     125             :     _MapTblFrmFmts& rMapArr;
     126             :     SwTableLine* pInsLine;
     127             :     SwTableBox* pInsBox;
     128             :     SwTableNode *pTblNd;
     129             :     const SwTable *pOldTable;
     130             : 
     131         440 :     _CopyTable( SwDoc* pDc, _MapTblFrmFmts& rArr, sal_uLong nOldStt,
     132             :                 SwTableNode& rTblNd, const SwTable* pOldTbl )
     133             :         : pDoc(pDc), nOldTblSttIdx(nOldStt), rMapArr(rArr),
     134         440 :         pInsLine(0), pInsBox(0), pTblNd(&rTblNd), pOldTable( pOldTbl )
     135         440 :     {}
     136             : };
     137             : 
     138             : static void lcl_CopyTblLine( const SwTableLine* pLine, _CopyTable* pCT );
     139             : 
     140        1604 : static void lcl_CopyTblBox( SwTableBox* pBox, _CopyTable* pCT )
     141             : {
     142        1604 :     SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
     143       10990 :     for( _MapTblFrmFmts::const_iterator it = pCT->rMapArr.begin(); it != pCT->rMapArr.end(); ++it )
     144        9406 :         if ( !lcl_SrchNew( *it, (const SwFrmFmt**)&pBoxFmt ) )
     145          20 :             break;
     146        1604 :     if( pBoxFmt == pBox->GetFrmFmt() ) // Create a new one?
     147             :     {
     148             :         const SfxPoolItem* pItem;
     149        1584 :         if( SfxItemState::SET == pBoxFmt->GetItemState( RES_BOXATR_FORMULA, false,
     150        1584 :             &pItem ) && ((SwTblBoxFormula*)pItem)->IsIntrnlName() )
     151             :         {
     152           0 :             ((SwTblBoxFormula*)pItem)->PtrToBoxNm( pCT->pOldTable );
     153             :         }
     154             : 
     155        1584 :         pBoxFmt = pCT->pDoc->MakeTableBoxFmt();
     156        1584 :         pBoxFmt->CopyAttrs( *pBox->GetFrmFmt() );
     157             : 
     158        1584 :         if( pBox->GetSttIdx() )
     159             :         {
     160        1584 :             SvNumberFormatter* pN = pCT->pDoc->GetNumberFormatter( false );
     161        1584 :             if( pN && pN->HasMergeFmtTbl() && SfxItemState::SET == pBoxFmt->
     162           0 :                 GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
     163             :             {
     164           0 :                 sal_uLong nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
     165           0 :                 sal_uLong nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
     166           0 :                 if( nNewIdx != nOldIdx )
     167           0 :                     pBoxFmt->SetFmtAttr( SwTblBoxNumFormat( nNewIdx ));
     168             : 
     169             :             }
     170             :         }
     171             : 
     172        1584 :         pCT->rMapArr.push_back( _MapTblFrmFmt( pBox->GetFrmFmt(), pBoxFmt ) );
     173             :     }
     174             : 
     175        1604 :     sal_uInt16 nLines = pBox->GetTabLines().size();
     176             :     SwTableBox* pNewBox;
     177        1604 :     if( nLines )
     178           0 :         pNewBox = new SwTableBox( pBoxFmt, nLines, pCT->pInsLine );
     179             :     else
     180             :     {
     181             :         SwNodeIndex aNewIdx( *pCT->pTblNd,
     182        1604 :                             pBox->GetSttIdx() - pCT->nOldTblSttIdx );
     183             :         OSL_ENSURE( aNewIdx.GetNode().IsStartNode(), "Index is not on the start node" );
     184        1604 :         pNewBox = new SwTableBox( pBoxFmt, aNewIdx, pCT->pInsLine );
     185        1604 :         pNewBox->setRowSpan( pBox->getRowSpan() );
     186             :     }
     187             : 
     188        1604 :     pCT->pInsLine->GetTabBoxes().push_back( pNewBox );
     189             : 
     190        1604 :     if( nLines )
     191             :     {
     192           0 :         _CopyTable aPara( *pCT );
     193           0 :         aPara.pInsBox = pNewBox;
     194           0 :         BOOST_FOREACH( const SwTableLine* pLine, pBox->GetTabLines() )
     195           0 :             lcl_CopyTblLine( pLine, &aPara );
     196             :     }
     197        1604 :     else if( pNewBox->IsInHeadline( &pCT->pTblNd->GetTable() ))
     198             :         // In the headline, the paragraphs must match conditional styles
     199        1024 :         pNewBox->GetSttNd()->CheckSectionCondColl();
     200        1604 : }
     201             : 
     202         650 : static void lcl_CopyTblLine( const SwTableLine* pLine, _CopyTable* pCT )
     203             : {
     204         650 :     SwTableLineFmt* pLineFmt = (SwTableLineFmt*)pLine->GetFrmFmt();
     205        3518 :     for( _MapTblFrmFmts::const_iterator it = pCT->rMapArr.begin(); it != pCT->rMapArr.end(); ++it )
     206        2868 :         if ( !lcl_SrchNew( *it, (const SwFrmFmt**)&pLineFmt ) )
     207           0 :             break;
     208         650 :     if( pLineFmt == pLine->GetFrmFmt() ) // Create a new one?
     209             :     {
     210         650 :         pLineFmt = pCT->pDoc->MakeTableLineFmt();
     211         650 :         pLineFmt->CopyAttrs( *pLine->GetFrmFmt() );
     212         650 :         pCT->rMapArr.push_back( _MapTblFrmFmt( pLine->GetFrmFmt(), pLineFmt ) );
     213             :     }
     214             :     SwTableLine* pNewLine = new SwTableLine( pLineFmt,
     215         650 :                             pLine->GetTabBoxes().size(), pCT->pInsBox );
     216             :     // Insert the new row into the table
     217         650 :     if( pCT->pInsBox )
     218             :     {
     219           0 :         pCT->pInsBox->GetTabLines().push_back( pNewLine );
     220             :     }
     221             :     else
     222             :     {
     223         650 :         pCT->pTblNd->GetTable().GetTabLines().push_back( pNewLine );
     224             :     }
     225         650 :     pCT->pInsLine = pNewLine;
     226        6762 :     for( SwTableBoxes::iterator it = ((SwTableLine*)pLine)->GetTabBoxes().begin();
     227        4508 :              it != ((SwTableLine*)pLine)->GetTabBoxes().end(); ++it)
     228        1604 :         lcl_CopyTblBox(*it, pCT );
     229         650 : }
     230             : 
     231         440 : SwTableNode* SwTableNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
     232             : {
     233             :     // In which array are we? Nodes? UndoNodes?
     234         440 :     SwNodes& rNds = (SwNodes&)GetNodes();
     235             : 
     236             :     {
     237         440 :         if( rIdx < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
     238           0 :             rIdx >= pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() )
     239           0 :             return 0;
     240             :     }
     241             : 
     242             :     // Copy the TableFrmFmt
     243         440 :     OUString sTblName( GetTable().GetFrmFmt()->GetName() );
     244         440 :     if( !pDoc->IsCopyIsMove() )
     245             :     {
     246         378 :         const SwFrmFmts& rTblFmts = *pDoc->GetTblFrmFmts();
     247        1102 :         for( sal_uInt16 n = rTblFmts.size(); n; )
     248         722 :             if( rTblFmts[ --n ]->GetName() == sTblName )
     249             :             {
     250         376 :                 sTblName = pDoc->GetUniqueTblName();
     251         376 :                 break;
     252             :             }
     253             :     }
     254             : 
     255         440 :     SwFrmFmt* pTblFmt = pDoc->MakeTblFrmFmt( sTblName, pDoc->GetDfltFrmFmt() );
     256         440 :     pTblFmt->CopyAttrs( *GetTable().GetFrmFmt() );
     257         440 :     SwTableNode* pTblNd = new SwTableNode( rIdx );
     258         440 :     SwEndNode* pEndNd = new SwEndNode( rIdx, *pTblNd );
     259         880 :     SwNodeIndex aInsPos( *pEndNd );
     260             : 
     261         440 :     SwTable& rTbl = (SwTable&)pTblNd->GetTable();
     262         440 :     rTbl.RegisterToFormat( *pTblFmt );
     263             : 
     264         440 :     rTbl.SetRowsToRepeat( GetTable().GetRowsToRepeat() );
     265         440 :     rTbl.SetTblChgMode( GetTable().GetTblChgMode() );
     266         440 :     rTbl.SetTableModel( GetTable().IsNewModel() );
     267             : 
     268         440 :     SwDDEFieldType* pDDEType = 0;
     269         440 :     if( IS_TYPE( SwDDETable, &GetTable() ))
     270             :     {
     271             :         // We're copying a DDE table
     272             :         // Is the field type available in the new document?
     273           0 :         pDDEType = ((SwDDETable&)GetTable()).GetDDEFldType();
     274           0 :         if( pDDEType->IsDeleted() )
     275           0 :             pDoc->getIDocumentFieldsAccess().InsDeletedFldType( *pDDEType );
     276             :         else
     277           0 :             pDDEType = (SwDDEFieldType*)pDoc->getIDocumentFieldsAccess().InsertFldType( *pDDEType );
     278             :         OSL_ENSURE( pDDEType, "unknown FieldType" );
     279             : 
     280             :         // Swap the table pointers in the node
     281           0 :         SwDDETable* pNewTable = new SwDDETable( pTblNd->GetTable(), pDDEType );
     282           0 :         pTblNd->SetNewTable( pNewTable, false );
     283             :     }
     284             :     // First copy the content of the tables, we will later assign the
     285             :     // boxes/lines and create the frames
     286         880 :     SwNodeRange aRg( *this, +1, *EndOfSectionNode() );
     287             : 
     288             :     // If there is a table in this table, the table format for the outer table
     289             :     // does not seem to be used, because the table does not have any contents yet
     290             :     // (see IsUsed). Therefore the inner table gets the same name as the outer table.
     291             :     // We have to make sure that the table node of the SwTable is accessible, even
     292             :     // without any content in m_TabSortContentBoxes. #i26629#
     293         440 :     pTblNd->GetTable().SetTableNode( pTblNd );
     294         440 :     rNds._Copy( aRg, aInsPos, false );
     295         440 :     pTblNd->GetTable().SetTableNode( 0 );
     296             : 
     297             :     // Special case for a single box
     298         440 :     if( 1 == GetTable().GetTabSortBoxes().size() )
     299             :     {
     300          42 :         aRg.aStart.Assign( *pTblNd, 1 );
     301          42 :         aRg.aEnd.Assign( *pTblNd->EndOfSectionNode() );
     302          42 :         pDoc->GetNodes().SectionDown( &aRg, SwTableBoxStartNode );
     303             :     }
     304             : 
     305             :     // Delete all frames from the copied area, they will be created
     306             :     // during the generation of the table frame
     307         440 :     pTblNd->DelFrms();
     308             : 
     309         880 :     _MapTblFrmFmts aMapArr;
     310         440 :     _CopyTable aPara( pDoc, aMapArr, GetIndex(), *pTblNd, &GetTable() );
     311             : 
     312        1090 :     BOOST_FOREACH(const SwTableLine* pLine, GetTable().GetTabLines() )
     313         650 :         lcl_CopyTblLine( pLine, &aPara );
     314             : 
     315         440 :     if( pDDEType )
     316           0 :         pDDEType->IncRefCnt();
     317             : 
     318             :     CHECK_TABLE( GetTable() );
     319         880 :     return pTblNd;
     320             : }
     321             : 
     322         406 : void SwTxtNode::CopyCollFmt( SwTxtNode& rDestNd )
     323             : {
     324             :     // Copy the formats into the other document:
     325             :     // Special case for PageBreak/PageDesc/ColBrk
     326         406 :     SwDoc* pDestDoc = rDestNd.GetDoc();
     327         406 :     SwAttrSet aPgBrkSet( pDestDoc->GetAttrPool(), aBreakSetRange );
     328             :     const SwAttrSet* pSet;
     329             : 
     330         406 :     if( 0 != ( pSet = rDestNd.GetpSwAttrSet() ) )
     331             :     {
     332             :         // Special cases for Break-Attributes
     333             :         const SfxPoolItem* pAttr;
     334         298 :         if( SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, &pAttr ) )
     335          16 :             aPgBrkSet.Put( *pAttr );
     336             : 
     337         298 :         if( SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, false, &pAttr ) )
     338           0 :             aPgBrkSet.Put( *pAttr );
     339             :     }
     340             : 
     341         406 :     rDestNd.ChgFmtColl( pDestDoc->CopyTxtColl( *GetTxtColl() ));
     342         406 :     if( 0 != ( pSet = GetpSwAttrSet() ) )
     343         298 :         pSet->CopyToModify( rDestNd );
     344             : 
     345         406 :     if( aPgBrkSet.Count() )
     346          16 :         rDestNd.SetAttr( aPgBrkSet );
     347         676 : }
     348             : 
     349             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10