LCOV - code coverage report
Current view: top level - sw/source/core/doc - docnew.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 408 464 87.9 %
Date: 2015-06-13 12:38:46 Functions: 22 23 95.7 %
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             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include <doc.hxx>
      23             : #include <dcontact.hxx>
      24             : #include <proofreadingiterator.hxx>
      25             : #include <com/sun/star/document/PrinterIndependentLayout.hpp>
      26             : #include <com/sun/star/document/UpdateDocMode.hpp>
      27             : #include <com/sun/star/text/XTextDocument.hpp>
      28             : #include <com/sun/star/text/XFlatParagraphIteratorProvider.hpp>
      29             : 
      30             : #include <comphelper/processfactory.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <vcl/virdev.hxx>
      33             : #include <rtl/random.h>
      34             : #include <sfx2/printer.hxx>
      35             : #include <sfx2/docfile.hxx>
      36             : #include <sfx2/frame.hxx>
      37             : #include <sfx2/viewfrm.hxx>
      38             : 
      39             : #include <svl/macitem.hxx>
      40             : #include <svx/svxids.hrc>
      41             : #include <svx/svdogrp.hxx>
      42             : #include <sfx2/linkmgr.hxx>
      43             : #include <editeng/forbiddencharacterstable.hxx>
      44             : #include <svl/zforlist.hxx>
      45             : #include <unotools/lingucfg.hxx>
      46             : #include <svx/svdpage.hxx>
      47             : #include <paratr.hxx>
      48             : #include <fchrfmt.hxx>
      49             : #include <fmtcntnt.hxx>
      50             : #include <fmtanchr.hxx>
      51             : #include <fmtfsize.hxx>
      52             : #include <fmtfordr.hxx>
      53             : #include <fmtpdsc.hxx>
      54             : #include <pvprtdat.hxx>
      55             : #include <rootfrm.hxx>
      56             : #include <layouter.hxx>
      57             : #include <pagedesc.hxx>
      58             : #include <ndtxt.hxx>
      59             : #include <printdata.hxx>
      60             : #include <docfld.hxx>
      61             : #include <ftninfo.hxx>
      62             : #include <ftnidx.hxx>
      63             : #include <docstat.hxx>
      64             : #include <charfmt.hxx>
      65             : #include <frmfmt.hxx>
      66             : #include <rolbck.hxx>
      67             : #include <poolfmt.hxx>
      68             : #include <dbmgr.hxx>
      69             : #include <docsh.hxx>
      70             : #include <acorrect.hxx>
      71             : #include <visiturl.hxx>
      72             : #include <docary.hxx>
      73             : #include <lineinfo.hxx>
      74             : #include <drawdoc.hxx>
      75             : #include <linkenum.hxx>
      76             : #include <fldupde.hxx>
      77             : #include <extinput.hxx>
      78             : #include <viewsh.hxx>
      79             : #include <doctxm.hxx>
      80             : #include <shellres.hxx>
      81             : #include <breakit.hxx>
      82             : #include <laycache.hxx>
      83             : #include <mvsave.hxx>
      84             : #include <istyleaccess.hxx>
      85             : #include <swstylemanager.hxx>
      86             : #include <IGrammarContact.hxx>
      87             : #include <tblsel.hxx>
      88             : #include <MarkManager.hxx>
      89             : #include <UndoManager.hxx>
      90             : #include <DocumentDeviceManager.hxx>
      91             : #include <DocumentSettingManager.hxx>
      92             : #include <DocumentDrawModelManager.hxx>
      93             : #include <DocumentChartDataProviderManager.hxx>
      94             : #include <DocumentTimerManager.hxx>
      95             : #include <DocumentLinksAdministrationManager.hxx>
      96             : #include <DocumentListItemsManager.hxx>
      97             : #include <DocumentListsManager.hxx>
      98             : #include <DocumentOutlineNodesManager.hxx>
      99             : #include <DocumentContentOperationsManager.hxx>
     100             : #include <DocumentRedlineManager.hxx>
     101             : #include <DocumentFieldsManager.hxx>
     102             : #include <DocumentStatisticsManager.hxx>
     103             : #include <DocumentStateManager.hxx>
     104             : #include <DocumentLayoutManager.hxx>
     105             : #include <DocumentStylePoolManager.hxx>
     106             : #include <DocumentExternalDataManager.hxx>
     107             : #include <unochart.hxx>
     108             : #include <fldbas.hxx>
     109             : #include <wrtsh.hxx>
     110             : #include <unocrsr.hxx>
     111             : 
     112             : #include <cmdid.h>
     113             : 
     114             : #include <pausethreadstarting.hxx>
     115             : #include <numrule.hxx>
     116             : #include <list.hxx>
     117             : 
     118             : #include <sfx2/Metadatable.hxx>
     119             : #include <fmtmeta.hxx>
     120             : 
     121             : //UUUU
     122             : #include <svx/xfillit0.hxx>
     123             : 
     124             : using namespace ::com::sun::star;
     125             : using namespace ::com::sun::star::document;
     126             : 
     127             : const sal_Char sFrameFormatStr[] = "Frameformat";
     128             : const sal_Char sEmptyPageStr[] = "Empty Page";
     129             : const sal_Char sColumnCntStr[] = "Columncontainer";
     130             : const sal_Char sCharFormatStr[] = "Character style";
     131             : const sal_Char sTextCollStr[] = "Paragraph style";
     132             : const sal_Char sGrfCollStr[] = "Graphikformatvorlage";
     133             : 
     134             : /*
     135             :  * global functions...
     136             :  */
     137    26718264 :  uno::Reference< linguistic2::XProofreadingIterator > SwDoc::GetGCIterator() const
     138             : {
     139    26718264 :     if (!m_xGCIterator.is() && SvtLinguConfig().HasGrammarChecker())
     140             :     {
     141           0 :         uno::Reference< uno::XComponentContext >  xContext( comphelper::getProcessComponentContext() );
     142             :         try
     143             :         {
     144           0 :             m_xGCIterator = sw::proofreadingiterator::get( xContext );
     145             :         }
     146           0 :         catch (const uno::Exception &)
     147             :         {
     148             :             OSL_FAIL( "No GCIterator" );
     149           0 :         }
     150             :     }
     151             : 
     152    26718264 :     return m_xGCIterator;
     153             : }
     154             : 
     155    26780438 : void StartGrammarChecking( SwDoc &rDoc )
     156             : {
     157             :     // check for a visible view
     158    26780438 :     bool bVisible = false;
     159    26780438 :     const SwDocShell *mpDocShell = rDoc.GetDocShell();
     160    26780438 :     SfxViewFrame    *pFrame = SfxViewFrame::GetFirst( mpDocShell, false );
     161    80341314 :     while (pFrame && !bVisible)
     162             :     {
     163    26780438 :         if (pFrame->IsVisible())
     164    26718264 :             bVisible = true;
     165    26780438 :         pFrame = SfxViewFrame::GetNext( *pFrame, mpDocShell, false );
     166             :     }
     167             : 
     168             :     //!! only documents with visible views need to be checked
     169             :     //!! (E.g. don't check temporary documents created for printing, see printing of notes and selections.
     170             :     //!! Those get created on the fly and get hard deleted a bit later as well, and no one should have
     171             :     //!! a uno reference to them)
     172    26780438 :     if (bVisible)
     173             :     {
     174    26718264 :         uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( rDoc.GetGCIterator() );
     175    26718264 :         if ( xGCIterator.is() )
     176             :         {
     177           0 :             uno::Reference< lang::XComponent >  xDoc( rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
     178           0 :             uno::Reference< text::XFlatParagraphIteratorProvider >  xFPIP( xDoc, uno::UNO_QUERY );
     179             : 
     180             :             // start automatic background checking if not active already
     181           0 :             if ( xFPIP.is() && !xGCIterator->isProofreading( xDoc ) )
     182           0 :                 xGCIterator->startProofreading( xDoc, xFPIP );
     183    26718264 :         }
     184             :     }
     185    26780438 : }
     186             : 
     187             : /*
     188             :  * internal functions
     189             :  */
     190        8421 : static void lcl_DelFormatIndices( SwFormat* pFormat )
     191             : {
     192        8421 :     SwFormatContent &rFormatContent = (SwFormatContent&)pFormat->GetContent();
     193        8421 :     if ( rFormatContent.GetContentIdx() )
     194        2630 :         rFormatContent.SetNewContentIdx( 0 );
     195        8421 :     SwFormatAnchor &rFormatAnchor = (SwFormatAnchor&)pFormat->GetAnchor();
     196        8421 :     if ( rFormatAnchor.GetContentAnchor() )
     197        3383 :         rFormatAnchor.SetAnchor( 0 );
     198        8421 : }
     199             : 
     200             : /*
     201             :  * exported methods
     202             :  */
     203        2958 : SwDoc::SwDoc()
     204        2958 :     : m_pNodes( new SwNodes(this) ),
     205        2958 :     mpAttrPool(new SwAttrPool(this)),
     206        2958 :     mpMarkManager(new ::sw::mark::MarkManager(*this)),
     207           0 :     m_pMetaFieldManager(new ::sw::MetaFieldManager()),
     208        2958 :     m_pDocumentDrawModelManager( new ::sw::DocumentDrawModelManager( *this ) ),
     209        2958 :     m_pDocumentRedlineManager( new ::sw::DocumentRedlineManager( *this ) ),
     210        2958 :     m_pDocumentStateManager( new ::sw::DocumentStateManager( *this ) ),
     211             :     m_pUndoManager(new ::sw::UndoManager(
     212       14790 :             boost::shared_ptr<SwNodes>(new SwNodes(this)), *m_pDocumentDrawModelManager, *m_pDocumentRedlineManager, *m_pDocumentStateManager)),
     213        2958 :     m_pDocumentSettingManager(new ::sw::DocumentSettingManager(*this)),
     214        2958 :     m_pDocumentChartDataProviderManager( new sw::DocumentChartDataProviderManager( *this ) ),
     215        2958 :     m_pDeviceAccess( new ::sw::DocumentDeviceManager( *this ) ),
     216        2958 :     m_pDocumentTimerManager( new ::sw::DocumentTimerManager( *this ) ),
     217        2958 :     m_pDocumentLinksAdministrationManager( new ::sw::DocumentLinksAdministrationManager( *this ) ),
     218           0 :     m_pDocumentListItemsManager( new ::sw::DocumentListItemsManager() ),
     219        2958 :     m_pDocumentListsManager( new ::sw::DocumentListsManager( *this ) ),
     220        2958 :     m_pDocumentOutlineNodesManager( new ::sw::DocumentOutlineNodesManager( *this ) ),
     221        2958 :     m_pDocumentContentOperationsManager( new ::sw::DocumentContentOperationsManager( *this ) ),
     222        2958 :     m_pDocumentFieldsManager( new ::sw::DocumentFieldsManager( *this ) ),
     223        2958 :     m_pDocumentStatisticsManager( new ::sw::DocumentStatisticsManager( *this ) ),
     224        2958 :     m_pDocumentLayoutManager( new ::sw::DocumentLayoutManager( *this ) ),
     225        2958 :     m_pDocumentStylePoolManager( new ::sw::DocumentStylePoolManager( *this ) ),
     226           0 :     m_pDocumentExternalDataManager( new ::sw::DocumentExternalDataManager() ),
     227        2958 :     mpDfltFrameFormat( new SwFrameFormat( GetAttrPool(), sFrameFormatStr, 0 ) ),
     228        2958 :     mpEmptyPageFormat( new SwFrameFormat( GetAttrPool(), sEmptyPageStr, mpDfltFrameFormat ) ),
     229        2958 :     mpColumnContFormat( new SwFrameFormat( GetAttrPool(), sColumnCntStr, mpDfltFrameFormat ) ),
     230        2958 :     mpDfltCharFormat( new SwCharFormat( GetAttrPool(), sCharFormatStr, 0 ) ),
     231        2958 :     mpDfltTextFormatColl( new SwTextFormatColl( GetAttrPool(), sTextCollStr ) ),
     232        2958 :     mpDfltGrfFormatColl( new SwGrfFormatColl( GetAttrPool(), sGrfCollStr ) ),
     233           0 :     mpFrameFormatTable( new SwFrameFormats() ),
     234           0 :     mpCharFormatTable( new SwCharFormats() ),
     235           0 :     mpSpzFrameFormatTable( new SwFrameFormats() ),
     236           0 :     mpSectionFormatTable( new SwSectionFormats() ),
     237           0 :     mpTableFrameFormatTable( new SwFrameFormats() ),
     238           0 :     mpTextFormatCollTable( new SwTextFormatColls() ),
     239           0 :     mpGrfFormatCollTable( new SwGrfFormatColls() ),
     240           0 :     mpTOXTypes( new SwTOXTypes() ),
     241             :     mpDefTOXBases( new SwDefTOXBase_Impl() ),
     242             :     mpGlossaryDoc( 0 ),
     243             :     mpOutlineRule( 0 ),
     244        2958 :     mpFootnoteInfo( new SwFootnoteInfo ),
     245        2958 :     mpEndNoteInfo( new SwEndNoteInfo ),
     246        2958 :     mpLineNumberInfo( new SwLineNumberInfo ),
     247        2958 :     mpFootnoteIdxs( new SwFootnoteIdxs ),
     248             :     mpDocShell( 0 ),
     249             :     mpACEWord( 0 ),
     250             :     mpURLStateChgd( 0 ),
     251             :     mpNumberFormatter( 0 ),
     252        2958 :     mpNumRuleTable( new SwNumRuleTable ),
     253             :     mpPgPViewPrtData( 0 ),
     254             :     mpExtInputRing( 0 ),
     255             :     mpStyleAccess( 0 ),
     256             :     mpLayoutCache( 0 ),
     257        2958 :     mpGrammarContact(createGrammarContact()),
     258             :     m_pXmlIdRegistry(),
     259             :     mReferenceCount(0),
     260             :     mbGlossDoc(false),
     261             :     mbDtor(false),
     262             :     mbCopyIsMove(false),
     263             :     mbInReading(false),
     264             :     mbInMailMerge(false),
     265             :     mbInXMLImport(false),
     266             :     mbUpdateTOX(false),
     267             :     mbInLoadAsynchron(false),
     268             :     mbIsAutoFormatRedline(false),
     269             :     mbOLEPrtNotifyPending(false),
     270             :     mbAllOLENotify(false),
     271             :     mbInsOnlyTextGlssry(false),
     272             :     mbContains_MSVBasic(false),
     273             :     mbClipBoard( false ),
     274             :     mbColumnSelection( false ),
     275             :     mbIsPrepareSelAll(false),
     276             : #ifdef DBG_UTIL
     277             :     mbXMLExport(false),
     278             : #endif
     279             :     mbContainsAtPageObjWithContentAnchor(false), //#i119292#, fdo#37024
     280             : 
     281             :     mbReadOnly(false),
     282      106488 :     meDocType(DOCTYPE_NATIVE)
     283             : {
     284             :     //UUUU The DrawingLayer ItemPool which is used as 2nd pool for Writer documents' pool
     285             :     // has a default for the XFillStyleItem of XFILL_SOLID and the color for it is the default
     286             :     // fill color (blue7 or similar). This is a problem, in Writer we want the default fill
     287             :     // style to be drawing::FillStyle_NONE. This cannot simply be done by changing it in the 2nd pool at the
     288             :     // pool defaults when the DrawingLayer ItemPool is used for Writer, that would lead to
     289             :     // countless problems like DrawObjects initial fill and others.
     290             :     // It is also hard to find all places where the initial ItemSets for Writer (including
     291             :     // style hierarchies) are created and to always set (but only at the root) the FillStyle
     292             :     // to NONE fixed; that will add that attribute to the file format. It will be hard to reset
     293             :     // attribbute sets (which is done at import and using UI). Also not a good solution.
     294             :     // Luckily Writer uses pDfltTextFormatColl as default parent for all paragraphs and similar, thus
     295             :     // it is possible to set this attribute here. It will be not reset when importing.
     296        2958 :     mpDfltTextFormatColl->SetFormatAttr(XFillStyleItem(drawing::FillStyle_NONE));
     297        2958 :     mpDfltFrameFormat->SetFormatAttr(XFillStyleItem(drawing::FillStyle_NONE));
     298             : 
     299             :     /*
     300             :      * DefaultFormats and DefaultFormatCollections (FormatColl)
     301             :      * are inserted at position 0 at the respective array.
     302             :      * The formats in the FormatColls are derived from the
     303             :      * DefaultFormats and are also in the list.
     304             :      */
     305             :     /* Formats */
     306        2958 :     mpFrameFormatTable->push_back(mpDfltFrameFormat);
     307        2958 :     mpCharFormatTable->push_back(mpDfltCharFormat);
     308             : 
     309             :     /* FormatColls */
     310             :     // TXT
     311        2958 :     mpTextFormatCollTable->push_back(mpDfltTextFormatColl);
     312             :     // GRF
     313        2958 :     mpGrfFormatCollTable->push_back(mpDfltGrfFormatColl);
     314             : 
     315             :     // Create PageDesc, EmptyPageFormat and ColumnFormat
     316        2958 :     if ( maPageDescs.empty() )
     317        2958 :         getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD );
     318             : 
     319             :     // Set to "Empty Page"
     320        2958 :     mpEmptyPageFormat->SetFormatAttr( SwFormatFrmSize( ATT_FIX_SIZE ) );
     321             :     // Set BodyFormat for columns
     322        2958 :     mpColumnContFormat->SetFormatAttr( SwFormatFillOrder( ATT_LEFT_TO_RIGHT ) );
     323             : 
     324        2958 :     GetDocumentFieldsManager()._InitFieldTypes();
     325             : 
     326             :     // Create a default OutlineNumRule (for Filters)
     327             :     mpOutlineRule = new SwNumRule( SwNumRule::GetOutlineRuleName(),
     328             :                                   // #i89178#
     329             :                                   numfunc::GetDefaultPositionAndSpaceMode(),
     330        2958 :                                   OUTLINE_RULE );
     331        2958 :     AddNumRule(mpOutlineRule);
     332             :     // Counting of phantoms depends on <IsOldNumbering()>
     333        2958 :     mpOutlineRule->SetCountPhantoms( !GetDocumentSettingManager().get(DocumentSettingId::OLD_NUMBERING) );
     334             : 
     335             :     new SwTextNode(
     336        2958 :             SwNodeIndex(GetUndoManager().GetUndoNodes().GetEndOfContent()),
     337        2958 :             mpDfltTextFormatColl );
     338        2958 :     new SwTextNode( SwNodeIndex( GetNodes().GetEndOfContent() ),
     339        2958 :                     getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ));
     340             : 
     341        2958 :     maOLEModifiedIdle.SetPriority( SchedulerPriority::LOWEST );
     342        2958 :     maOLEModifiedIdle.SetIdleHdl( LINK( this, SwDoc, DoUpdateModifiedOLE ));
     343             : 
     344             : #if HAVE_FEATURE_DBCONNECTIVITY
     345             :     // Create DBManager
     346        2958 :     mpDBManager = new SwDBManager(this);
     347             : #endif
     348             : 
     349             :     // create TOXTypes
     350        2958 :     InitTOXTypes();
     351             : 
     352             :     // pass empty item set containing the paragraph's list attributes
     353             :     // as ignorable items to the stype manager.
     354             :     {
     355        2958 :         SfxItemSet aIgnorableParagraphItems( GetAttrPool(), RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1);
     356        2958 :         mpStyleAccess = createStyleManager( &aIgnorableParagraphItems );
     357             :     }
     358             : 
     359        2958 :     static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
     360             : 
     361        2958 :     if (bHack)
     362             :     {
     363           0 :         mnRsid = 0;
     364             :     }
     365             :     else
     366             :     {
     367             :         // Initialize the session id of the current document to a random number
     368             :         // smaller than 2^21.
     369        2958 :         static rtlRandomPool aPool = rtl_random_createPool();
     370        2958 :         rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) );
     371        2958 :         mnRsid &= ( 1<<21 ) - 1;
     372        2958 :         mnRsid++;
     373             :     }
     374        2958 :     mnRsidRoot = mnRsid;
     375             : 
     376        2958 :     getIDocumentState().ResetModified();
     377        2958 : }
     378             : 
     379             : /**
     380             :  * Speciality: a member of the class SwDoc is located at
     381             :  * position 0 in the array of the Format and GDI objects.
     382             :  * This MUST not be destroyed using 'delete' in any case!
     383             :  */
     384        8846 : SwDoc::~SwDoc()
     385             : {
     386             :     // nothing here should create Undo actions!
     387        2949 :     GetIDocumentUndoRedo().DoUndo(false);
     388             : 
     389        2949 :     if (mpDocShell)
     390             :     {
     391           0 :         mpDocShell->SetUndoManager(0);
     392             :     }
     393             : 
     394        2949 :     delete mpGrammarContact;
     395        2949 :     mpGrammarContact = 0;
     396             : 
     397             :     //!! needs to be done to destroy a possible SwFormatDrop format that may
     398             :     //!! be connected to a char format which may not otherwise be removed
     399             :     //!! and thus would leave a unremoved SwFormat object. (TL)
     400             :     //!! (this is case is not possible via UI but via API...)
     401        2949 :     SwFormatDrop aDrop;
     402        2949 :     SetDefault(aDrop);
     403             :     //!! same for SwFormatCharFormat
     404        5898 :     SwFormatCharFormat aCharFormat(NULL);
     405        2949 :     SetDefault(aCharFormat);
     406             : 
     407        2949 :     getIDocumentTimerAccess().StopIdling();   // stop idle timer
     408             : 
     409        2949 :     delete mpURLStateChgd;
     410             : 
     411             :     // Deactivate Undo notification from Draw
     412        2949 :     if( GetDocumentDrawModelManager().GetDrawModel() )
     413             :     {
     414        2949 :         GetDocumentDrawModelManager().DrawNotifyUndoHdl();
     415        2949 :         ClrContourCache();
     416             :     }
     417             : 
     418        2949 :     delete mpPgPViewPrtData;
     419             : 
     420        2949 :     mbDtor = true;
     421             : 
     422             :     //Clear the redline table before the nodes array is destroyed
     423        2949 :     getIDocumentRedlineAccess().GetRedlineTable().DeleteAndDestroyAll();
     424        2949 :     getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteAndDestroyAll();
     425             : 
     426        5898 :     const sw::DocDisposingHint aHint;
     427        5898 :     std::vector< std::weak_ptr<SwUnoCrsr> > vCursorsToKill(mvUnoCrsrTbl.begin(), mvUnoCrsrTbl.end());
     428      216143 :     for(auto& pWeakCursor : vCursorsToKill)
     429             :     {
     430      213194 :         auto pCursor(pWeakCursor.lock());
     431      213194 :         if(pCursor)
     432        3408 :             pCursor->CallSwClientNotify(aHint);
     433      213194 :     }
     434        2949 :     delete mpACEWord;
     435             : 
     436             :     // Release the BaseLinks
     437             :     {
     438        2949 :        ::sfx2::SvLinkSources aTemp(getIDocumentLinksAdministration().GetLinkManager().GetServers());
     439        8850 :        for( ::sfx2::SvLinkSources::const_iterator it = aTemp.begin();
     440        5900 :             it != aTemp.end(); ++it )
     441           1 :             (*it)->Closed();
     442             : 
     443        2949 :         if( !getIDocumentLinksAdministration().GetLinkManager().GetLinks().empty() )
     444          13 :             getIDocumentLinksAdministration().GetLinkManager().Remove( 0, getIDocumentLinksAdministration().GetLinkManager().GetLinks().size() );
     445             :     }
     446             : 
     447             :     // The ChapterNumbers/Numbers need to be deleted before the styles
     448             :     // or we update all the time!
     449        2949 :     m_pNodes->pOutlineNds->clear();
     450        2949 :     SwNodes & rUndoNodes( GetUndoManager().GetUndoNodes() );
     451        2949 :     rUndoNodes.pOutlineNds->clear();
     452             : 
     453        2949 :     mpFootnoteIdxs->clear();
     454             : 
     455             :     // indices could be registered in attributes
     456        2949 :     m_pUndoManager->DelAllUndoObj();
     457             : 
     458             :     // The BookMarks contain indices to the Content. These must be deleted
     459             :     // before deleting the Nodes.
     460        2949 :     mpMarkManager->clearAllMarks();
     461             : 
     462        2949 :     if( mpExtInputRing )
     463             :     {
     464           0 :         SwPaM* pTmp = mpExtInputRing;
     465           0 :         mpExtInputRing = 0;
     466           0 :         while( pTmp->GetNext() != pTmp )
     467           0 :             delete pTmp->GetNext();
     468           0 :         delete pTmp;
     469             :     }
     470             : 
     471             :     // Old - deletion without a Flag is expensive, because we send a Modify
     472             :     // aTOXTypes.DeleteAndDestroy( 0, aTOXTypes.Count() );
     473             :     {
     474       29658 :         for( auto n = mpTOXTypes->size(); n; )
     475             :         {
     476       23760 :             (*mpTOXTypes)[ --n ]->SetInDocDTOR();
     477       23760 :             delete (*mpTOXTypes)[ n ];
     478             :         }
     479        2949 :         mpTOXTypes->clear();
     480             :     }
     481        2949 :     delete mpDefTOXBases;
     482             : 
     483             :     // Any of the FrmFormats can still have indices registered.
     484             :     // These need to be destroyed now at the latest.
     485        7509 :     for( SwFrameFormat* pFormat : *mpFrameFormatTable )
     486        4560 :         lcl_DelFormatIndices( pFormat );
     487        6474 :     for( SwFrameFormat* pFormat : *mpSpzFrameFormatTable )
     488        3525 :         lcl_DelFormatIndices( pFormat );
     489        3285 :     for( SwSectionFormat* pFormat : *mpSectionFormatTable )
     490         336 :         lcl_DelFormatIndices( pFormat );
     491             : 
     492             :     // The formats/styles that follow depend on the default formats.
     493             :     // Destroy these only after destroying the FormatIndices, because the content
     494             :     // of headers/footers has to be deleted as well. If in the headers/footers
     495             :     // there are still Flys registered at that point, we have a problem.
     496        2949 :     maPageDescs.clear();
     497             : 
     498             :     // Delete content selections.
     499             :     // Don't wait for the SwNodes dtor to destroy them; so that Formats
     500             :     // do not have any dependencies anymore.
     501        2949 :     m_pNodes->DelNodes( SwNodeIndex(*m_pNodes), m_pNodes->Count() );
     502        2949 :     rUndoNodes.DelNodes( SwNodeIndex( rUndoNodes ), rUndoNodes.Count() );
     503             : 
     504             :     // Delete Formats, make it permanent some time in the future
     505             : 
     506             :     // Delete for Collections
     507             :     // So that we get rid of the dependencies
     508        2949 :     mpFootnoteInfo->ReleaseCollection();
     509        2949 :     mpEndNoteInfo->ReleaseCollection();
     510             : 
     511             :     OSL_ENSURE( mpDfltTextFormatColl == (*mpTextFormatCollTable)[0],
     512             :             "Default-Text-Collection must always be at the start" );
     513             : 
     514             :     // Optimization: Based on the fact that Standard is always 2nd in the
     515             :     // array, we should delete it as the last. With this we avoid
     516             :     // reparenting the Formats all the time!
     517        2949 :     if( 2 < mpTextFormatCollTable->size() )
     518        2935 :         mpTextFormatCollTable->DeleteAndDestroy(2, mpTextFormatCollTable->size());
     519        2949 :     mpTextFormatCollTable->DeleteAndDestroy(1, mpTextFormatCollTable->size());
     520        2949 :     delete mpTextFormatCollTable;
     521             : 
     522             :     OSL_ENSURE( mpDfltGrfFormatColl == (*mpGrfFormatCollTable)[0],
     523             :             "DefaultGrfCollection must always be at the start" );
     524             : 
     525        2949 :     mpGrfFormatCollTable->DeleteAndDestroy(1, mpGrfFormatCollTable->size());
     526        2949 :     delete mpGrfFormatCollTable;
     527             : 
     528             :     // Without explicitly freeing the DocumentDeviceManager
     529             :     // and relying on the implicit freeing there would be a crash
     530             :     // due to it happening after SwAttrPool is freed.
     531        2949 :     m_pDeviceAccess.reset();
     532             : 
     533             :     /*
     534             :      * DefaultFormats and DefaultFormatCollections (FormatColl)
     535             :      * are at position 0 of their respective arrays.
     536             :      * In order to not be deleted by the array's dtor, we remove them
     537             :      * now.
     538             :      */
     539        2949 :     mpFrameFormatTable->erase( mpFrameFormatTable->begin() );
     540        2949 :     mpCharFormatTable->erase( mpCharFormatTable->begin() );
     541             : 
     542             : #if HAVE_FEATURE_DBCONNECTIVITY
     543             :     // On load, SwDBManager::setEmbeddedName() may register a data source.
     544             :     // If we have an embedded one, then sDataSoure points to the registered name, so revoke it here.
     545        2949 :     if (!mpDBManager->getEmbeddedName().isEmpty() && !maDBData.sDataSource.isEmpty())
     546             :     {
     547             :         // Remove the revoke listener here first, so that we don't remove the data source from the document.
     548           2 :         mpDBManager->releaseRevokeListener();
     549           2 :         SwDBManager::RevokeDataSource(maDBData.sDataSource);
     550             :     }
     551             : 
     552        2949 :     DELETEZ( mpDBManager );
     553             : #endif
     554             : 
     555             :     // All Flys need to be destroyed before the Drawing Model,
     556             :     // because Flys can still contain DrawContacts, when no
     557             :     // Layout could be constructed due to a read error.
     558        2949 :     mpSpzFrameFormatTable->DeleteAndDestroy( 0, mpSpzFrameFormatTable->size() );
     559             : 
     560             :     // Only now destroy the Model, the drawing objects - which are also
     561             :     // contained in the Undo - need to remove their attributes from the
     562             :     // Model. Also, DrawContacts could exist before this.
     563        2949 :     GetDocumentDrawModelManager().ReleaseDrawModel();
     564             :     // Destroy DrawModel before the LinkManager, because it's always set
     565             :     // in the DrawModel.
     566             :     //The LinkManager gets destroyed automatically with m_pLinksAdministrationManager
     567             : 
     568             :     // Clear the Tables before deleting the defaults, or we crash due to
     569             :     // dependencies on defaults.
     570        2949 :     delete mpFrameFormatTable;
     571        2949 :     delete mpSpzFrameFormatTable;
     572             : 
     573        2949 :     delete mpStyleAccess;
     574             : 
     575        2949 :     delete mpCharFormatTable;
     576        2949 :     delete mpSectionFormatTable;
     577        2949 :     delete mpTableFrameFormatTable;
     578        2949 :     delete mpDfltTextFormatColl;
     579        2949 :     delete mpDfltGrfFormatColl;
     580        2949 :     delete mpNumRuleTable;
     581             : 
     582        2949 :     disposeXForms(); // #i113606#, dispose the XForms objects
     583             : 
     584        2949 :     delete mpNumberFormatter;
     585        2949 :     delete mpFootnoteInfo;
     586        2949 :     delete mpEndNoteInfo;
     587        2949 :     delete mpLineNumberInfo;
     588        2949 :     delete mpFootnoteIdxs;
     589        2949 :     delete mpTOXTypes;
     590        2949 :     delete mpEmptyPageFormat;
     591        2949 :     delete mpColumnContFormat;
     592        2949 :     delete mpDfltCharFormat;
     593        2949 :     delete mpDfltFrameFormat;
     594        2949 :     delete mpLayoutCache;
     595             : 
     596        5898 :     SfxItemPool::Free(mpAttrPool);
     597        5897 : }
     598             : 
     599        6117 : void SwDoc::SetDocShell( SwDocShell* pDSh )
     600             : {
     601        6117 :     if( mpDocShell != pDSh )
     602             :     {
     603        6117 :         if (mpDocShell)
     604             :         {
     605        3056 :             mpDocShell->SetUndoManager(0);
     606             :         }
     607        6117 :         mpDocShell = pDSh;
     608        6117 :         if (mpDocShell)
     609             :         {
     610        3061 :             mpDocShell->SetUndoManager(& GetUndoManager());
     611             :         }
     612             : 
     613        6117 :         getIDocumentLinksAdministration().GetLinkManager().SetPersist( mpDocShell );
     614             : 
     615             :         // set DocShell pointer also on DrawModel
     616        6117 :         InitDrawModelAndDocShell(mpDocShell, GetDocumentDrawModelManager().GetDrawModel());
     617             :         OSL_ENSURE(!GetDocumentDrawModelManager().GetDrawModel() ||
     618             :             GetDocumentDrawModelManager().GetDrawModel()->GetPersist() == GetPersist(),
     619             :             "draw model's persist is out of sync");
     620             :     }
     621        6117 : }
     622             : 
     623             : // Convenience method; to avoid excessive includes from docsh.hxx
     624          69 : uno::Reference < embed::XStorage > SwDoc::GetDocStorage()
     625             : {
     626          69 :     if( mpDocShell )
     627          69 :         return mpDocShell->GetStorage();
     628           0 :     if( getIDocumentLinksAdministration().GetLinkManager().GetPersist() )
     629           0 :         return getIDocumentLinksAdministration().GetLinkManager().GetPersist()->GetStorage();
     630           0 :     return NULL;
     631             : }
     632             : 
     633        3045 : SfxObjectShell* SwDoc::GetPersist() const
     634             : {
     635        3045 :     return mpDocShell ? mpDocShell : getIDocumentLinksAdministration().GetLinkManager().GetPersist();
     636             : }
     637             : 
     638          21 : void SwDoc::ClearDoc()
     639             : {
     640          21 :     GetIDocumentUndoRedo().DelAllUndoObj();
     641          21 :     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
     642             : 
     643             :     // Deactivate Undo notification from Draw
     644          21 :     if( GetDocumentDrawModelManager().GetDrawModel() )
     645             :     {
     646          21 :         GetDocumentDrawModelManager().DrawNotifyUndoHdl();
     647          21 :         ClrContourCache();
     648             :     }
     649             : 
     650             :     // if there are still FlyFrames dangling around, delete them too
     651          42 :     while ( !mpSpzFrameFormatTable->empty() )
     652           0 :         getIDocumentLayoutAccess().DelLayoutFormat((*mpSpzFrameFormatTable)[mpSpzFrameFormatTable->size()-1]);
     653             :     OSL_ENSURE( !GetDocumentDrawModelManager().GetDrawModel() || !GetDocumentDrawModelManager().GetDrawModel()->GetPage(0)->GetObjCount(),
     654             :                 "not all DrawObjects removed from the page" );
     655             : 
     656          21 :     getIDocumentRedlineAccess().GetRedlineTable().DeleteAndDestroyAll();
     657          21 :     getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteAndDestroyAll();
     658             : 
     659          21 :     delete mpACEWord;
     660             : 
     661             :     // The BookMarks contain indices to the Content. These must be deleted
     662             :     // before deleting the Nodes.
     663          21 :     mpMarkManager->clearAllMarks();
     664          21 :     InitTOXTypes();
     665             : 
     666             :     // create a dummy pagedesc for the layout
     667          21 :     SwPageDesc* pDummyPgDsc = MakePageDesc("?DUMMY?");
     668             : 
     669          42 :     SwNodeIndex aSttIdx( *GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
     670             :     // create the first one over and over again (without attributes/style etc.
     671          21 :     SwTextNode* pFirstNd = GetNodes().MakeTextNode( aSttIdx, mpDfltTextFormatColl );
     672             : 
     673          21 :     if( getIDocumentLayoutAccess().GetCurrentViewShell() )
     674             :     {
     675             :         // set the layout to the dummy pagedesc
     676           0 :         pFirstNd->SetAttr( SwFormatPageDesc( pDummyPgDsc ));
     677             : 
     678           0 :         SwPosition aPos( *pFirstNd, SwIndex( pFirstNd ));
     679           0 :         SwPaM const tmpPaM(aSttIdx, SwNodeIndex(GetNodes().GetEndOfContent()));
     680           0 :         ::PaMCorrAbs(tmpPaM, aPos);
     681             :     }
     682             : 
     683          21 :     GetNodes().Delete( aSttIdx,
     684          42 :             GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
     685             : 
     686             :     // #i62440#
     687             :     // destruction of numbering rules and creation of new outline rule
     688             :     // *after* the document nodes are deleted.
     689          21 :     mpOutlineRule = NULL;
     690          42 :     for( SwNumRule* pNumRule : *mpNumRuleTable )
     691          21 :         delete pNumRule;
     692          21 :     mpNumRuleTable->clear();
     693             : 
     694             :     // creation of new outline numbering rule
     695             :     mpOutlineRule = new SwNumRule( SwNumRule::GetOutlineRuleName(),
     696             :                                   // #i89178#
     697             :                                   numfunc::GetDefaultPositionAndSpaceMode(),
     698          21 :                                   OUTLINE_RULE );
     699          21 :     AddNumRule(mpOutlineRule);
     700             :     // Counting of phantoms depends on <IsOldNumbering()>
     701          21 :     mpOutlineRule->SetCountPhantoms( !GetDocumentSettingManager().get(DocumentSettingId::OLD_NUMBERING) );
     702             : 
     703             :     // remove the dummy pagedesc from the array and delete all the old ones
     704          21 :     size_t nDummyPgDsc = 0;
     705          21 :     if (FindPageDesc(pDummyPgDsc->GetName(), &nDummyPgDsc))
     706          21 :         pDummyPgDsc = maPageDescs.release(maPageDescs.begin() + nDummyPgDsc).release();
     707          21 :     maPageDescs.clear();
     708             : 
     709             :     // Delete for Collections
     710             :     // So that we get rid of the dependencies
     711          21 :     mpFootnoteInfo->ReleaseCollection();
     712          21 :     mpEndNoteInfo->ReleaseCollection();
     713             : 
     714             :     // Optimization: Based on the fact that Standard is always 2nd in the
     715             :     // array, we should delete it as the last. With this we avoid
     716             :     // reparenting the Formats all the time!
     717          21 :     if( 2 < mpTextFormatCollTable->size() )
     718          14 :         mpTextFormatCollTable->DeleteAndDestroy(2, mpTextFormatCollTable->size());
     719          21 :     mpTextFormatCollTable->DeleteAndDestroy(1, mpTextFormatCollTable->size());
     720          21 :     mpGrfFormatCollTable->DeleteAndDestroy(1, mpGrfFormatCollTable->size());
     721          21 :     mpCharFormatTable->DeleteAndDestroy(1, mpCharFormatTable->size());
     722             : 
     723          21 :     if( getIDocumentLayoutAccess().GetCurrentViewShell() )
     724             :     {
     725             :         // search the FrameFormat of the root frm. This is not allowed to delete
     726           0 :         mpFrameFormatTable->erase( std::find( mpFrameFormatTable->begin(), mpFrameFormatTable->end(), getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFormat() ) );
     727           0 :         mpFrameFormatTable->DeleteAndDestroy(1, mpFrameFormatTable->size());
     728           0 :         mpFrameFormatTable->push_back( getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFormat() );
     729             :     }
     730             :     else
     731          21 :         mpFrameFormatTable->DeleteAndDestroy(1, mpFrameFormatTable->size());
     732             : 
     733          21 :     mxForbiddenCharsTable.clear();
     734             : 
     735          21 :     GetDocumentFieldsManager().ClearFieldTypes();
     736             : 
     737          21 :     delete mpNumberFormatter, mpNumberFormatter = 0;
     738             : 
     739          21 :     getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD );
     740          21 :     pFirstNd->ChgFormatColl( getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ));
     741          21 :     nDummyPgDsc = maPageDescs.size();
     742          21 :     maPageDescs.push_back( pDummyPgDsc );
     743             :     // set the layout back to the new standard pagedesc
     744          21 :     pFirstNd->ResetAllAttr();
     745             :     // delete now the dummy pagedesc
     746          42 :     DelPageDesc( nDummyPgDsc );
     747          21 : }
     748             : 
     749           0 : void SwDoc::SetPreviewPrtData( const SwPagePreviewPrtData* pNew )
     750             : {
     751           0 :     if( pNew )
     752             :     {
     753           0 :         if( mpPgPViewPrtData )
     754           0 :             *mpPgPViewPrtData = *pNew;
     755             :         else
     756           0 :             mpPgPViewPrtData = new SwPagePreviewPrtData( *pNew );
     757             :     }
     758           0 :     else if( mpPgPViewPrtData )
     759           0 :         DELETEZ( mpPgPViewPrtData );
     760           0 :     getIDocumentState().SetModified();
     761           0 : }
     762             : 
     763         262 : void SwDoc::SetOLEObjModified()
     764             : {
     765         262 :     if( getIDocumentLayoutAccess().GetCurrentViewShell() ) maOLEModifiedIdle.Start();
     766         262 : }
     767             : 
     768             : /** SwDoc: Reading and writing of the layout cache. */
     769          41 : void SwDoc::ReadLayoutCache( SvStream& rStream )
     770             : {
     771          41 :     if( !mpLayoutCache )
     772          41 :         mpLayoutCache = new SwLayoutCache();
     773          41 :     if( !mpLayoutCache->IsLocked() )
     774             :     {
     775          41 :         mpLayoutCache->GetLockCount() |= 0x8000;
     776          41 :         mpLayoutCache->Read( rStream );
     777          41 :         mpLayoutCache->GetLockCount() &= 0x7fff;
     778             :     }
     779          41 : }
     780             : 
     781          15 : void SwDoc::WriteLayoutCache( SvStream& rStream )
     782             : {
     783          15 :     SwLayoutCache::Write( rStream, *this );
     784          15 : }
     785             : 
     786       12239 : IGrammarContact* getGrammarContact( const SwTextNode& rTextNode )
     787             : {
     788       12239 :     const SwDoc* pDoc = rTextNode.GetDoc();
     789       12239 :     if( !pDoc || pDoc->IsInDtor() )
     790           0 :         return 0;
     791       12239 :     return pDoc->getGrammarContact();
     792             : }
     793             : 
     794             : ::sfx2::IXmlIdRegistry&
     795         171 : SwDoc::GetXmlIdRegistry()
     796             : {
     797             :     // UGLY: this relies on SetClipBoard being called before GetXmlIdRegistry!
     798         171 :     if (!m_pXmlIdRegistry.get())
     799             :     {
     800          34 :         m_pXmlIdRegistry.reset( ::sfx2::createXmlIdRegistry( IsClipBoard() ) );
     801             :     }
     802         171 :     return *m_pXmlIdRegistry;
     803             : }
     804             : 
     805        2979 : void SwDoc::InitTOXTypes()
     806             : {
     807        2979 :     ShellResource* pShellRes = SwViewShell::GetShellRes();
     808        2979 :     SwTOXType * pNew = new SwTOXType(TOX_CONTENT,   pShellRes->aTOXContentName        );
     809        2979 :     mpTOXTypes->push_back( pNew );
     810        2979 :     pNew = new SwTOXType(TOX_INDEX,                 pShellRes->aTOXIndexName  );
     811        2979 :     mpTOXTypes->push_back( pNew );
     812        2979 :     pNew = new SwTOXType(TOX_USER,                  pShellRes->aTOXUserName  );
     813        2979 :     mpTOXTypes->push_back( pNew );
     814        2979 :     pNew = new SwTOXType(TOX_ILLUSTRATIONS,         pShellRes->aTOXIllustrationsName );
     815        2979 :     mpTOXTypes->push_back( pNew );
     816        2979 :     pNew = new SwTOXType(TOX_OBJECTS,               pShellRes->aTOXObjectsName       );
     817        2979 :     mpTOXTypes->push_back( pNew );
     818        2979 :     pNew = new SwTOXType(TOX_TABLES,                pShellRes->aTOXTablesName        );
     819        2979 :     mpTOXTypes->push_back( pNew );
     820        2979 :     pNew = new SwTOXType(TOX_AUTHORITIES,           pShellRes->aTOXAuthoritiesName   );
     821        2979 :     mpTOXTypes->push_back( pNew );
     822        2979 :     pNew = new SwTOXType(TOX_CITATION,           pShellRes->aTOXCitationName   );
     823        2979 :     mpTOXTypes->push_back( pNew );
     824        2979 : }
     825             : 
     826          53 : void SwDoc::ReplaceDefaults(const SwDoc& rSource)
     827             : {
     828             :     // copy property defaults
     829             :     const sal_uInt16 aRangeOfDefaults[] =
     830             :     {
     831             :         RES_FRMATR_BEGIN, RES_FRMATR_END-1,
     832             :         RES_CHRATR_BEGIN, RES_CHRATR_END-1,
     833             :         RES_PARATR_BEGIN, RES_PARATR_END-1,
     834             :         RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
     835             :         RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
     836             :         XATTR_START, XATTR_END-1,
     837             :         0
     838          53 :     };
     839             : 
     840          53 :     SfxItemSet aNewDefaults(GetAttrPool(), aRangeOfDefaults);
     841             : 
     842         371 :     for (auto nRange = 0; aRangeOfDefaults[nRange] != 0; nRange += 2)
     843             :     {
     844       17490 :         for (sal_uInt16 nWhich = aRangeOfDefaults[nRange];
     845        8745 :              nWhich <= aRangeOfDefaults[nRange + 1]; ++nWhich)
     846             :         {
     847             :             const SfxPoolItem& rSourceAttr =
     848        8427 :                 rSource.mpAttrPool->GetDefaultItem(nWhich);
     849        8427 :             if (rSourceAttr != mpAttrPool->GetDefaultItem(nWhich))
     850         337 :                 aNewDefaults.Put(rSourceAttr);
     851             :         }
     852             :     }
     853             : 
     854          53 :     if (aNewDefaults.Count())
     855          53 :         SetDefault(aNewDefaults);
     856          53 : }
     857             : 
     858          53 : void SwDoc::ReplaceCompatibilityOptions(const SwDoc& rSource)
     859             : {
     860          53 :     m_pDocumentSettingManager->ReplaceCompatibilityOptions(rSource.GetDocumentSettingManager());
     861          53 : }
     862             : 
     863             : #ifdef DBG_UTIL
     864             : #define CNTNT_DOC( doc ) \
     865             :     ((doc)->GetNodes().GetEndOfContent().GetIndex() - (doc)->GetNodes().GetEndOfExtras().GetIndex() - 2)
     866             : #define CNTNT_IDX( idx ) \
     867             :     ((idx).GetNode().GetIndex() - GetNodes().GetEndOfExtras().GetIndex() - 1)
     868             : #endif
     869             : 
     870          47 : SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
     871             : {
     872          47 :     SwDoc* pRet = new SwDoc;
     873             : 
     874             :     // we have to use pointer here, since the callee has to decide whether
     875             :     // SfxObjectShellLock or SfxObjectShellRef should be used sometimes the
     876             :     // object will be returned with refcount set to 0 ( if no DoInitNew is done )
     877          47 :     SfxObjectShell* pRetShell = new SwDocShell( pRet, SfxObjectCreateMode::STANDARD );
     878          47 :     if( bCallInitNew )
     879             :     {
     880             :         // it could happen that DoInitNew creates model,
     881             :         // that increases the refcount of the object
     882          47 :         pRetShell->DoInitNew();
     883             :     }
     884             : 
     885          47 :     (void)pRet->acquire();
     886             : 
     887          47 :     pRet->ReplaceDefaults(*this);
     888             : 
     889          47 :     pRet->ReplaceCompatibilityOptions(*this);
     890             : 
     891          47 :     pRet->ReplaceStyles(*this);
     892             : 
     893             : #ifdef DBG_UTIL
     894             :     SAL_INFO( "sw.createcopy", "CC-Nd-Src: " << CNTNT_DOC( this ) );
     895             :     SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
     896             : #endif
     897          47 :     pRet->AppendDoc(*this, 0, NULL, bCallInitNew);
     898             : #ifdef DBG_UTIL
     899             :     SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
     900             : #endif
     901             : 
     902             :     // remove the temporary shell if it is there as it was done before
     903          47 :     pRet->SetTmpDocShell( nullptr );
     904             : 
     905          47 :     (void)pRet->release();
     906             : 
     907          47 :     return pRetShell;
     908             : }
     909             : 
     910             : // appends all pages of source SwDoc - based on SwFEShell::Paste( SwDoc* )
     911          91 : SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const nStartPageNumber,
     912             :             SwPageDesc *const pTargetPageDesc, bool const bDeletePrevious, int pageOffset)
     913             : {
     914             :     // GetEndOfExtras + 1 = StartOfContent == no content node!
     915             :     // @see IDocumentContentOperations::CopyRange
     916          91 :     SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
     917         182 :     SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
     918         182 :     SwPaM aCpyPam( aSourceIdx );
     919             : 
     920          91 :     if ( aSourceEndIdx.GetNode().IsTextNode() ) {
     921          91 :         aCpyPam.SetMark();
     922             :         // moves to the last content node before EOC; for single paragraph
     923             :         // documents this would result in [n, n], which is considered empty
     924          91 :         aCpyPam.Move( fnMoveForward, fnGoDoc );
     925             :     }
     926             :     else
     927           0 :         aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
     928             : 
     929             : #ifdef DBG_UTIL
     930             :     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
     931             :                               << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
     932             :     aSourceIdx++;
     933             :     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
     934             :                                             << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
     935             :     if ( aSourceIdx.GetNode().GetNodeType() != ND_ENDNODE ) {
     936             :         aSourceIdx++;
     937             :         SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType() << std::dec );
     938             :         aSourceIdx--;
     939             :     }
     940             :     aSourceIdx--;
     941             :     SAL_INFO( "sw.docappend", ".." );
     942             :     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
     943             :                               << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
     944             :     aSourceEndIdx++;
     945             :     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
     946             :                               << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
     947             :     aSourceEndIdx--;
     948             :     SAL_INFO( "sw.docappend", "Src-Nd: " << CNTNT_DOC( &rSource ) );
     949             :     SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
     950             : #endif
     951             : 
     952          91 :     SwWrtShell* pTargetShell = GetDocShell()->GetWrtShell();
     953          91 :     if ( pTargetShell ) {
     954             : #ifdef DBG_UTIL
     955             :         SAL_INFO( "sw.docappend", "Has target write shell" );
     956             : #endif
     957          44 :         pTargetShell->StartAllAction();
     958             : 
     959             :         // Otherwise we have to handle SwPlaceholderNodes as first node
     960          44 :         if ( pTargetPageDesc ) {
     961          44 :             OUString name = pTargetPageDesc->GetName();
     962          44 :             pTargetShell->InsertPageBreak( &name, nStartPageNumber );
     963             : 
     964             :             // There is now a new empty text node on the new page. If it has
     965             :             // any marks, those are from the previous page: move them back
     966             :             // there, otherwise later we can't delete that empty text node.
     967          88 :             SwNodeIndex aNodeIndex(GetNodes().GetEndOfContent(), -1);
     968          44 :             if (SwTextNode* pTextNode = aNodeIndex.GetNode().GetTextNode())
     969             :             {
     970             :                 // Position of the last paragraph on the previous page.
     971          44 :                 --aNodeIndex;
     972          44 :                 SwPaM aPaM(aNodeIndex);
     973             :                 // Collect the marks starting or ending at this text node.
     974          88 :                 std::set<sw::mark::IMark*> aSeenMarks;
     975          44 :                 IDocumentMarkAccess* pMarkAccess = getIDocumentMarkAccess();
     976          97 :                 for (const SwIndex* pIndex = pTextNode->GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
     977             :                 {
     978          53 :                     sw::mark::IMark* pMark = const_cast<sw::mark::IMark*>(pIndex->GetMark());
     979          53 :                     if (!pMark)
     980          88 :                         continue;
     981           9 :                     if (aSeenMarks.find(pMark) != aSeenMarks.end())
     982           0 :                         continue;
     983           9 :                     aSeenMarks.insert(pMark);
     984             :                 }
     985             :                 // And move them back.
     986          53 :                 for (sw::mark::IMark* pMark : aSeenMarks)
     987          53 :                     pMarkAccess->repositionMark(pMark, aPaM);
     988          44 :             }
     989             :         }
     990             :     }
     991             : #ifdef DBG_UTIL
     992             :     SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
     993             : #endif
     994             : 
     995             :     // -1, otherwise aFixupIdx would move to new EOC
     996         182 :     SwNodeIndex aFixupIdx( GetNodes().GetEndOfContent(), -1 );
     997             : 
     998             :     // append at the end of document / content
     999         182 :     SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
    1000         182 :     SwPaM aInsertPam( aTargetIdx );
    1001             : 
    1002             : #ifdef DBG_UTIL
    1003             :     SAL_INFO( "sw.docappend", "Pam-Nd: " << aCpyPam.GetNode( true ).GetIndex() - aCpyPam.GetNode( false ).GetIndex() + 1
    1004             :                               << " (0x" << std::hex << (int) aCpyPam.GetNode( false ).GetNodeType() << std::dec
    1005             :                               << " " << aCpyPam.GetNode( false ).GetIndex()
    1006             :                               << " - 0x" << std::hex << (int) aCpyPam.GetNode( true ).GetNodeType() << std::dec
    1007             :                               << " " << aCpyPam.GetNode( true ).GetIndex() << ")" );
    1008             : #endif
    1009             : 
    1010          91 :     this->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
    1011          91 :     this->getIDocumentFieldsAccess().LockExpFields();
    1012             : 
    1013             :     // Position where the appended doc starts. Will be filled in later (uses GetEndOfContent() because SwNodeIndex has no default ctor).
    1014          91 :     SwNodeIndex aStartAppendIndex( GetNodes().GetEndOfContent() );
    1015             : 
    1016             :     {
    1017             :         // **
    1018             :         // ** refer to SwFEShell::Paste, if you change the following code **
    1019             :         // **
    1020             : 
    1021          91 :         SwPosition& rInsPos = *aInsertPam.GetPoint();
    1022             : 
    1023             :         {
    1024          91 :             SwNodeIndex aIndexBefore(rInsPos.nNode);
    1025             : 
    1026          91 :             aIndexBefore--;
    1027             : #ifdef DBG_UTIL
    1028             :     SAL_INFO( "sw.docappend", "CopyRange In: " << CNTNT_DOC( this ) );
    1029             : #endif
    1030          91 :             rSource.getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/true, /*bCheckPos=*/true );
    1031             :             // Note: aCpyPam is invalid now
    1032             : #ifdef DBG_UTIL
    1033             :     SAL_INFO( "sw.docappend", "CopyRange Out: " << CNTNT_DOC( this ) );
    1034             : #endif
    1035             : 
    1036          91 :             ++aIndexBefore;
    1037             :             SwPaM aPaM(SwPosition(aIndexBefore),
    1038         182 :                        SwPosition(rInsPos.nNode));
    1039             : 
    1040          91 :             aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
    1041             : 
    1042             :             // Update the rsid of each pasted text node
    1043          91 :             SwNodes &rDestNodes = GetNodes();
    1044          91 :             sal_uLong const nEndIdx = aPaM.End()->nNode.GetIndex();
    1045             : 
    1046         461 :             for (sal_uLong nIdx = aPaM.Start()->nNode.GetIndex();
    1047             :                     nIdx <= nEndIdx; ++nIdx)
    1048             :             {
    1049         370 :                 SwTextNode *const pTextNode = rDestNodes[nIdx]->GetTextNode();
    1050         370 :                 if ( pTextNode )
    1051         366 :                     UpdateParRsid( pTextNode );
    1052          91 :             }
    1053             :         }
    1054             : 
    1055             :         {
    1056          91 :             sal_uLong iDelNodes = 0;
    1057          91 :             SwNodeIndex aDelIdx( aFixupIdx );
    1058             : 
    1059             :             // we just need to set the new page description and reset numbering
    1060             :             // this keeps all other settings as in the pasted document
    1061          91 :             if ( nStartPageNumber || pTargetPageDesc ) {
    1062             :                 SfxPoolItem *pNewItem;
    1063          44 :                 SwTextNode *aTextNd = 0;
    1064          44 :                 SwFormat *pFormat = 0;
    1065             : 
    1066             :                 // find the first node allowed to contain a RES_PAGEDESC
    1067             :                 while (true) {
    1068          44 :                     aFixupIdx++;
    1069             : 
    1070          44 :                     SwNode &node = aFixupIdx.GetNode();
    1071          44 :                     if ( node.IsTextNode() ) {
    1072             :                         // every document contains at least one text node!
    1073          44 :                         aTextNd = node.GetTextNode();
    1074          44 :                         pNewItem = aTextNd->GetAttr( RES_PAGEDESC ).Clone();
    1075          44 :                         break;
    1076             :                     }
    1077           0 :                     else if ( node.IsTableNode() ) {
    1078           0 :                         pFormat = node.GetTableNode()->GetTable().GetFrameFormat();
    1079           0 :                         pNewItem = pFormat->GetFormatAttr( RES_PAGEDESC ).Clone();
    1080           0 :                         break;
    1081             :                     }
    1082             :                 }
    1083             : 
    1084             : #ifdef DBG_UTIL
    1085             :     SAL_INFO( "sw.docappend", "Idx Del " << CNTNT_IDX( aDelIdx ) );
    1086             :     SAL_INFO( "sw.docappend", "Idx Fix " << CNTNT_IDX( aFixupIdx ) );
    1087             : #endif
    1088             :                 // just update the original instead of overwriting
    1089          44 :                 SwFormatPageDesc *aDesc = static_cast< SwFormatPageDesc* >( pNewItem );
    1090             : #ifdef DBG_UTIL
    1091             : if ( aDesc->GetPageDesc() )
    1092             :     SAL_INFO( "sw.docappend", "PD Update " << aDesc->GetPageDesc()->GetName() );
    1093             : else
    1094             :     SAL_INFO( "sw.docappend", "PD New" );
    1095             : #endif
    1096          44 :                 if ( nStartPageNumber )
    1097          44 :                     aDesc->SetNumOffset( nStartPageNumber );
    1098          44 :                 if ( pTargetPageDesc )
    1099          44 :                     aDesc->RegisterToPageDesc( *pTargetPageDesc );
    1100          44 :                 if ( aTextNd )
    1101          44 :                     aTextNd->SetAttr( *aDesc );
    1102             :                 else
    1103           0 :                     pFormat->SetFormatAttr( *aDesc );
    1104          44 :                 delete pNewItem;
    1105             : 
    1106             : #ifdef DBG_UTIL
    1107             :     SAL_INFO( "sw.docappend", "Idx " << CNTNT_IDX( aDelIdx ) );
    1108             : #endif
    1109          44 :                 iDelNodes++;
    1110             :             }
    1111             : 
    1112          91 :             if ( bDeletePrevious )
    1113          52 :                 iDelNodes++;
    1114             : 
    1115          91 :             if ( iDelNodes ) {
    1116             :                 // delete leading empty page(s), e.g. from InsertPageBreak or
    1117             :                 // new SwDoc. this has to be done before copying the page bound
    1118             :                 // frames, otherwise the drawing layer gets confused.
    1119          91 :                 if ( pTargetShell )
    1120          44 :                     pTargetShell->SttEndDoc( false );
    1121          91 :                 aDelIdx -= (iDelNodes - 1);
    1122             : #ifdef DBG_UTIL
    1123             :     SAL_INFO( "sw.docappend", "iDelNodes: " << iDelNodes
    1124             :                               << "  Idx: " << aDelIdx.GetNode().GetIndex()
    1125             :                               << "  EOE: " << GetNodes().GetEndOfExtras().GetIndex() );
    1126             : #endif
    1127          91 :                 GetNodes().Delete( aDelIdx, iDelNodes );
    1128          91 :                 aStartAppendIndex = aFixupIdx;
    1129             :             }
    1130             :             else
    1131             :             {
    1132           0 :                 aStartAppendIndex = aFixupIdx;
    1133           0 :                 ++aStartAppendIndex;
    1134          91 :             }
    1135             :         }
    1136             : 
    1137             :         // finally copy page bound frames
    1138         122 :         for ( auto pCpyFormat : *rSource.GetSpzFrameFormats() )
    1139             :         {
    1140          31 :             const SwFrameFormat& rCpyFormat = *pCpyFormat;
    1141          31 :             SwFormatAnchor aAnchor( rCpyFormat.GetAnchor() );
    1142          31 :             if (FLY_AT_PAGE != aAnchor.GetAnchorId())
    1143          14 :                 continue;
    1144             : #ifdef DBG_UTIL
    1145             :     SAL_INFO( "sw.docappend", "PaAn: " << aAnchor.GetPageNum()
    1146             :                               << " => " << aAnchor.GetPageNum() + pageOffset );
    1147             : #endif
    1148          17 :             if ( pageOffset != 0 )
    1149           6 :                 aAnchor.SetPageNum( aAnchor.GetPageNum() + pageOffset );
    1150          17 :             this->getIDocumentLayoutAccess().CopyLayoutFormat( rCpyFormat, aAnchor, true, true );
    1151          17 :         }
    1152             :     }
    1153             : 
    1154          91 :     this->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
    1155             : 
    1156          91 :     getIDocumentFieldsAccess().UnlockExpFields();
    1157          91 :     getIDocumentFieldsAccess().UpdateFields(NULL, false);
    1158             : 
    1159          91 :     if ( pTargetShell )
    1160          44 :         pTargetShell->EndAllAction();
    1161             : 
    1162         182 :     return aStartAppendIndex;
    1163         177 : }
    1164             : 
    1165             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11