LCOV - code coverage report
Current view: top level - sw/source/core/docnode - ndcopy.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 124 152 81.6 %
Date: 2015-06-13 12:38:46 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 <vector>
      32             : 
      33             : 
      34             : #ifdef DBG_UTIL
      35             : #define CHECK_TABLE(t) (t).CheckConsistency();
      36             : #else
      37             : #define CHECK_TABLE(t)
      38             : #endif
      39             : 
      40             : 
      41             : 
      42             : // Structure for the mapping from old and new frame formats to the
      43             : // boxes and lines of a table
      44             : struct _MapTableFrameFormat
      45             : {
      46             :     const SwFrameFormat *pOld;
      47             :     SwFrameFormat *pNew;
      48        1354 :     _MapTableFrameFormat( const SwFrameFormat *pOldFormat, SwFrameFormat*pNewFormat )
      49        1354 :         : pOld( pOldFormat ), pNew( pNewFormat )
      50        1354 :     {}
      51             : };
      52             : 
      53             : typedef std::vector<_MapTableFrameFormat> _MapTableFrameFormats;
      54             : 
      55        6914 : SwContentNode* SwTextNode::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        6914 :     SwTextNode* pCpyTextNd = const_cast<SwTextNode*>(this);
      62        6914 :     SwTextNode* pCpyAttrNd = pCpyTextNd;
      63             : 
      64             :     // Copy the formats to the other document
      65        6914 :     SwTextFormatColl* pColl = 0;
      66        6914 :     if( pDoc->IsInsOnlyTextGlossary() )
      67             :     {
      68           2 :         SwNodeIndex aIdx( rIdx, -1 );
      69           2 :         if( aIdx.GetNode().IsTextNode() )
      70             :         {
      71           2 :             pCpyAttrNd = aIdx.GetNode().GetTextNode();
      72           2 :             pColl = &pCpyAttrNd->GetTextColl()->GetNextTextFormatColl();
      73           2 :         }
      74             :     }
      75        6914 :     if( !pColl )
      76        6912 :         pColl = pDoc->CopyTextColl( *GetTextColl() );
      77             : 
      78        6914 :     SwTextNode* pTextNd = pDoc->GetNodes().MakeTextNode( rIdx, pColl );
      79             : 
      80             :     // METADATA: register copy
      81        6914 :     pTextNd->RegisterAsCopyOf(*pCpyTextNd);
      82             : 
      83             :     // Copy Attribute/Text
      84        6914 :     if( !pCpyAttrNd->HasSwAttrSet() )
      85             :         // An AttrSet was added for numbering, so delete it
      86        4213 :         pTextNd->ResetAllAttr();
      87             : 
      88             :     // if Copy-Textnode unequal to Copy-Attrnode, then copy first
      89             :     // the attributes into the new Node.
      90        6914 :     if( pCpyAttrNd != pCpyTextNd )
      91             :     {
      92           2 :         pCpyAttrNd->CopyAttr( pTextNd, 0, 0 );
      93           2 :         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( *pTextNd );
      99             :         }
     100             :     }
     101             : 
     102             :     // Is that enough? What about PostIts/Fields/FieldTypes?
     103             :     // #i96213# - force copy of all attributes
     104        6914 :     pCpyTextNd->CopyText( pTextNd, SwIndex( pCpyTextNd ),
     105       13828 :         pCpyTextNd->GetText().getLength(), true );
     106             : 
     107        6914 :     if( RES_CONDTXTFMTCOLL == pColl->Which() )
     108           0 :         pTextNd->ChkCondColl();
     109             : 
     110        6914 :     return pTextNd;
     111             : }
     112             : 
     113        5220 : static bool lcl_SrchNew( const _MapTableFrameFormat& rMap, SwFrameFormat** pPara )
     114             : {
     115        5220 :     if( rMap.pOld != *pPara )
     116        5207 :         return true;
     117          13 :     *pPara = rMap.pNew;
     118          13 :     return false;
     119             : }
     120             : 
     121             : struct _CopyTable
     122             : {
     123             :     SwDoc* m_pDoc;
     124             :     sal_uLong m_nOldTableSttIdx;
     125             :     _MapTableFrameFormats& m_rMapArr;
     126             :     SwTableLine* m_pInsLine;
     127             :     SwTableBox* m_pInsBox;
     128             :     SwTableNode *m_pTableNd;
     129             :     const SwTable *m_pOldTable;
     130             : 
     131         284 :     _CopyTable(SwDoc* pDc, _MapTableFrameFormats& rArr, sal_uLong nOldStt,
     132             :                SwTableNode& rTableNd, const SwTable* pOldTable)
     133             :         : m_pDoc(pDc), m_nOldTableSttIdx(nOldStt), m_rMapArr(rArr),
     134         284 :           m_pInsLine(0), m_pInsBox(0), m_pTableNd(&rTableNd), m_pOldTable(pOldTable)
     135         284 :     {}
     136             : };
     137             : 
     138             : static void lcl_CopyTableLine( const SwTableLine* pLine, _CopyTable* pCT );
     139             : 
     140         979 : static void lcl_CopyTableBox( SwTableBox* pBox, _CopyTable* pCT )
     141             : {
     142         979 :     SwTableBoxFormat * pBoxFormat = static_cast<SwTableBoxFormat*>(pBox->GetFrameFormat());
     143        5272 :     for (_MapTableFrameFormats::const_iterator it = pCT->m_rMapArr.begin(); it != pCT->m_rMapArr.end(); ++it)
     144        4306 :         if ( !lcl_SrchNew( *it, reinterpret_cast<SwFrameFormat**>(&pBoxFormat) ) )
     145          13 :             break;
     146             : 
     147         979 :     if (pBoxFormat == pBox->GetFrameFormat()) // Create a new one?
     148             :     {
     149             :         const SfxPoolItem* pItem;
     150         966 :         if( SfxItemState::SET == pBoxFormat->GetItemState( RES_BOXATR_FORMULA, false,
     151         966 :             &pItem ) && static_cast<const SwTableBoxFormula*>(pItem)->IsIntrnlName() )
     152             :         {
     153           0 :             const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem))->PtrToBoxNm(pCT->m_pOldTable);
     154             :         }
     155             : 
     156         966 :         pBoxFormat = pCT->m_pDoc->MakeTableBoxFormat();
     157         966 :         pBoxFormat->CopyAttrs( *pBox->GetFrameFormat() );
     158             : 
     159         966 :         if( pBox->GetSttIdx() )
     160             :         {
     161         966 :             SvNumberFormatter* pN = pCT->m_pDoc->GetNumberFormatter(false);
     162         966 :             if( pN && pN->HasMergeFormatTable() && SfxItemState::SET == pBoxFormat->
     163           0 :                 GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
     164             :             {
     165           0 :                 sal_uLong nOldIdx = static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue();
     166           0 :                 sal_uLong nNewIdx = pN->GetMergeFormatIndex( nOldIdx );
     167           0 :                 if( nNewIdx != nOldIdx )
     168           0 :                     pBoxFormat->SetFormatAttr( SwTableBoxNumFormat( nNewIdx ));
     169             : 
     170             :             }
     171             :         }
     172             : 
     173         966 :         pCT->m_rMapArr.push_back(_MapTableFrameFormat(pBox->GetFrameFormat(), pBoxFormat));
     174             :     }
     175             : 
     176         979 :     sal_uInt16 nLines = pBox->GetTabLines().size();
     177             :     SwTableBox* pNewBox;
     178         979 :     if( nLines )
     179           0 :         pNewBox = new SwTableBox(pBoxFormat, nLines, pCT->m_pInsLine);
     180             :     else
     181             :     {
     182         979 :         SwNodeIndex aNewIdx(*pCT->m_pTableNd, pBox->GetSttIdx() - pCT->m_nOldTableSttIdx);
     183             :         OSL_ENSURE( aNewIdx.GetNode().IsStartNode(), "Index is not on the start node" );
     184             : 
     185         979 :         pNewBox = new SwTableBox(pBoxFormat, aNewIdx, pCT->m_pInsLine);
     186         979 :         pNewBox->setRowSpan( pBox->getRowSpan() );
     187             :     }
     188             : 
     189         979 :     pCT->m_pInsLine->GetTabBoxes().push_back( pNewBox );
     190             : 
     191         979 :     if (nLines)
     192             :     {
     193           0 :         _CopyTable aPara(*pCT);
     194           0 :         aPara.m_pInsBox = pNewBox;
     195           0 :         for( const SwTableLine* pLine : pBox->GetTabLines() )
     196           0 :             lcl_CopyTableLine( pLine, &aPara );
     197             :     }
     198         979 :     else if (pNewBox->IsInHeadline(&pCT->m_pTableNd->GetTable()))
     199             :     {
     200             :         // In the headline, the paragraphs must match conditional styles
     201         668 :         pNewBox->GetSttNd()->CheckSectionCondColl();
     202             :     }
     203         979 : }
     204             : 
     205         388 : static void lcl_CopyTableLine( const SwTableLine* pLine, _CopyTable* pCT )
     206             : {
     207         388 :     SwTableLineFormat * pLineFormat = static_cast<SwTableLineFormat*>(pLine->GetFrameFormat());
     208        1302 :     for (_MapTableFrameFormats::const_iterator it = pCT->m_rMapArr.begin(); it != pCT->m_rMapArr.end(); ++it)
     209         914 :         if ( !lcl_SrchNew( *it, reinterpret_cast<SwFrameFormat**>(&pLineFormat) ) )
     210           0 :             break;
     211             : 
     212         388 :     if( pLineFormat == pLine->GetFrameFormat() ) // Create a new one?
     213             :     {
     214         388 :         pLineFormat = pCT->m_pDoc->MakeTableLineFormat();
     215         388 :         pLineFormat->CopyAttrs( *pLine->GetFrameFormat() );
     216         388 :         pCT->m_rMapArr.push_back(_MapTableFrameFormat(pLine->GetFrameFormat(), pLineFormat));
     217             :     }
     218             : 
     219         388 :     SwTableLine* pNewLine = new SwTableLine(pLineFormat, pLine->GetTabBoxes().size(), pCT->m_pInsBox);
     220             :     // Insert the new row into the table
     221         388 :     if (pCT->m_pInsBox)
     222             :     {
     223           0 :         pCT->m_pInsBox->GetTabLines().push_back(pNewLine);
     224             :     }
     225             :     else
     226             :     {
     227         388 :         pCT->m_pTableNd->GetTable().GetTabLines().push_back(pNewLine);
     228             :     }
     229             : 
     230         388 :     pCT->m_pInsLine = pNewLine;
     231        4101 :     for( SwTableBoxes::iterator it = const_cast<SwTableLine*>(pLine)->GetTabBoxes().begin();
     232        2734 :              it != const_cast<SwTableLine*>(pLine)->GetTabBoxes().end(); ++it)
     233         979 :         lcl_CopyTableBox(*it, pCT );
     234         388 : }
     235             : 
     236         284 : SwTableNode* SwTableNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
     237             : {
     238             :     // In which array are we? Nodes? UndoNodes?
     239         284 :     SwNodes& rNds = (SwNodes&)GetNodes();
     240             : 
     241             :     {
     242         284 :         if( rIdx < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
     243           0 :             rIdx >= pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() )
     244           0 :             return 0;
     245             :     }
     246             : 
     247             :     // Copy the TableFrameFormat
     248         284 :     OUString sTableName( GetTable().GetFrameFormat()->GetName() );
     249         284 :     if( !pDoc->IsCopyIsMove() )
     250             :     {
     251         252 :         const SwFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
     252         763 :         for( size_t n = rTableFormats.size(); n; )
     253         509 :             if( rTableFormats[ --n ]->GetName() == sTableName )
     254             :             {
     255         250 :                 sTableName = pDoc->GetUniqueTableName();
     256         250 :                 break;
     257             :             }
     258             :     }
     259             : 
     260         284 :     SwFrameFormat* pTableFormat = pDoc->MakeTableFrameFormat( sTableName, pDoc->GetDfltFrameFormat() );
     261         284 :     pTableFormat->CopyAttrs( *GetTable().GetFrameFormat() );
     262         284 :     SwTableNode* pTableNd = new SwTableNode( rIdx );
     263         284 :     SwEndNode* pEndNd = new SwEndNode( rIdx, *pTableNd );
     264         568 :     SwNodeIndex aInsPos( *pEndNd );
     265             : 
     266         284 :     SwTable& rTable = (SwTable&)pTableNd->GetTable();
     267         284 :     rTable.RegisterToFormat( *pTableFormat );
     268             : 
     269         284 :     rTable.SetRowsToRepeat( GetTable().GetRowsToRepeat() );
     270         284 :     rTable.SetTableChgMode( GetTable().GetTableChgMode() );
     271         284 :     rTable.SetTableModel( GetTable().IsNewModel() );
     272             : 
     273         284 :     SwDDEFieldType* pDDEType = 0;
     274         284 :     if( IS_TYPE( SwDDETable, &GetTable() ))
     275             :     {
     276             :         // We're copying a DDE table
     277             :         // Is the field type available in the new document?
     278           0 :         pDDEType = const_cast<SwDDETable&>(static_cast<const SwDDETable&>(GetTable())).GetDDEFieldType();
     279           0 :         if( pDDEType->IsDeleted() )
     280           0 :             pDoc->getIDocumentFieldsAccess().InsDeletedFieldType( *pDDEType );
     281             :         else
     282           0 :             pDDEType = static_cast<SwDDEFieldType*>(pDoc->getIDocumentFieldsAccess().InsertFieldType( *pDDEType ));
     283             :         OSL_ENSURE( pDDEType, "unknown FieldType" );
     284             : 
     285             :         // Swap the table pointers in the node
     286           0 :         SwDDETable* pNewTable = new SwDDETable( pTableNd->GetTable(), pDDEType );
     287           0 :         pTableNd->SetNewTable( pNewTable, false );
     288             :     }
     289             :     // First copy the content of the tables, we will later assign the
     290             :     // boxes/lines and create the frames
     291         568 :     SwNodeRange aRg( *this, +1, *EndOfSectionNode() );
     292             : 
     293             :     // If there is a table in this table, the table format for the outer table
     294             :     // does not seem to be used, because the table does not have any contents yet
     295             :     // (see IsUsed). Therefore the inner table gets the same name as the outer table.
     296             :     // We have to make sure that the table node of the SwTable is accessible, even
     297             :     // without any content in m_TabSortContentBoxes. #i26629#
     298         284 :     pTableNd->GetTable().SetTableNode( pTableNd );
     299         284 :     rNds._Copy( aRg, aInsPos, false );
     300         284 :     pTableNd->GetTable().SetTableNode( 0 );
     301             : 
     302             :     // Special case for a single box
     303         284 :     if( 1 == GetTable().GetTabSortBoxes().size() )
     304             :     {
     305          21 :         aRg.aStart.Assign( *pTableNd, 1 );
     306          21 :         aRg.aEnd.Assign( *pTableNd->EndOfSectionNode() );
     307          21 :         pDoc->GetNodes().SectionDown( &aRg, SwTableBoxStartNode );
     308             :     }
     309             : 
     310             :     // Delete all frames from the copied area, they will be created
     311             :     // during the generation of the table frame
     312         284 :     pTableNd->DelFrms();
     313             : 
     314         568 :     _MapTableFrameFormats aMapArr;
     315         284 :     _CopyTable aPara( pDoc, aMapArr, GetIndex(), *pTableNd, &GetTable() );
     316             : 
     317         672 :     for( const SwTableLine* pLine : GetTable().GetTabLines() )
     318         388 :         lcl_CopyTableLine( pLine, &aPara );
     319             : 
     320         284 :     if( pDDEType )
     321           0 :         pDDEType->IncRefCnt();
     322             : 
     323             :     CHECK_TABLE( GetTable() );
     324         568 :     return pTableNd;
     325             : }
     326             : 
     327         291 : void SwTextNode::CopyCollFormat( SwTextNode& rDestNd )
     328             : {
     329             :     // Copy the formats into the other document:
     330             :     // Special case for PageBreak/PageDesc/ColBrk
     331         291 :     SwDoc* pDestDoc = rDestNd.GetDoc();
     332         291 :     SwAttrSet aPgBrkSet( pDestDoc->GetAttrPool(), aBreakSetRange );
     333             :     const SwAttrSet* pSet;
     334             : 
     335         291 :     if( 0 != ( pSet = rDestNd.GetpSwAttrSet() ) )
     336             :     {
     337             :         // Special cases for Break-Attributes
     338             :         const SfxPoolItem* pAttr;
     339         229 :         if( SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, &pAttr ) )
     340           8 :             aPgBrkSet.Put( *pAttr );
     341             : 
     342         229 :         if( SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, false, &pAttr ) )
     343           0 :             aPgBrkSet.Put( *pAttr );
     344             :     }
     345             : 
     346         291 :     rDestNd.ChgFormatColl( pDestDoc->CopyTextColl( *GetTextColl() ));
     347         291 :     if( 0 != ( pSet = GetpSwAttrSet() ) )
     348         229 :         pSet->CopyToModify( rDestNd );
     349             : 
     350         291 :     if( aPgBrkSet.Count() )
     351           8 :         rDestNd.SetAttr( aPgBrkSet );
     352         468 : }
     353             : 
     354             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11