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 <com/sun/star/document/PrinterIndependentLayout.hpp>
25 : #include <com/sun/star/document/UpdateDocMode.hpp>
26 : #include <com/sun/star/text/XTextDocument.hpp>
27 : #include <com/sun/star/linguistic2/ProofreadingIterator.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 :
111 : #include <cmdid.h>
112 :
113 : #include <pausethreadstarting.hxx>
114 : #include <numrule.hxx>
115 : #include <list.hxx>
116 :
117 : #include <sfx2/Metadatable.hxx>
118 : #include <fmtmeta.hxx>
119 : #include <boost/foreach.hpp>
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 sFrmFmtStr[] = "Frameformat";
128 : const sal_Char sEmptyPageStr[] = "Empty Page";
129 : const sal_Char sColumnCntStr[] = "Columncontainer";
130 : const sal_Char sCharFmtStr[] = "Character style";
131 : const sal_Char sTxtCollStr[] = "Paragraph style";
132 : const sal_Char sGrfCollStr[] = "Graphikformatvorlage";
133 :
134 : /*
135 : * global functions...
136 : */
137 352 : uno::Reference< linguistic2::XProofreadingIterator > SwDoc::GetGCIterator() const
138 : {
139 352 : if (!m_xGCIterator.is() && SvtLinguConfig().HasGrammarChecker())
140 : {
141 0 : uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
142 : try
143 : {
144 0 : m_xGCIterator = linguistic2::ProofreadingIterator::create( xContext );
145 : }
146 0 : catch (const uno::Exception &)
147 : {
148 : OSL_FAIL( "No GCIterator" );
149 0 : }
150 : }
151 :
152 352 : return m_xGCIterator;
153 : }
154 :
155 771 : void StartGrammarChecking( SwDoc &rDoc )
156 : {
157 : // check for a visible view
158 771 : bool bVisible = false;
159 771 : const SwDocShell *mpDocShell = rDoc.GetDocShell();
160 771 : SfxViewFrame *pFrame = SfxViewFrame::GetFirst( mpDocShell, false );
161 2313 : while (pFrame && !bVisible)
162 : {
163 771 : if (pFrame->IsVisible())
164 352 : bVisible = true;
165 771 : 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 771 : if (bVisible)
173 : {
174 352 : uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( rDoc.GetGCIterator() );
175 352 : 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 352 : }
184 : }
185 771 : }
186 :
187 : /*
188 : * internal functions
189 : */
190 14787 : static void lcl_DelFmtIndices( SwFmt* pFmt )
191 : {
192 14787 : SwFmtCntnt &rFmtCntnt = (SwFmtCntnt&)pFmt->GetCntnt();
193 14787 : if ( rFmtCntnt.GetCntntIdx() )
194 4640 : rFmtCntnt.SetNewCntntIdx( 0 );
195 14787 : SwFmtAnchor &rFmtAnchor = (SwFmtAnchor&)pFmt->GetAnchor();
196 14787 : if ( rFmtAnchor.GetCntntAnchor() )
197 6162 : rFmtAnchor.SetAnchor( 0 );
198 14787 : }
199 :
200 : /*
201 : * exported methods
202 : */
203 5052 : SwDoc::SwDoc()
204 5052 : : m_pNodes( new SwNodes(this) ),
205 5052 : mpAttrPool(new SwAttrPool(this)),
206 5052 : mpMarkManager(new ::sw::mark::MarkManager(*this)),
207 0 : m_pMetaFieldManager(new ::sw::MetaFieldManager()),
208 5052 : m_pDocumentDrawModelManager( new ::sw::DocumentDrawModelManager( *this ) ),
209 5052 : m_pDocumentRedlineManager( new ::sw::DocumentRedlineManager( *this ) ),
210 5052 : m_pDocumentStateManager( new ::sw::DocumentStateManager( *this ) ),
211 : m_pUndoManager(new ::sw::UndoManager(
212 25260 : boost::shared_ptr<SwNodes>(new SwNodes(this)), *m_pDocumentDrawModelManager, *m_pDocumentRedlineManager, *m_pDocumentStateManager)),
213 5052 : m_pDocumentSettingManager(new ::sw::DocumentSettingManager(*this)),
214 5052 : m_pDocumentChartDataProviderManager( new sw::DocumentChartDataProviderManager( *this ) ),
215 5052 : m_pDeviceAccess( new ::sw::DocumentDeviceManager( *this ) ),
216 5052 : m_pDocumentTimerManager( new ::sw::DocumentTimerManager( *this ) ),
217 5052 : m_pDocumentLinksAdministrationManager( new ::sw::DocumentLinksAdministrationManager( *this ) ),
218 0 : m_pDocumentListItemsManager( new ::sw::DocumentListItemsManager() ),
219 5052 : m_pDocumentListsManager( new ::sw::DocumentListsManager( *this ) ),
220 5052 : m_pDocumentOutlineNodesManager( new ::sw::DocumentOutlineNodesManager( *this ) ),
221 5052 : m_pDocumentContentOperationsManager( new ::sw::DocumentContentOperationsManager( *this ) ),
222 5052 : m_pDocumentFieldsManager( new ::sw::DocumentFieldsManager( *this ) ),
223 5052 : m_pDocumentStatisticsManager( new ::sw::DocumentStatisticsManager( *this ) ),
224 5052 : m_pDocumentLayoutManager( new ::sw::DocumentLayoutManager( *this ) ),
225 5052 : m_pDocumentStylePoolManager( new ::sw::DocumentStylePoolManager( *this ) ),
226 0 : m_pDocumentExternalDataManager( new ::sw::DocumentExternalDataManager() ),
227 5052 : mpDfltFrmFmt( new SwFrmFmt( GetAttrPool(), sFrmFmtStr, 0 ) ),
228 5052 : mpEmptyPageFmt( new SwFrmFmt( GetAttrPool(), sEmptyPageStr, mpDfltFrmFmt ) ),
229 5052 : mpColumnContFmt( new SwFrmFmt( GetAttrPool(), sColumnCntStr, mpDfltFrmFmt ) ),
230 5052 : mpDfltCharFmt( new SwCharFmt( GetAttrPool(), sCharFmtStr, 0 ) ),
231 5052 : mpDfltTxtFmtColl( new SwTxtFmtColl( GetAttrPool(), sTxtCollStr ) ),
232 5052 : mpDfltGrfFmtColl( new SwGrfFmtColl( GetAttrPool(), sGrfCollStr ) ),
233 : mpFrmFmtTbl( new SwFrmFmts() ),
234 : mpCharFmtTbl( new SwCharFmts() ),
235 : mpSpzFrmFmtTbl( new SwFrmFmts() ),
236 : mpSectionFmtTbl( new SwSectionFmts() ),
237 : mpTblFrmFmtTbl( new SwFrmFmts() ),
238 : mpTxtFmtCollTbl( new SwTxtFmtColls() ),
239 : mpGrfFmtCollTbl( new SwGrfFmtColls() ),
240 : mpTOXTypes( new SwTOXTypes() ),
241 : mpDefTOXBases( new SwDefTOXBase_Impl() ),
242 : mpGlossaryDoc( 0 ),
243 : mpOutlineRule( 0 ),
244 5052 : mpFtnInfo( new SwFtnInfo ),
245 5052 : mpEndNoteInfo( new SwEndNoteInfo ),
246 5052 : mpLineNumberInfo( new SwLineNumberInfo ),
247 5052 : mpFtnIdxs( new SwFtnIdxs ),
248 : mpDocShell( 0 ),
249 : mpACEWord( 0 ),
250 : mpURLStateChgd( 0 ),
251 : mpNumberFormatter( 0 ),
252 5052 : mpNumRuleTbl( new SwNumRuleTbl ),
253 0 : mpUnoCrsrTbl( new SwUnoCrsrTbl() ),
254 : mpPgPViewPrtData( 0 ),
255 : mpExtInputRing( 0 ),
256 : mpStyleAccess( 0 ),
257 : mpLayoutCache( 0 ),
258 5052 : mpGrammarContact(createGrammarContact()),
259 : m_pXmlIdRegistry(),
260 : mReferenceCount(0),
261 : mbGlossDoc(false),
262 : mbDtor(false),
263 : mbCopyIsMove(false),
264 : mbInReading(false),
265 : mbInMailMerge(false),
266 : mbInXMLImport(false),
267 : mbUpdateTOX(false),
268 : mbInLoadAsynchron(false),
269 : mbIsAutoFmtRedline(false),
270 : mbOLEPrtNotifyPending(false),
271 : mbAllOLENotify(false),
272 : mbInsOnlyTxtGlssry(false),
273 : mbContains_MSVBasic(false),
274 : mbClipBoard( false ),
275 : mbColumnSelection( false ),
276 : mbIsPrepareSelAll(false),
277 : #ifdef DBG_UTIL
278 : mbXMLExport(false),
279 : #endif
280 : mbContainsAtPageObjWithContentAnchor(false), //#i119292#, fdo#37024
281 :
282 : mbReadOnly(false),
283 181872 : meDocType(DOCTYPE_NATIVE)
284 : {
285 : //UUUU The DrawingLayer ItemPool which is used as 2nd pool for Writer documents' pool
286 : // has a default for the XFillStyleItem of XFILL_SOLID and the color for it is the default
287 : // fill color (blue7 or similar). This is a problem, in Writer we want the default fill
288 : // style to be drawing::FillStyle_NONE. This cannot simply be done by changing it in the 2nd pool at the
289 : // pool defaults when the DrawingLayer ItemPool is used for Writer, that would lead to
290 : // countless problems like DrawObjects initial fill and others.
291 : // It is also hard to find all places where the initial ItemSets for Writer (including
292 : // style hierarchies) are created and to always set (but only at the root) the FillStyle
293 : // to NONE fixed; that will add that attribute to the file format. It will be hard to reset
294 : // attribbute sets (which is done at import and using UI). Also not a good solution.
295 : // Luckily Writer uses pDfltTxtFmtColl as default parent for all paragraphs and similar, thus
296 : // it is possible to set this attribute here. It will be not reset when importing.
297 5052 : mpDfltTxtFmtColl->SetFmtAttr(XFillStyleItem(drawing::FillStyle_NONE));
298 5052 : mpDfltFrmFmt->SetFmtAttr(XFillStyleItem(drawing::FillStyle_NONE));
299 :
300 : /*
301 : * DefaultFormats and DefaultFormatCollections (FmtColl)
302 : * are inserted at position 0 at the respective array.
303 : * The formats in the FmtColls are derived from the
304 : * DefaultFormats and are also in the list.
305 : */
306 : /* Formats */
307 5052 : mpFrmFmtTbl->push_back(mpDfltFrmFmt);
308 5052 : mpCharFmtTbl->push_back(mpDfltCharFmt);
309 :
310 : /* FmtColls */
311 : // TXT
312 5052 : mpTxtFmtCollTbl->push_back(mpDfltTxtFmtColl);
313 : // GRF
314 5052 : mpGrfFmtCollTbl->push_back(mpDfltGrfFmtColl);
315 :
316 : // Create PageDesc, EmptyPageFmt and ColumnFmt
317 5052 : if ( maPageDescs.empty() )
318 5052 : getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD );
319 :
320 : // Set to "Empty Page"
321 5052 : mpEmptyPageFmt->SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE ) );
322 : // Set BodyFmt for columns
323 5052 : mpColumnContFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) );
324 :
325 5052 : GetDocumentFieldsManager()._InitFieldTypes();
326 :
327 : // Create a default OutlineNumRule (for Filters)
328 : mpOutlineRule = new SwNumRule( SwNumRule::GetOutlineRuleName(),
329 : // #i89178#
330 : numfunc::GetDefaultPositionAndSpaceMode(),
331 5052 : OUTLINE_RULE );
332 5052 : AddNumRule(mpOutlineRule);
333 : // Counting of phantoms depends on <IsOldNumbering()>
334 5052 : mpOutlineRule->SetCountPhantoms( !GetDocumentSettingManager().get(IDocumentSettingAccess::OLD_NUMBERING) );
335 :
336 : new SwTxtNode(
337 5052 : SwNodeIndex(GetUndoManager().GetUndoNodes().GetEndOfContent()),
338 5052 : mpDfltTxtFmtColl );
339 5052 : new SwTxtNode( SwNodeIndex( GetNodes().GetEndOfContent() ),
340 5052 : getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
341 :
342 5052 : maOLEModifiedTimer.SetTimeout( 1000 );
343 5052 : maOLEModifiedTimer.SetTimeoutHdl( LINK( this, SwDoc, DoUpdateModifiedOLE ));
344 :
345 : #if HAVE_FEATURE_DBCONNECTIVITY
346 : // Create DBManager
347 5052 : mpDBManager = new SwDBManager;
348 : #endif
349 :
350 : // create TOXTypes
351 5052 : InitTOXTypes();
352 :
353 : // pass empty item set containing the paragraph's list attributes
354 : // as ignorable items to the stype manager.
355 : {
356 5052 : SfxItemSet aIgnorableParagraphItems( GetAttrPool(), RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1);
357 5052 : mpStyleAccess = createStyleManager( &aIgnorableParagraphItems );
358 : }
359 :
360 5052 : static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
361 :
362 5052 : if (bHack)
363 : {
364 0 : mnRsid = 0;
365 : }
366 : else
367 : {
368 : // Initialize the session id of the current document to a random number
369 : // smaller than 2^21.
370 5052 : static rtlRandomPool aPool = rtl_random_createPool();
371 5052 : rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) );
372 5052 : mnRsid &= ( 1<<21 ) - 1;
373 5052 : mnRsid++;
374 : }
375 5052 : mnRsidRoot = mnRsid;
376 :
377 5052 : getIDocumentState().ResetModified();
378 5052 : }
379 :
380 5083 : static void DeleteAndDestroy(SwFrmFmts& rFmts, int aStartIdx, int aEndIdx)
381 : {
382 5083 : if (aEndIdx < aStartIdx)
383 5083 : return;
384 27717 : for( SwFrmFmts::const_iterator it = rFmts.begin() + aStartIdx;
385 18478 : it != rFmts.begin() + aEndIdx; ++it )
386 4156 : delete *it;
387 5083 : rFmts.erase( rFmts.begin() + aStartIdx, rFmts.begin() + aEndIdx);
388 : }
389 :
390 10126 : static void DeleteAndDestroy(SwTxtFmtColls& rFmts, int aStartIdx, int aEndIdx)
391 : {
392 10126 : if (aEndIdx < aStartIdx)
393 10126 : return;
394 210276 : for( SwTxtFmtColls::const_iterator it = rFmts.begin() + aStartIdx;
395 140184 : it != rFmts.begin() + aEndIdx; ++it )
396 59966 : delete *it;
397 10126 : rFmts.erase( rFmts.begin() + aStartIdx, rFmts.begin() + aEndIdx);
398 : }
399 :
400 38 : static void DeleteAndDestroy(SwCharFmts& rFmts, int aStartIdx, int aEndIdx)
401 : {
402 38 : if (aEndIdx < aStartIdx)
403 38 : return;
404 114 : for( SwCharFmts::const_iterator it = rFmts.begin() + aStartIdx;
405 76 : it != rFmts.begin() + aEndIdx; ++it )
406 0 : delete *it;
407 38 : rFmts.erase( rFmts.begin() + aStartIdx, rFmts.begin() + aEndIdx);
408 : }
409 :
410 : /**
411 : * Speciality: a member of the class SwDoc is located at
412 : * position 0 in the array of the Format and GDI objects.
413 : * This MUST not be destroyed using 'delete' in any case!
414 : */
415 15133 : SwDoc::~SwDoc()
416 : {
417 : // nothing here should create Undo actions!
418 5045 : GetIDocumentUndoRedo().DoUndo(false);
419 :
420 5045 : if (mpDocShell)
421 : {
422 0 : mpDocShell->SetUndoManager(0);
423 : }
424 :
425 5045 : delete mpGrammarContact;
426 5045 : mpGrammarContact = 0;
427 :
428 : //!! needs to be done to destroy a possible SwFmtDrop format that may
429 : //!! be connected to a char format which may not otherwise be removed
430 : //!! and thus would leave a unremoved SwFmt object. (TL)
431 : //!! (this is case is not possible via UI but via API...)
432 5045 : SwFmtDrop aDrop;
433 5045 : SetDefault(aDrop);
434 : //!! same for SwFmtCharFmt
435 10090 : SwFmtCharFmt aCharFmt(NULL);
436 5045 : SetDefault(aCharFmt);
437 :
438 5045 : getIDocumentTimerAccess().StopIdling(); // stop idle timer
439 :
440 5045 : delete mpURLStateChgd;
441 :
442 : // Deactivate Undo notification from Draw
443 5045 : if( GetDocumentDrawModelManager().GetDrawModel() )
444 : {
445 5045 : GetDocumentDrawModelManager().DrawNotifyUndoHdl();
446 5045 : ClrContourCache();
447 : }
448 :
449 5045 : delete mpPgPViewPrtData;
450 :
451 5045 : mbDtor = true;
452 :
453 : //Clear the redline table before the nodes array is destroyed
454 5045 : getIDocumentRedlineAccess().GetRedlineTbl().DeleteAndDestroyAll();
455 5045 : getIDocumentRedlineAccess().GetExtraRedlineTbl().DeleteAndDestroyAll();
456 :
457 5045 : delete mpUnoCrsrTbl;
458 5045 : delete mpACEWord;
459 :
460 : // Release the BaseLinks
461 : {
462 5045 : ::sfx2::SvLinkSources aTemp(getIDocumentLinksAdministration().GetLinkManager().GetServers());
463 15141 : for( ::sfx2::SvLinkSources::const_iterator it = aTemp.begin();
464 10094 : it != aTemp.end(); ++it )
465 2 : (*it)->Closed();
466 :
467 5045 : if( !getIDocumentLinksAdministration().GetLinkManager().GetLinks().empty() )
468 10 : getIDocumentLinksAdministration().GetLinkManager().Remove( 0, getIDocumentLinksAdministration().GetLinkManager().GetLinks().size() );
469 : }
470 :
471 : // The ChapterNumbers/Numbers need to be deleted before the styles
472 : // or we update all the time!
473 5045 : m_pNodes->pOutlineNds->clear();
474 5045 : SwNodes & rUndoNodes( GetUndoManager().GetUndoNodes() );
475 5045 : rUndoNodes.pOutlineNds->clear();
476 :
477 5045 : mpFtnIdxs->clear();
478 :
479 : // indices could be registered in attributes
480 5045 : m_pUndoManager->DelAllUndoObj();
481 :
482 : // The BookMarks contain indices to the Content. These must be deleted
483 : // before deleting the Nodes.
484 5045 : mpMarkManager->clearAllMarks();
485 :
486 5045 : if( mpExtInputRing )
487 : {
488 0 : Ring* pTmp = mpExtInputRing;
489 0 : mpExtInputRing = 0;
490 0 : while( pTmp->GetNext() != pTmp )
491 0 : delete pTmp->GetNext();
492 0 : delete pTmp;
493 : }
494 :
495 : // Old - deletion without a Flag is expensive, because we send a Modify
496 : // aTOXTypes.DeleteAndDestroy( 0, aTOXTypes.Count() );
497 : {
498 50754 : for( sal_uInt16 n = mpTOXTypes->size(); n; )
499 : {
500 40664 : (*mpTOXTypes)[ --n ]->SetInDocDTOR();
501 40664 : delete (*mpTOXTypes)[ n ];
502 : }
503 5045 : mpTOXTypes->clear();
504 : }
505 5045 : delete mpDefTOXBases;
506 :
507 : // Any of the FrmFormats can still have indices registered.
508 : // These need to be destroyed now at the latest.
509 12820 : BOOST_FOREACH( SwFrmFmt* pFmt, *mpFrmFmtTbl )
510 7775 : lcl_DelFmtIndices( pFmt );
511 11485 : BOOST_FOREACH( SwFrmFmt* pFmt, *mpSpzFrmFmtTbl )
512 6440 : lcl_DelFmtIndices( pFmt );
513 5617 : BOOST_FOREACH( SwSectionFmt* pFmt, *mpSectionFmtTbl )
514 572 : lcl_DelFmtIndices( pFmt );
515 :
516 : // The formats/styles that follow depend on the default formats.
517 : // Destroy these only after destroying the FmtIndices, because the content
518 : // of headers/footers has to be deleted as well. If in the headers/footers
519 : // there are still Flys registered at that point, we have a problem.
520 11574 : BOOST_FOREACH(SwPageDesc *pPageDesc, maPageDescs)
521 6529 : delete pPageDesc;
522 5045 : maPageDescs.clear();
523 :
524 : // Delete content selections.
525 : // Don't wait for the SwNodes dtor to destroy them; so that Formats
526 : // do not have any dependencies anymore.
527 5045 : m_pNodes->DelNodes( SwNodeIndex(*m_pNodes), m_pNodes->Count() );
528 5045 : rUndoNodes.DelNodes( SwNodeIndex( rUndoNodes ), rUndoNodes.Count() );
529 :
530 : // Delete Formats, make it permanent some time in the future
531 :
532 : // Delete for Collections
533 : // So that we get rid of the dependencies
534 5045 : mpFtnInfo->ReleaseCollection();
535 5045 : mpEndNoteInfo->ReleaseCollection();
536 :
537 : OSL_ENSURE( mpDfltTxtFmtColl == (*mpTxtFmtCollTbl)[0],
538 : "Default-Text-Collection must always be at the start" );
539 :
540 : // Optimization: Based on the fact that Standard is always 2nd in the
541 : // array, we should delete it as the last. With this we avoid
542 : // reparenting the Formats all the time!
543 5045 : if( 2 < mpTxtFmtCollTbl->size() )
544 5019 : DeleteAndDestroy(*mpTxtFmtCollTbl, 2, mpTxtFmtCollTbl->size());
545 5045 : DeleteAndDestroy(*mpTxtFmtCollTbl, 1, mpTxtFmtCollTbl->size());
546 5045 : delete mpTxtFmtCollTbl;
547 :
548 : OSL_ENSURE( mpDfltGrfFmtColl == (*mpGrfFmtCollTbl)[0],
549 : "DefaultGrfCollection must always be at the start" );
550 :
551 5045 : mpGrfFmtCollTbl->DeleteAndDestroy(1, mpGrfFmtCollTbl->size());
552 5045 : delete mpGrfFmtCollTbl;
553 :
554 : // Without explicitly freeing the DocumentDeviceManager
555 : // and relying on the implicit freeing there would be a crash
556 : // due to it happening after SwAttrPool is freed.
557 5045 : m_pDeviceAccess.reset();
558 :
559 : /*
560 : * DefaultFormats and DefaultFormatCollections (FmtColl)
561 : * are at position 0 of their respective arrays.
562 : * In order to not be deleted by the array's dtor, we remove them
563 : * now.
564 : */
565 5045 : mpFrmFmtTbl->erase( mpFrmFmtTbl->begin() );
566 5045 : mpCharFmtTbl->erase( mpCharFmtTbl->begin() );
567 :
568 : #if HAVE_FEATURE_DBCONNECTIVITY
569 5045 : DELETEZ( mpDBManager );
570 : #endif
571 :
572 : // All Flys need to be destroyed before the Drawing Model,
573 : // because Flys can still contain DrawContacts, when no
574 : // Layout could be constructed due to a read error.
575 5045 : DeleteAndDestroy( *mpSpzFrmFmtTbl, 0, mpSpzFrmFmtTbl->size() );
576 :
577 : // Only now destroy the Model, the drawing objects - which are also
578 : // contained in the Undo - need to remove their attributes from the
579 : // Model. Also, DrawContacts could exist before this.
580 5045 : GetDocumentDrawModelManager().ReleaseDrawModel();
581 : // Destroy DrawModel before the LinkManager, because it's always set
582 : // in the DrawModel.
583 : //The LinkManager gets destroyed automatically with m_pLinksAdministrationManager
584 :
585 : // Clear the Tables before deleting the defaults, or we crash due to
586 : // dependencies on defaults.
587 5045 : delete mpFrmFmtTbl;
588 5045 : delete mpSpzFrmFmtTbl;
589 :
590 5045 : delete mpStyleAccess;
591 :
592 5045 : delete mpCharFmtTbl;
593 5045 : delete mpSectionFmtTbl;
594 5045 : delete mpTblFrmFmtTbl;
595 5045 : delete mpDfltTxtFmtColl;
596 5045 : delete mpDfltGrfFmtColl;
597 5045 : delete mpNumRuleTbl;
598 :
599 5045 : disposeXForms(); // #i113606#, dispose the XForms objects
600 :
601 5045 : delete mpNumberFormatter;
602 5045 : delete mpFtnInfo;
603 5045 : delete mpEndNoteInfo;
604 5045 : delete mpLineNumberInfo;
605 5045 : delete mpFtnIdxs;
606 5045 : delete mpTOXTypes;
607 5045 : delete mpEmptyPageFmt;
608 5045 : delete mpColumnContFmt;
609 5045 : delete mpDfltCharFmt;
610 5045 : delete mpDfltFrmFmt;
611 5045 : delete mpLayoutCache;
612 :
613 10090 : SfxItemPool::Free(mpAttrPool);
614 10088 : }
615 :
616 10453 : void SwDoc::SetDocShell( SwDocShell* pDSh )
617 : {
618 10453 : if( mpDocShell != pDSh )
619 : {
620 10453 : if (mpDocShell)
621 : {
622 5225 : mpDocShell->SetUndoManager(0);
623 : }
624 10453 : mpDocShell = pDSh;
625 10453 : if (mpDocShell)
626 : {
627 5228 : mpDocShell->SetUndoManager(& GetUndoManager());
628 : }
629 :
630 10453 : getIDocumentLinksAdministration().GetLinkManager().SetPersist( mpDocShell );
631 :
632 : // set DocShell pointer also on DrawModel
633 10453 : InitDrawModelAndDocShell(mpDocShell, GetDocumentDrawModelManager().GetDrawModel());
634 : OSL_ENSURE(!GetDocumentDrawModelManager().GetDrawModel() ||
635 : GetDocumentDrawModelManager().GetDrawModel()->GetPersist() == GetPersist(),
636 : "draw model's persist is out of sync");
637 : }
638 10453 : }
639 :
640 : // Convenience method; to avoid excessive includes from docsh.hxx
641 72 : uno::Reference < embed::XStorage > SwDoc::GetDocStorage()
642 : {
643 72 : if( mpDocShell )
644 72 : return mpDocShell->GetStorage();
645 0 : if( getIDocumentLinksAdministration().GetLinkManager().GetPersist() )
646 0 : return getIDocumentLinksAdministration().GetLinkManager().GetPersist()->GetStorage();
647 0 : return NULL;
648 : }
649 :
650 5058 : SfxObjectShell* SwDoc::GetPersist() const
651 : {
652 5058 : return mpDocShell ? mpDocShell : getIDocumentLinksAdministration().GetLinkManager().GetPersist();
653 : }
654 :
655 38 : void SwDoc::ClearDoc()
656 : {
657 38 : GetIDocumentUndoRedo().DelAllUndoObj();
658 38 : ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
659 :
660 : // Deactivate Undo notification from Draw
661 38 : if( GetDocumentDrawModelManager().GetDrawModel() )
662 : {
663 38 : GetDocumentDrawModelManager().DrawNotifyUndoHdl();
664 38 : ClrContourCache();
665 : }
666 :
667 : // if there are still FlyFrames dangling around, delete them too
668 : sal_uInt16 n;
669 76 : while ( 0 != (n = GetSpzFrmFmts()->size()) )
670 0 : getIDocumentLayoutAccess().DelLayoutFmt((*mpSpzFrmFmtTbl)[n-1]);
671 : OSL_ENSURE( !GetDocumentDrawModelManager().GetDrawModel() || !GetDocumentDrawModelManager().GetDrawModel()->GetPage(0)->GetObjCount(),
672 : "not all DrawObjects removed from the page" );
673 :
674 38 : getIDocumentRedlineAccess().GetRedlineTbl().DeleteAndDestroyAll();
675 38 : getIDocumentRedlineAccess().GetExtraRedlineTbl().DeleteAndDestroyAll();
676 :
677 38 : delete mpACEWord;
678 :
679 : // The BookMarks contain indices to the Content. These must be deleted
680 : // before deleting the Nodes.
681 38 : mpMarkManager->clearAllMarks();
682 38 : InitTOXTypes();
683 :
684 : // create a dummy pagedesc for the layout
685 38 : SwPageDesc* pDummyPgDsc = MakePageDesc("?DUMMY?");
686 :
687 76 : SwNodeIndex aSttIdx( *GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
688 : // create the first one over and over again (without attributes/style etc.
689 38 : SwTxtNode* pFirstNd = GetNodes().MakeTxtNode( aSttIdx, mpDfltTxtFmtColl );
690 :
691 38 : if( getIDocumentLayoutAccess().GetCurrentViewShell() )
692 : {
693 : // set the layout to the dummy pagedesc
694 0 : pFirstNd->SetAttr( SwFmtPageDesc( pDummyPgDsc ));
695 :
696 0 : SwPosition aPos( *pFirstNd, SwIndex( pFirstNd ));
697 0 : SwPaM const tmpPaM(aSttIdx, SwNodeIndex(GetNodes().GetEndOfContent()));
698 0 : ::PaMCorrAbs(tmpPaM, aPos);
699 : }
700 :
701 38 : GetNodes().Delete( aSttIdx,
702 76 : GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() );
703 :
704 : // #i62440#
705 : // destruction of numbering rules and creation of new outline rule
706 : // *after* the document nodes are deleted.
707 38 : mpOutlineRule = NULL;
708 76 : BOOST_FOREACH( SwNumRule* pNumRule, *mpNumRuleTbl )
709 38 : delete pNumRule;
710 38 : mpNumRuleTbl->clear();
711 :
712 : // creation of new outline numbering rule
713 : mpOutlineRule = new SwNumRule( SwNumRule::GetOutlineRuleName(),
714 : // #i89178#
715 : numfunc::GetDefaultPositionAndSpaceMode(),
716 38 : OUTLINE_RULE );
717 38 : AddNumRule(mpOutlineRule);
718 : // Counting of phantoms depends on <IsOldNumbering()>
719 38 : mpOutlineRule->SetCountPhantoms( !GetDocumentSettingManager().get(IDocumentSettingAccess::OLD_NUMBERING) );
720 :
721 : // remove the dummy pagedesc from the array and delete all the old ones
722 38 : sal_uInt16 nDummyPgDsc = 0;
723 38 : if (FindPageDesc(pDummyPgDsc->GetName(), &nDummyPgDsc))
724 38 : maPageDescs.erase(maPageDescs.begin() + nDummyPgDsc);
725 :
726 76 : BOOST_FOREACH(SwPageDesc *pPageDesc, maPageDescs)
727 38 : delete pPageDesc;
728 38 : maPageDescs.clear();
729 :
730 : // Delete for Collections
731 : // So that we get rid of the dependencies
732 38 : mpFtnInfo->ReleaseCollection();
733 38 : mpEndNoteInfo->ReleaseCollection();
734 :
735 : // Optimization: Based on the fact that Standard is always 2nd in the
736 : // array, we should delete it as the last. With this we avoid
737 : // reparenting the Formats all the time!
738 38 : if( 2 < mpTxtFmtCollTbl->size() )
739 24 : DeleteAndDestroy(*mpTxtFmtCollTbl, 2, mpTxtFmtCollTbl->size());
740 38 : DeleteAndDestroy(*mpTxtFmtCollTbl, 1, mpTxtFmtCollTbl->size());
741 38 : mpGrfFmtCollTbl->DeleteAndDestroy(1, mpGrfFmtCollTbl->size());
742 38 : DeleteAndDestroy(*mpCharFmtTbl, 1, mpCharFmtTbl->size());
743 :
744 38 : if( getIDocumentLayoutAccess().GetCurrentViewShell() )
745 : {
746 : // search the FrameFormat of the root frm. This is not allowed to delete
747 0 : mpFrmFmtTbl->erase( std::find( mpFrmFmtTbl->begin(), mpFrmFmtTbl->end(), getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() ) );
748 0 : DeleteAndDestroy(*mpFrmFmtTbl, 1, mpFrmFmtTbl->size());
749 0 : mpFrmFmtTbl->push_back( getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() );
750 : }
751 : else
752 38 : DeleteAndDestroy(*mpFrmFmtTbl, 1, mpFrmFmtTbl->size());
753 :
754 38 : mxForbiddenCharsTable.clear();
755 :
756 38 : GetDocumentFieldsManager().ClearFieldTypes();
757 :
758 38 : delete mpNumberFormatter, mpNumberFormatter = 0;
759 :
760 38 : getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD );
761 38 : pFirstNd->ChgFmtColl( getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
762 38 : nDummyPgDsc = maPageDescs.size();
763 38 : maPageDescs.push_back( pDummyPgDsc );
764 : // set the layout back to the new standard pagedesc
765 38 : pFirstNd->ResetAllAttr();
766 : // delete now the dummy pagedesc
767 76 : DelPageDesc( nDummyPgDsc );
768 38 : }
769 :
770 0 : void SwDoc::SetPreviewPrtData( const SwPagePreviewPrtData* pNew )
771 : {
772 0 : if( pNew )
773 : {
774 0 : if( mpPgPViewPrtData )
775 0 : *mpPgPViewPrtData = *pNew;
776 : else
777 0 : mpPgPViewPrtData = new SwPagePreviewPrtData( *pNew );
778 : }
779 0 : else if( mpPgPViewPrtData )
780 0 : DELETEZ( mpPgPViewPrtData );
781 0 : getIDocumentState().SetModified();
782 0 : }
783 :
784 508 : void SwDoc::SetOLEObjModified()
785 : {
786 508 : if( getIDocumentLayoutAccess().GetCurrentViewShell() ) maOLEModifiedTimer.Start();
787 508 : }
788 :
789 : /** SwDoc: Reading and writing of the layout cache. */
790 32 : void SwDoc::ReadLayoutCache( SvStream& rStream )
791 : {
792 32 : if( !mpLayoutCache )
793 32 : mpLayoutCache = new SwLayoutCache();
794 32 : if( !mpLayoutCache->IsLocked() )
795 : {
796 32 : mpLayoutCache->GetLockCount() |= 0x8000;
797 32 : mpLayoutCache->Read( rStream );
798 32 : mpLayoutCache->GetLockCount() &= 0x7fff;
799 : }
800 32 : }
801 :
802 6 : void SwDoc::WriteLayoutCache( SvStream& rStream )
803 : {
804 6 : mpLayoutCache->Write( rStream, *this );
805 6 : }
806 :
807 24652 : IGrammarContact* getGrammarContact( const SwTxtNode& rTxtNode )
808 : {
809 24652 : const SwDoc* pDoc = rTxtNode.GetDoc();
810 24652 : if( !pDoc || pDoc->IsInDtor() )
811 0 : return 0;
812 24652 : return pDoc->getGrammarContact();
813 : }
814 :
815 : ::sfx2::IXmlIdRegistry&
816 342 : SwDoc::GetXmlIdRegistry()
817 : {
818 : // UGLY: this relies on SetClipBoard being called before GetXmlIdRegistry!
819 342 : if (!m_pXmlIdRegistry.get())
820 : {
821 68 : m_pXmlIdRegistry.reset( ::sfx2::createXmlIdRegistry( IsClipBoard() ) );
822 : }
823 342 : return *m_pXmlIdRegistry;
824 : }
825 :
826 5090 : void SwDoc::InitTOXTypes()
827 : {
828 5090 : ShellResource* pShellRes = SwViewShell::GetShellRes();
829 5090 : SwTOXType * pNew = new SwTOXType(TOX_CONTENT, pShellRes->aTOXContentName );
830 5090 : mpTOXTypes->push_back( pNew );
831 5090 : pNew = new SwTOXType(TOX_INDEX, pShellRes->aTOXIndexName );
832 5090 : mpTOXTypes->push_back( pNew );
833 5090 : pNew = new SwTOXType(TOX_USER, pShellRes->aTOXUserName );
834 5090 : mpTOXTypes->push_back( pNew );
835 5090 : pNew = new SwTOXType(TOX_ILLUSTRATIONS, pShellRes->aTOXIllustrationsName );
836 5090 : mpTOXTypes->push_back( pNew );
837 5090 : pNew = new SwTOXType(TOX_OBJECTS, pShellRes->aTOXObjectsName );
838 5090 : mpTOXTypes->push_back( pNew );
839 5090 : pNew = new SwTOXType(TOX_TABLES, pShellRes->aTOXTablesName );
840 5090 : mpTOXTypes->push_back( pNew );
841 5090 : pNew = new SwTOXType(TOX_AUTHORITIES, pShellRes->aTOXAuthoritiesName );
842 5090 : mpTOXTypes->push_back( pNew );
843 5090 : pNew = new SwTOXType(TOX_CITATION, pShellRes->aTOXCitationName );
844 5090 : mpTOXTypes->push_back( pNew );
845 5090 : }
846 :
847 16 : void SwDoc::ReplaceDefaults(const SwDoc& rSource)
848 : {
849 : // copy property defaults
850 : const sal_uInt16 aRangeOfDefaults[] =
851 : {
852 : RES_FRMATR_BEGIN, RES_FRMATR_END-1,
853 : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
854 : RES_PARATR_BEGIN, RES_PARATR_END-1,
855 : RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
856 : RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
857 : XATTR_START, XATTR_END-1,
858 : 0
859 16 : };
860 :
861 16 : SfxItemSet aNewDefaults(GetAttrPool(), aRangeOfDefaults);
862 :
863 16 : sal_uInt16 nRange = 0;
864 128 : while (aRangeOfDefaults[nRange] != 0)
865 : {
866 5280 : for (sal_uInt16 nWhich = aRangeOfDefaults[nRange];
867 2640 : nWhich <= aRangeOfDefaults[nRange + 1]; ++nWhich)
868 : {
869 : const SfxPoolItem& rSourceAttr =
870 2544 : rSource.mpAttrPool->GetDefaultItem(nWhich);
871 2544 : if (rSourceAttr != mpAttrPool->GetDefaultItem(nWhich))
872 116 : aNewDefaults.Put(rSourceAttr);
873 : }
874 96 : nRange += 2;
875 : }
876 :
877 16 : if (aNewDefaults.Count())
878 16 : SetDefault(aNewDefaults);
879 16 : }
880 :
881 16 : void SwDoc::ReplaceCompatibilityOptions(const SwDoc& rSource)
882 : {
883 16 : m_pDocumentSettingManager->ReplaceCompatibilityOptions(rSource.GetDocumentSettingManager());
884 16 : }
885 :
886 : #ifdef DBG_UTIL
887 : #define CNTNT_DOC( doc ) \
888 : ((doc)->GetNodes().GetEndOfContent().GetIndex() - (doc)->GetNodes().GetEndOfExtras().GetIndex() - 2)
889 : #define CNTNT_IDX( idx ) \
890 : ((idx).GetNode().GetIndex() - GetNodes().GetEndOfExtras().GetIndex() - 1)
891 : #endif
892 :
893 10 : SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
894 : {
895 10 : SwDoc* pRet = new SwDoc;
896 :
897 : // we have to use pointer here, since the callee has to decide whether
898 : // SfxObjectShellLock or SfxObjectShellRef should be used sometimes the
899 : // object will be returned with refcount set to 0 ( if no DoInitNew is done )
900 10 : SfxObjectShell* pRetShell = new SwDocShell( pRet, SFX_CREATE_MODE_STANDARD );
901 10 : if( bCallInitNew )
902 : {
903 : // it could happen that DoInitNew creates model,
904 : // that increases the refcount of the object
905 10 : pRetShell->DoInitNew();
906 : }
907 :
908 10 : (void)pRet->acquire();
909 :
910 10 : pRet->ReplaceDefaults(*this);
911 :
912 10 : pRet->ReplaceCompatibilityOptions(*this);
913 :
914 10 : pRet->ReplaceStyles(*this);
915 :
916 : #ifdef DBG_UTIL
917 : SAL_INFO( "sw.createcopy", "CC-Nd-Src: " << CNTNT_DOC( this ) );
918 : SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
919 : #endif
920 10 : pRet->AppendDoc(*this, 0, NULL, bCallInitNew);
921 : #ifdef DBG_UTIL
922 : SAL_INFO( "sw.createcopy", "CC-Nd: " << CNTNT_DOC( pRet ) );
923 : #endif
924 :
925 : // remove the temporary shell if it is there as it was done before
926 10 : pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
927 :
928 10 : (void)pRet->release();
929 :
930 10 : return pRetShell;
931 : }
932 :
933 : // appends all pages of source SwDoc - based on SwFEShell::Paste( SwDoc* )
934 20 : void SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const nStartPageNumber,
935 : SwPageDesc *const pTargetPageDesc, bool const bDeletePrevious)
936 : {
937 : // GetEndOfExtras + 1 = StartOfContent == no content node!
938 : // @see IDocumentContentOperations::CopyRange
939 20 : SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
940 40 : SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
941 40 : SwPaM aCpyPam( aSourceIdx );
942 :
943 20 : if ( aSourceEndIdx.GetNode().IsTxtNode() ) {
944 20 : aCpyPam.SetMark();
945 : // moves to the last content node before EOC; for single paragraph
946 : // documents this would result in [n, n], which is considered empty
947 20 : aCpyPam.Move( fnMoveForward, fnGoDoc );
948 : }
949 : else
950 0 : aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
951 :
952 : #ifdef DBG_UTIL
953 : SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
954 : << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
955 : aSourceIdx++;
956 : SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType()
957 : << std::dec << " " << aSourceIdx.GetNode().GetIndex() );
958 : if ( aSourceIdx.GetNode().GetNodeType() != ND_ENDNODE ) {
959 : aSourceIdx++;
960 : SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceIdx.GetNode().GetNodeType() << std::dec );
961 : aSourceIdx--;
962 : }
963 : aSourceIdx--;
964 : SAL_INFO( "sw.docappend", ".." );
965 : SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
966 : << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
967 : aSourceEndIdx++;
968 : SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) aSourceEndIdx.GetNode().GetNodeType()
969 : << std::dec << " " << aSourceEndIdx.GetNode().GetIndex() );
970 : aSourceEndIdx--;
971 : SAL_INFO( "sw.docappend", "Src-Nd: " << CNTNT_DOC( &rSource ) );
972 : SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
973 : #endif
974 :
975 20 : SwWrtShell* pTargetShell = GetDocShell()->GetWrtShell();
976 20 : sal_uInt16 nPhysPageNumber = 0;
977 20 : if ( pTargetShell ) {
978 : #ifdef DBG_UTIL
979 : SAL_INFO( "sw.docappend", "Has target write shell" );
980 : #endif
981 10 : pTargetShell->StartAllAction();
982 :
983 : // Otherwise we have to handle SwDummySectionNodes as first node
984 10 : if ( pTargetPageDesc ) {
985 10 : OUString name = pTargetPageDesc->GetName();
986 10 : pTargetShell->InsertPageBreak( &name, nStartPageNumber );
987 : }
988 :
989 : // -1 for the page break + -1, becauce it's an offset
990 10 : nPhysPageNumber = pTargetShell->GetPhyPageNum() - 2;
991 10 : if (bDeletePrevious)
992 4 : nPhysPageNumber--;
993 :
994 : // We always start on an odd physical page number
995 10 : if (1 == nPhysPageNumber % 2)
996 6 : nPhysPageNumber++;
997 : #ifdef DBG_UTIL
998 : SAL_INFO( "sw.docappend", "PPNo " << nPhysPageNumber );
999 : #endif
1000 : }
1001 : #ifdef DBG_UTIL
1002 : SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
1003 : #endif
1004 :
1005 : // -1, otherwise aFixupIdx would move to new EOC
1006 40 : SwNodeIndex aFixupIdx( GetNodes().GetEndOfContent(), -1 );
1007 :
1008 : // append at the end of document / content
1009 40 : SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
1010 40 : SwPaM aInsertPam( aTargetIdx );
1011 :
1012 : #ifdef DBG_UTIL
1013 : SAL_INFO( "sw.docappend", "Pam-Nd: " << aCpyPam.GetNode( true ).GetIndex() - aCpyPam.GetNode( false ).GetIndex() + 1
1014 : << " (0x" << std::hex << (int) aCpyPam.GetNode( false ).GetNodeType() << std::dec
1015 : << " " << aCpyPam.GetNode( false ).GetIndex()
1016 : << " - 0x" << std::hex << (int) aCpyPam.GetNode( true ).GetNodeType() << std::dec
1017 : << " " << aCpyPam.GetNode( true ).GetIndex() << ")" );
1018 : #endif
1019 :
1020 20 : this->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
1021 20 : this->getIDocumentFieldsAccess().LockExpFlds();
1022 :
1023 : {
1024 : // **
1025 : // ** refer to SwFEShell::Paste, if you change the following code **
1026 : // **
1027 :
1028 20 : SwPosition& rInsPos = *aInsertPam.GetPoint();
1029 :
1030 : {
1031 20 : SwNodeIndex aIndexBefore(rInsPos.nNode);
1032 :
1033 20 : aIndexBefore--;
1034 : #ifdef DBG_UTIL
1035 : SAL_INFO( "sw.docappend", "CopyRange In: " << CNTNT_DOC( this ) );
1036 : #endif
1037 20 : rSource.getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, true );
1038 : // Note: aCpyPam is invalid now
1039 : #ifdef DBG_UTIL
1040 : SAL_INFO( "sw.docappend", "CopyRange Out: " << CNTNT_DOC( this ) );
1041 : #endif
1042 :
1043 20 : ++aIndexBefore;
1044 : SwPaM aPaM(SwPosition(aIndexBefore),
1045 40 : SwPosition(rInsPos.nNode));
1046 :
1047 20 : aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
1048 :
1049 : // Update the rsid of each pasted text node
1050 20 : SwNodes &rDestNodes = GetNodes();
1051 20 : sal_uLong const nEndIdx = aPaM.End()->nNode.GetIndex();
1052 :
1053 144 : for (sal_uLong nIdx = aPaM.Start()->nNode.GetIndex();
1054 : nIdx <= nEndIdx; ++nIdx)
1055 : {
1056 124 : SwTxtNode *const pTxtNode = rDestNodes[nIdx]->GetTxtNode();
1057 124 : if ( pTxtNode )
1058 108 : UpdateParRsid( pTxtNode );
1059 20 : }
1060 : }
1061 :
1062 : {
1063 20 : sal_uInt16 iDelNodes = 0;
1064 20 : SwNodeIndex aDelIdx( aFixupIdx );
1065 :
1066 : // we just need to set the new page description and reset numbering
1067 : // this keeps all other settings as in the pasted document
1068 20 : if ( nStartPageNumber || pTargetPageDesc ) {
1069 : SfxPoolItem *pNewItem;
1070 10 : SwTxtNode *aTxtNd = 0;
1071 10 : SwFmt *pFmt = 0;
1072 :
1073 : // find the first node allowed to contain a RES_PAGEDESC
1074 : while (true) {
1075 12 : aFixupIdx++;
1076 :
1077 12 : SwNode &node = aFixupIdx.GetNode();
1078 12 : if ( node.IsTxtNode() ) {
1079 : // every document contains at least one text node!
1080 10 : aTxtNd = node.GetTxtNode();
1081 10 : pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
1082 10 : break;
1083 : }
1084 2 : else if ( node.IsTableNode() ) {
1085 0 : pFmt = node.GetTableNode()->GetTable().GetFrmFmt();
1086 0 : pNewItem = pFmt->GetFmtAttr( RES_PAGEDESC ).Clone();
1087 0 : break;
1088 : }
1089 : }
1090 :
1091 : #ifdef DBG_UTIL
1092 : SAL_INFO( "sw.docappend", "Idx Del " << CNTNT_IDX( aDelIdx ) );
1093 : SAL_INFO( "sw.docappend", "Idx Fix " << CNTNT_IDX( aFixupIdx ) );
1094 : #endif
1095 : // just update the original instead of overwriting
1096 10 : SwFmtPageDesc *aDesc = static_cast< SwFmtPageDesc* >( pNewItem );
1097 : #ifdef DBG_UTIL
1098 : if ( aDesc->GetPageDesc() )
1099 : SAL_INFO( "sw.docappend", "PD Update " << aDesc->GetPageDesc()->GetName() );
1100 : else
1101 : SAL_INFO( "sw.docappend", "PD New" );
1102 : #endif
1103 10 : if ( nStartPageNumber )
1104 10 : aDesc->SetNumOffset( nStartPageNumber );
1105 10 : if ( pTargetPageDesc )
1106 10 : aDesc->RegisterToPageDesc( *pTargetPageDesc );
1107 10 : if ( aTxtNd )
1108 10 : aTxtNd->SetAttr( *aDesc );
1109 : else
1110 0 : pFmt->SetFmtAttr( *aDesc );
1111 10 : delete pNewItem;
1112 :
1113 : #ifdef DBG_UTIL
1114 : SAL_INFO( "sw.docappend", "Idx " << CNTNT_IDX( aDelIdx ) );
1115 : #endif
1116 12 : iDelNodes++;
1117 : }
1118 :
1119 20 : if ( bDeletePrevious )
1120 14 : iDelNodes++;
1121 :
1122 20 : if ( iDelNodes ) {
1123 : // delete leading empty page(s), e.g. from InsertPageBreak or
1124 : // new SwDoc. this has to be done before copying the page bound
1125 : // frames, otherwise the drawing layer gets confused.
1126 20 : if ( pTargetShell )
1127 10 : pTargetShell->SttEndDoc( false );
1128 20 : aDelIdx -= (iDelNodes - 1);
1129 : #ifdef DBG_UTIL
1130 : SAL_INFO( "sw.docappend", "iDelNodes: " << iDelNodes
1131 : << " Idx: " << aDelIdx.GetNode().GetIndex()
1132 : << " EOE: " << GetNodes().GetEndOfExtras().GetIndex() );
1133 : #endif
1134 20 : GetNodes().Delete( aDelIdx, iDelNodes );
1135 20 : }
1136 : }
1137 :
1138 : // finally copy page bound frames
1139 20 : const SwFrmFmts *pSpzFrmFmts = rSource.GetSpzFrmFmts();
1140 112 : for ( sal_uInt16 i = 0; i < pSpzFrmFmts->size(); ++i )
1141 : {
1142 92 : const SwFrmFmt& rCpyFmt = *(*pSpzFrmFmts)[i];
1143 92 : SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
1144 92 : if (FLY_AT_PAGE != aAnchor.GetAnchorId())
1145 56 : continue;
1146 : #ifdef DBG_UTIL
1147 : SAL_INFO( "sw.docappend", "PaAn: " << aAnchor.GetPageNum()
1148 : << " => " << aAnchor.GetPageNum() + nPhysPageNumber );
1149 : #endif
1150 36 : if ( nPhysPageNumber )
1151 12 : aAnchor.SetPageNum( aAnchor.GetPageNum() + nPhysPageNumber );
1152 36 : this->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
1153 36 : }
1154 : }
1155 :
1156 20 : this->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL );
1157 :
1158 20 : getIDocumentFieldsAccess().UnlockExpFlds();
1159 20 : getIDocumentFieldsAccess().UpdateFlds(NULL, false);
1160 :
1161 20 : if ( pTargetShell )
1162 30 : pTargetShell->EndAllAction();
1163 20 : }
1164 :
1165 0 : sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const
1166 : {
1167 0 : const_iterator it = std::find(begin(), end(), p);
1168 0 : return it == end() ? USHRT_MAX : it - begin();
1169 : }
1170 :
1171 5083 : void SwGrfFmtColls::DeleteAndDestroy(int nStartIdx, int nEndIdx)
1172 : {
1173 5083 : if (nEndIdx < nStartIdx)
1174 5083 : return;
1175 15249 : for( std::vector<SwGrfFmtColl*>::const_iterator it = mvColls.begin() + nStartIdx;
1176 10166 : it != mvColls.begin() + nEndIdx; ++it )
1177 0 : delete *it;
1178 5083 : mvColls.erase( mvColls.begin() + nStartIdx, mvColls.begin() + nEndIdx);
1179 : }
1180 :
1181 0 : sal_uInt16 SwGrfFmtColls::GetPos(const SwGrfFmtColl* p) const
1182 : {
1183 0 : std::vector<SwGrfFmtColl*>::const_iterator it = std::find(mvColls.begin(), mvColls.end(), p);
1184 0 : return it == mvColls.end() ? USHRT_MAX : it - mvColls.begin();
1185 270 : }
1186 :
1187 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|