xref: /aoo42x/main/sw/source/core/doc/doc.cxx (revision 26ea3662)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 
25 #include <doc.hxx>
26 #include <UndoManager.hxx>
27 #include <hintids.hxx>
28 #include <tools/shl.hxx>
29 #include <tools/globname.hxx>
30 #include <svx/svxids.hrc>
31 #include <com/sun/star/i18n/WordType.hdl>
32 #include <com/sun/star/i18n/ForbiddenCharacters.hdl>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
37 #include <com/sun/star/document/XDocumentProperties.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <tools/urlobj.hxx>
40 #include <tools/poly.hxx>
41 #include <tools/multisel.hxx>
42 #include <rtl/ustring.hxx>
43 #include <vcl/virdev.hxx>
44 #include <svl/itemiter.hxx>
45 #include <svl/poolitem.hxx>
46 #include <unotools/syslocale.hxx>
47 #include <sfx2/printer.hxx>
48 #include <editeng/keepitem.hxx>
49 #include <editeng/cscoitem.hxx>
50 #include <editeng/brkitem.hxx>
51 #include <sfx2/linkmgr.hxx>
52 #include <editeng/forbiddencharacterstable.hxx>
53 #include <svx/svdmodel.hxx>
54 #include <editeng/pbinitem.hxx>
55 #include <unotools/charclass.hxx>
56 #include <unotools/localedatawrapper.hxx>
57 #include <swatrset.hxx>
58 #include <swmodule.hxx>
59 #include <fmtpdsc.hxx>
60 #include <fmtanchr.hxx>
61 #include <fmtrfmrk.hxx>
62 #include <fmtinfmt.hxx>
63 #include <fmtfld.hxx>
64 #include <txtfld.hxx>
65 #include <dbfld.hxx>
66 #include <txtinet.hxx>
67 #include <txtrfmrk.hxx>
68 #include <frmatr.hxx>
69 #include <linkenum.hxx>
70 #include <errhdl.hxx>
71 #include <pagefrm.hxx>
72 #include <rootfrm.hxx>
73 #include <swtable.hxx>
74 #include <pam.hxx>
75 #include <ndtxt.hxx>
76 #include <swundo.hxx>			// fuer die UndoIds
77 #include <UndoCore.hxx>
78 #include <UndoInsert.hxx>
79 #include <UndoSplitMove.hxx>
80 #include <UndoTable.hxx>
81 #include <pagedesc.hxx> //DTor
82 #include <breakit.hxx>
83 #include <ndole.hxx>
84 #include <ndgrf.hxx>
85 #include <rolbck.hxx>			// Undo-Attr
86 #include <doctxm.hxx>			// fuer die Verzeichnisse
87 #include <grfatr.hxx>
88 #include <poolfmt.hxx>			// PoolVorlagen-Id's
89 #include <mvsave.hxx>			// fuer Server-Funktionalitaet
90 #include <SwGrammarMarkUp.hxx>
91 #include <scriptinfo.hxx>
92 #include <acorrect.hxx>			// Autokorrektur
93 #include <mdiexp.hxx>	   		// Statusanzeige
94 #include <docstat.hxx>
95 #include <docary.hxx>
96 #include <redline.hxx>
97 #include <fldupde.hxx>
98 #include <swbaslnk.hxx>
99 #include <printdata.hxx>
100 #include <cmdid.h>              // fuer den dflt - Printer in SetJob
101 #include <statstr.hrc>      	// StatLine-String
102 #include <comcore.hrc>
103 #include <SwUndoTOXChange.hxx>
104 #include <SwUndoFmt.hxx>
105 #include <unocrsr.hxx>
106 #include <docsh.hxx>
107 #include <viewopt.hxx>
108 #include <docfld.hxx>           // _SetGetExpFld
109 #include <docufld.hxx>          // SwPostItField
110 #include <viewsh.hxx>
111 #include <shellres.hxx>
112 #include <txtfrm.hxx>
113 #include <attrhint.hxx>
114 #include <wdocsh.hxx>           // SwWebDocShell
115 #include <prtopt.hxx>           // SwPrintOptions
116 #include <vector>
117 #include <map>
118 #include <osl/diagnose.h>
119 #include <osl/interlck.h>
120 #include <vbahelper/vbaaccesshelper.hxx>
121 #include "switerator.hxx"
122 #include <layouter.hxx>
123 #include <drawdoc.hxx>
124 
125 using namespace ::com::sun::star;
126 using ::rtl::OUString;
127 
128 
129 // Seiten-Deskriptoren
130 SV_IMPL_PTRARR(SwPageDescs,SwPageDescPtr);
131 // Verzeichnisse
132 SV_IMPL_PTRARR( SwTOXTypes, SwTOXTypePtr )
133 // FeldTypen
134 SV_IMPL_PTRARR( SwFldTypes, SwFldTypePtr)
135 
136 /** IInterface
137 */
138 sal_Int32 SwDoc::acquire()
139 {
140     OSL_ASSERT(mReferenceCount >= 0 && "Negative reference count detected! This is a sign for unbalanced acquire/release calls.");
141     return osl_incrementInterlockedCount(&mReferenceCount);
142 }
143 
144 sal_Int32 SwDoc::release()
145 {
146     OSL_PRECOND(mReferenceCount >= 1, "Object is already released! Releasing it again leads to a negative reference count.");
147     return osl_decrementInterlockedCount(&mReferenceCount);
148 }
149 
150 sal_Int32 SwDoc::getReferenceCount() const
151 {
152     OSL_ASSERT(mReferenceCount >= 0 && "Negative reference count detected! This is a sign for unbalanced acquire/release calls.");
153     return mReferenceCount;
154 }
155 
156 /** IDocumentSettingAccess
157 */
158 bool SwDoc::get(/*[in]*/ DocumentSettingId id) const
159 {
160     switch (id)
161     {
162         // COMPATIBILITY FLAGS START
163         case PARA_SPACE_MAX: return mbParaSpaceMax; //(n8Dummy1 & DUMMY_PARASPACEMAX);
164         case PARA_SPACE_MAX_AT_PAGES: return mbParaSpaceMaxAtPages; //(n8Dummy1 & DUMMY_PARASPACEMAX_AT_PAGES);
165         case TAB_COMPAT: return mbTabCompat; //(n8Dummy1 & DUMMY_TAB_COMPAT);
166         case ADD_FLY_OFFSETS: return mbAddFlyOffsets; //(n8Dummy2 & DUMMY_ADD_FLY_OFFSETS);
167         case ADD_EXT_LEADING: return mbAddExternalLeading; //(n8Dummy2 & DUMMY_ADD_EXTERNAL_LEADING);
168         case USE_VIRTUAL_DEVICE: return mbUseVirtualDevice; //(n8Dummy1 & DUMMY_USE_VIRTUAL_DEVICE);
169         case USE_HIRES_VIRTUAL_DEVICE: return mbUseHiResolutionVirtualDevice; //(n8Dummy2 & DUMMY_USE_HIRES_VIR_DEV);
170         case OLD_NUMBERING: return mbOldNumbering;
171         case OLD_LINE_SPACING: return mbOldLineSpacing;
172         case ADD_PARA_SPACING_TO_TABLE_CELLS: return mbAddParaSpacingToTableCells;
173         case USE_FORMER_OBJECT_POS: return mbUseFormerObjectPos;
174         case USE_FORMER_TEXT_WRAPPING: return mbUseFormerTextWrapping;
175         case CONSIDER_WRAP_ON_OBJECT_POSITION: return mbConsiderWrapOnObjPos;
176         case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: return mbDoNotJustifyLinesWithManualBreak;
177         case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: return mbIgnoreFirstLineIndentInNumbering;
178         case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE: return mbOutlineLevelYieldsOutlineRule;
179 	    case TABLE_ROW_KEEP: return mbTableRowKeep;
180 	    case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: return mbIgnoreTabsAndBlanksForLineCalculation;
181 	    case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: return mbDoNotCaptureDrawObjsOnPage;
182         // --> OD 2006-08-25 #i68949#
183         case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME: return mbClipAsCharacterAnchoredWriterFlyFrames;
184         // <--
185         case UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading;
186         case USE_OLD_PRINTER_METRICS: return mbOldPrinterMetrics;
187         case TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent;
188         case PROTECT_FORM: return mbProtectForm;
189         // --> OD 2008-06-05 #i89181#
190         case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList;
191         // <--
192          // COMPATIBILITY FLAGS END
193 
194         case BROWSE_MODE: return mbLastBrowseMode; // Attention: normally the ViewShell has to be asked!
195         case HTML_MODE: return mbHTMLMode;
196         case GLOBAL_DOCUMENT: return mbIsGlobalDoc;
197         case GLOBAL_DOCUMENT_SAVE_LINKS: return mbGlblDocSaveLinks;
198         case LABEL_DOCUMENT: return mbIsLabelDoc;
199         case PURGE_OLE: return mbPurgeOLE;
200         case KERN_ASIAN_PUNCTUATION: return mbKernAsianPunctuation;
201         case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT: return mbDoNotResetParaAttrsForNumFont;
202         case MATH_BASELINE_ALIGNMENT: return mbMathBaselineAlignment;
203         default:
204             ASSERT(false, "Invalid setting id");
205     }
206     return false;
207 }
208 
209 void SwDoc::set(/*[in]*/ DocumentSettingId id, /*[in]*/ bool value)
210 {
211     switch (id)
212     {
213         // COMPATIBILITY FLAGS START
214         case PARA_SPACE_MAX:
215             mbParaSpaceMax = value;
216             break;
217         case PARA_SPACE_MAX_AT_PAGES:
218             mbParaSpaceMaxAtPages = value;
219             break;
220         case TAB_COMPAT:
221             mbTabCompat = value;
222             break;
223         case ADD_FLY_OFFSETS:
224             mbAddFlyOffsets = value;
225             break;
226         case ADD_EXT_LEADING:
227             mbAddExternalLeading = value;
228             break;
229         case USE_VIRTUAL_DEVICE:
230             mbUseVirtualDevice = value;
231             break;
232         case USE_HIRES_VIRTUAL_DEVICE:
233             mbUseHiResolutionVirtualDevice = value;
234             break;
235         case OLD_NUMBERING:
236             if (mbOldNumbering != value)
237             {
238                 mbOldNumbering = value;
239 
240                 const SwNumRuleTbl& rNmTbl = GetNumRuleTbl();
241                 for( sal_uInt16 n = 0; n < rNmTbl.Count(); ++n )
242                     rNmTbl[n]->SetInvalidRule(sal_True);
243 
244                 UpdateNumRule();
245 
246                 if (pOutlineRule)
247                 {
248                     pOutlineRule->Validate();
249                     // counting of phantoms depends on <IsOldNumbering()>
250                     pOutlineRule->SetCountPhantoms( !mbOldNumbering );
251                 }
252             }
253             break;
254         case OLD_LINE_SPACING:
255             mbOldLineSpacing = value;
256             break;
257         case ADD_PARA_SPACING_TO_TABLE_CELLS:
258             mbAddParaSpacingToTableCells = value;
259             break;
260         case USE_FORMER_OBJECT_POS:
261             mbUseFormerObjectPos = value;
262             break;
263         case USE_FORMER_TEXT_WRAPPING:
264             mbUseFormerTextWrapping = value;
265             break;
266         case CONSIDER_WRAP_ON_OBJECT_POSITION:
267             mbConsiderWrapOnObjPos = value;
268             break;
269         case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
270             mbDoNotJustifyLinesWithManualBreak = value;
271             break;
272         case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING:
273             mbIgnoreFirstLineIndentInNumbering = value;
274             break;
275 
276         case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE:
277             mbOutlineLevelYieldsOutlineRule = value;
278             break;
279 
280         case TABLE_ROW_KEEP:
281             mbTableRowKeep = value;
282             break;
283 
284         case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION:
285             mbIgnoreTabsAndBlanksForLineCalculation = value;
286             break;
287 
288         case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE:
289             mbDoNotCaptureDrawObjsOnPage = value;
290             break;
291 
292         case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME:
293             mbClipAsCharacterAnchoredWriterFlyFrames = value;
294             break;
295 
296         case UNIX_FORCE_ZERO_EXT_LEADING:
297             mbUnixForceZeroExtLeading = value;
298             break;
299 
300         case PROTECT_FORM:
301             mbProtectForm = value;
302             break;
303 
304         case USE_OLD_PRINTER_METRICS:
305             mbOldPrinterMetrics = value;
306             break;
307 
308         case TABS_RELATIVE_TO_INDENT:
309             mbTabRelativeToIndent = value;
310         break;
311 
312         case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
313             mbTabAtLeftIndentForParagraphsInList = value;
314         break;
315 
316         // COMPATIBILITY FLAGS END
317 
318         case BROWSE_MODE: //can be used temporary (load/save) when no ViewShell is avaiable
319             mbLastBrowseMode = value;
320             break;
321         case HTML_MODE:
322             mbHTMLMode = value;
323             break;
324         case GLOBAL_DOCUMENT:
325             mbIsGlobalDoc = value;
326             break;
327         case GLOBAL_DOCUMENT_SAVE_LINKS:
328             mbGlblDocSaveLinks = value;
329             break;
330         case LABEL_DOCUMENT:
331             mbIsLabelDoc = value;
332             break;
333         case PURGE_OLE:
334             mbPurgeOLE = value;
335             break;
336         case KERN_ASIAN_PUNCTUATION:
337             mbKernAsianPunctuation = value;
338             break;
339         case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT:
340             mbDoNotResetParaAttrsForNumFont = value;
341             break;
342         case MATH_BASELINE_ALIGNMENT:
343             mbMathBaselineAlignment  = value;
344             break;
345         default:
346             ASSERT(false, "Invalid setting id");
347     }
348 }
349 
350 const i18n::ForbiddenCharacters*
351     SwDoc::getForbiddenCharacters(/*[in]*/ sal_uInt16 nLang, /*[in]*/ bool bLocaleData ) const
352 {
353     const i18n::ForbiddenCharacters* pRet = 0;
354     if( xForbiddenCharsTable.isValid() )
355         pRet = xForbiddenCharsTable->GetForbiddenCharacters( nLang, sal_False );
356     if( bLocaleData && !pRet && pBreakIt )
357         pRet = &pBreakIt->GetForbidden( (LanguageType)nLang );
358     return pRet;
359 }
360 
361 void SwDoc::setForbiddenCharacters(/*[in]*/ sal_uInt16 nLang,
362                                    /*[in]*/ const com::sun::star::i18n::ForbiddenCharacters& rFChars )
363 {
364     if( !xForbiddenCharsTable.isValid() )
365     {
366         uno::Reference<
367             lang::XMultiServiceFactory > xMSF =
368                                     ::comphelper::getProcessServiceFactory();
369         xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF );
370     }
371     xForbiddenCharsTable->SetForbiddenCharacters( nLang, rFChars );
372     if( pDrawModel )
373     {
374         pDrawModel->SetForbiddenCharsTable( xForbiddenCharsTable );
375         if( !mbInReading )
376             pDrawModel->ReformatAllTextObjects();
377     }
378 
379     SwRootFrm* pTmpRoot = GetCurrentLayout();
380 	if( pTmpRoot && !mbInReading )
381     {
382         pTmpRoot->StartAllAction();
383 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
384 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));
385         pTmpRoot->EndAllAction();
386     }//swmod 080310
387     SetModified();
388 }
389 
390 vos::ORef<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable()
391 {
392     if( !xForbiddenCharsTable.isValid() )
393     {
394         uno::Reference<
395             lang::XMultiServiceFactory > xMSF =
396                                     ::comphelper::getProcessServiceFactory();
397         xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF );
398     }
399     return xForbiddenCharsTable;
400 }
401 
402 const vos::ORef<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable() const
403 {
404     return xForbiddenCharsTable;
405 }
406 
407 sal_uInt16 SwDoc::getLinkUpdateMode( /*[in]*/bool bGlobalSettings ) const
408 {
409     sal_uInt16 nRet = nLinkUpdMode;
410     if( bGlobalSettings && GLOBALSETTING == nRet )
411         nRet = SW_MOD()->GetLinkUpdMode(get(IDocumentSettingAccess::HTML_MODE));
412     return nRet;
413 }
414 
415 void SwDoc::setLinkUpdateMode( /*[in]*/sal_uInt16 eMode )
416 {
417     nLinkUpdMode = eMode;
418 }
419 
420 SwFldUpdateFlags SwDoc::getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const
421 {
422     SwFldUpdateFlags eRet = eFldUpdMode;
423     if( bGlobalSettings && AUTOUPD_GLOBALSETTING == eRet )
424         eRet = SW_MOD()->GetFldUpdateFlags(get(IDocumentSettingAccess::HTML_MODE));
425     return eRet;
426 }
427 
428 void SwDoc::setFieldUpdateFlags(/*[in]*/SwFldUpdateFlags eMode )
429 {
430     eFldUpdMode = eMode;
431 }
432 
433 SwCharCompressType SwDoc::getCharacterCompressionType() const
434 {
435     return eChrCmprType;
436 }
437 
438 void SwDoc::setCharacterCompressionType( /*[in]*/SwCharCompressType n )
439 {
440     if( eChrCmprType != n )
441     {
442         eChrCmprType = n;
443         if( pDrawModel )
444         {
445             pDrawModel->SetCharCompressType( static_cast<sal_uInt16>(n) );
446             if( !mbInReading )
447                 pDrawModel->ReformatAllTextObjects();
448         }
449 
450 		SwRootFrm* pTmpRoot = GetCurrentLayout();
451 		if( pTmpRoot && !mbInReading )
452         {
453 			pTmpRoot->StartAllAction();
454 			std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
455 			std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));
456 			pTmpRoot->EndAllAction();
457 		}//swmod 080310
458         SetModified();
459     }
460 }
461 
462 /** IDocumentDeviceAccess
463 */
464 SfxPrinter* SwDoc::getPrinter(/*[in]*/ bool bCreate ) const
465 {
466     SfxPrinter* pRet = 0;
467     if ( !bCreate || pPrt )
468         pRet = pPrt;
469     else
470         pRet = &CreatePrinter_();
471 
472     return pRet;
473 }
474 
475 void SwDoc::setPrinter(/*[in]*/ SfxPrinter *pP,/*[in]*/ bool bDeleteOld,/*[in]*/ bool bCallPrtDataChanged )
476 {
477     if ( pP != pPrt )
478     {
479         if ( bDeleteOld )
480             delete pPrt;
481         pPrt = pP;
482 
483         // our printer should always use TWIP. Don't rely on this being set in ViewShell::InitPrt, there
484         // are situations where this isn't called.
485         // #i108712# / 2010-02-26 / frank.schoenheit@sun.com
486         if ( pPrt )
487         {
488             MapMode aMapMode( pPrt->GetMapMode() );
489             aMapMode.SetMapUnit( MAP_TWIP );
490             pPrt->SetMapMode( aMapMode );
491         }
492 
493         if ( pDrawModel && !get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) )
494             pDrawModel->SetRefDevice( pPrt );
495     }
496 
497     if ( bCallPrtDataChanged &&
498          // --> FME 2005-01-21 #i41075# Do not call PrtDataChanged() if we do not
499          // use the printer for formatting:
500          !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
501         // <--
502         PrtDataChanged();
503 }
504 
505 VirtualDevice* SwDoc::getVirtualDevice(/*[in]*/ bool bCreate ) const
506 {
507     VirtualDevice* pRet = 0;
508     if ( !bCreate || pVirDev )
509         pRet = pVirDev;
510     else
511         pRet = &CreateVirtualDevice_();
512 
513     return pRet;
514 }
515 
516 void SwDoc::setVirtualDevice(/*[in]*/ VirtualDevice* pVd,/*[in]*/ bool bDeleteOld, /*[in]*/ bool )
517 {
518     if ( pVirDev != pVd )
519     {
520         if ( bDeleteOld )
521             delete pVirDev;
522         pVirDev = pVd;
523 
524         if ( pDrawModel && get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) )
525             pDrawModel->SetRefDevice( pVirDev );
526     }
527 }
528 
529 OutputDevice* SwDoc::getReferenceDevice(/*[in]*/ bool bCreate ) const
530 {
531     OutputDevice* pRet = 0;
532     if ( !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
533     {
534         pRet = getPrinter( bCreate );
535 
536         if ( bCreate && !pPrt->IsValid() )
537         {
538             pRet = getVirtualDevice( sal_True );
539         }
540     }
541     else
542     {
543         pRet = getVirtualDevice( bCreate );
544     }
545 
546     return pRet;
547 }
548 
549 void SwDoc::setReferenceDeviceType(/*[in]*/ bool bNewVirtual,/*[in]*/ bool bNewHiRes )
550 {
551     if ( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) != bNewVirtual ||
552          get(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE) != bNewHiRes )
553     {
554         if ( bNewVirtual )
555         {
556             VirtualDevice* pMyVirDev = getVirtualDevice( true );
557             if ( !bNewHiRes )
558                 pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE06 );
559             else
560                 pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
561 
562             if( pDrawModel )
563                 pDrawModel->SetRefDevice( pMyVirDev );
564         }
565         else
566         {
567             // --> FME 2005-01-21 #i41075#
568             // We have to take care that a printer exists before calling
569             // PrtDataChanged() in order to prevent that PrtDataChanged()
570             // triggers this funny situation:
571             // getReferenceDevice()->getPrinter()->CreatePrinter_()
572             // ->setPrinter()-> PrtDataChanged()
573             SfxPrinter* pPrinter = getPrinter( true );
574             // <--
575             if( pDrawModel )
576                 pDrawModel->SetRefDevice( pPrinter );
577         }
578 
579         set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, bNewVirtual );
580         set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, bNewHiRes );
581         PrtDataChanged();
582         SetModified();
583     }
584 }
585 
586 const JobSetup* SwDoc::getJobsetup() const
587 {
588     return pPrt ? &pPrt->GetJobSetup() : 0;
589 }
590 
591 void SwDoc::setJobsetup(/*[in]*/ const JobSetup &rJobSetup )
592 {
593     sal_Bool bCheckPageDescs = 0 == pPrt;
594     sal_Bool bDataChanged = sal_False;
595 
596     if ( pPrt )
597     {
598         if ( pPrt->GetName() == rJobSetup.GetPrinterName() )
599         {
600             if ( pPrt->GetJobSetup() != rJobSetup )
601             {
602                 pPrt->SetJobSetup( rJobSetup );
603                 bDataChanged = sal_True;
604             }
605         }
606         else
607             delete pPrt, pPrt = 0;
608     }
609 
610     if( !pPrt )
611     {
612         //Das ItemSet wird vom Sfx geloescht!
613         SfxItemSet *pSet = new SfxItemSet( GetAttrPool(),
614                         FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
615                         SID_HTML_MODE,  SID_HTML_MODE,
616                         SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
617                         SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
618                         0 );
619         SfxPrinter *p = new SfxPrinter( pSet, rJobSetup );
620         if ( bCheckPageDescs )
621             setPrinter( p, true, true );
622         else
623         {
624             pPrt = p;
625             bDataChanged = sal_True;
626         }
627     }
628     if ( bDataChanged && !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
629         PrtDataChanged();
630 }
631 
632 const SwPrintData & SwDoc::getPrintData() const
633 {
634     if(!pPrtData)
635     {
636         SwDoc * pThis = const_cast< SwDoc * >(this);
637         pThis->pPrtData = new SwPrintData;
638 
639         // SwPrintData should be initialized from the configuration,
640         // the respective config item is implememted by SwPrintOptions which
641         // is also derived from SwPrintData
642         const SwDocShell *pDocSh = GetDocShell();
643         DBG_ASSERT( pDocSh, "pDocSh is 0, can't determine if this is a WebDoc or not" );
644         bool bWeb = 0 != dynamic_cast< const SwWebDocShell * >(pDocSh);
645         SwPrintOptions aPrintOptions( bWeb );
646         *pThis->pPrtData = aPrintOptions;
647     }
648     return *pPrtData;
649 }
650 
651 void SwDoc::setPrintData(/*[in]*/ const SwPrintData& rPrtData )
652 {
653     if(!pPrtData)
654         pPrtData = new SwPrintData;
655     *pPrtData = rPrtData;
656 }
657 
658 /** Implementations the next Interface here
659 */
660 
661 /*
662  * Dokumenteditieren (Doc-SS) zum Fuellen des Dokuments
663  * durch den RTF Parser und fuer die EditShell.
664  */
665 void SwDoc::ChgDBData(const SwDBData& rNewData)
666 {
667 	if( rNewData != aDBData )
668 	{
669 		aDBData = rNewData;
670 		SetModified();
671 	}
672 	GetSysFldType(RES_DBNAMEFLD)->UpdateFlds();
673 }
674 
675 bool SwDoc::SplitNode( const SwPosition &rPos, bool bChkTableStart )
676 {
677 	SwCntntNode *pNode = rPos.nNode.GetNode().GetCntntNode();
678 	if(0 == pNode)
679         return false;
680 
681 	{
682 		// Bug 26675:	DataChanged vorm loeschen verschicken, dann bekommt
683 		//			man noch mit, welche Objecte sich im Bereich befinden.
684 		//			Danach koennen sie vor/hinter der Position befinden.
685 		SwDataChanged aTmp( this, rPos, 0 );
686 	}
687 
688 	SwUndoSplitNode* pUndo = 0;
689     if (GetIDocumentUndoRedo().DoesUndo())
690     {
691         GetIDocumentUndoRedo().ClearRedo();
692 		// einfuegen vom Undo-Object, z.Z. nur beim TextNode
693 		if( pNode->IsTxtNode() )
694         {
695             pUndo = new SwUndoSplitNode( this, rPos, bChkTableStart );
696             GetIDocumentUndoRedo().AppendUndo(pUndo);
697         }
698     }
699 
700 	//JP 28.01.97: Sonderfall fuer SplitNode am Tabellenanfang:
701 	//				steht die am Doc/Fly/Footer/..-Anfang oder direkt
702 	//				hinter einer Tabelle, dann fuege davor
703 	//				einen Absatz ein
704 	if( bChkTableStart && !rPos.nContent.GetIndex() && pNode->IsTxtNode() )
705 	{
706 		sal_uLong nPrevPos = rPos.nNode.GetIndex() - 1;
707 		const SwTableNode* pTblNd;
708 		const SwNode* pNd = GetNodes()[ nPrevPos ];
709 		if( pNd->IsStartNode() &&
710 			SwTableBoxStartNode == ((SwStartNode*)pNd)->GetStartNodeType() &&
711 			0 != ( pTblNd = GetNodes()[ --nPrevPos ]->GetTableNode() ) &&
712 			((( pNd = GetNodes()[ --nPrevPos ])->IsStartNode() &&
713 			   SwTableBoxStartNode != ((SwStartNode*)pNd)->GetStartNodeType() )
714                || ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() )
715 			   || pNd->IsCntntNode() ))
716 		{
717 			if( pNd->IsCntntNode() )
718 			{
719 				//JP 30.04.99 Bug 65660:
720 				// ausserhalb des normalen BodyBereiches gibt es keine
721 				// Seitenumbrueche, also ist das hier kein gueltige
722 				// Bedingung fuers einfuegen eines Absatzes
723 				if( nPrevPos < GetNodes().GetEndOfExtras().GetIndex() )
724 					pNd = 0;
725 				else
726 				{
727 					// Dann nur, wenn die Tabelle Umbrueche traegt!
728 					const SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt();
729 					if( SFX_ITEM_SET != pFrmFmt->GetItemState(RES_PAGEDESC, sal_False) &&
730 						SFX_ITEM_SET != pFrmFmt->GetItemState( RES_BREAK, sal_False ) )
731 						pNd = 0;
732 				}
733 			}
734 
735 			if( pNd )
736 			{
737 				SwTxtNode* pTxtNd = GetNodes().MakeTxtNode(
738 										SwNodeIndex( *pTblNd ),
739 										GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
740 				if( pTxtNd )
741 				{
742 					((SwPosition&)rPos).nNode = pTblNd->GetIndex()-1;
743 					((SwPosition&)rPos).nContent.Assign( pTxtNd, 0 );
744 
745 					// nur im BodyBereich den SeitenUmbruch/-Vorlage umhaengem
746 					if( nPrevPos > GetNodes().GetEndOfExtras().GetIndex() )
747 					{
748 						SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt();
749 						const SfxPoolItem *pItem;
750 						if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_PAGEDESC,
751 							sal_False, &pItem ) )
752 						{
753                             pTxtNd->SetAttr( *pItem );
754                             pFrmFmt->ResetFmtAttr( RES_PAGEDESC );
755 						}
756 						if( SFX_ITEM_SET == pFrmFmt->GetItemState( RES_BREAK,
757 							sal_False, &pItem ) )
758 						{
759                             pTxtNd->SetAttr( *pItem );
760                             pFrmFmt->ResetFmtAttr( RES_BREAK );
761 						}
762 					}
763 
764 					if( pUndo )
765 						pUndo->SetTblFlag();
766 					SetModified();
767                     return true;
768                 }
769             }
770         }
771     }
772 
773 	SvULongs aBkmkArr( 15, 15 );
774 	_SaveCntntIdx( this, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(),
775 					aBkmkArr, SAVEFLY_SPLIT );
776     // FIXME: only SwTxtNode has a valid implementation of SplitCntntNode!
777     ASSERT(pNode->IsTxtNode(), "splitting non-text node?");
778     pNode = pNode->SplitCntntNode( rPos );
779     if (pNode)
780 	{
781 		// verschiebe noch alle Bookmarks/TOXMarks/FlyAtCnt
782 		if( aBkmkArr.Count() )
783 			_RestoreCntntIdx( this, aBkmkArr, rPos.nNode.GetIndex()-1, 0, sal_True );
784 
785 		if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
786 		{
787 			SwPaM aPam( rPos );
788 			aPam.SetMark();
789 			aPam.Move( fnMoveBackward );
790 			if( IsRedlineOn() )
791 				AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
792 			else
793 				SplitRedline( aPam );
794 		}
795 	}
796 
797 	SetModified();
798     return true;
799 }
800 
801 bool SwDoc::AppendTxtNode( SwPosition& rPos )
802 {
803     // create new node before EndOfContent
804     SwTxtNode * pCurNode = rPos.nNode.GetNode().GetTxtNode();
805 	if( !pCurNode )
806 	{
807 		// dann kann ja einer angelegt werden!
808 		SwNodeIndex aIdx( rPos.nNode, 1 );
809 		pCurNode = GetNodes().MakeTxtNode( aIdx,
810 						GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
811 	}
812 	else
813 		pCurNode = (SwTxtNode*)pCurNode->AppendNode( rPos );
814 
815 	rPos.nNode++;
816 	rPos.nContent.Assign( pCurNode, 0 );
817 
818     if (GetIDocumentUndoRedo().DoesUndo())
819     {
820         GetIDocumentUndoRedo().AppendUndo( new SwUndoInsert( rPos.nNode ) );
821     }
822 
823 	if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
824 	{
825 		SwPaM aPam( rPos );
826 		aPam.SetMark();
827 		aPam.Move( fnMoveBackward );
828 		if( IsRedlineOn() )
829 			AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
830 		else
831 			SplitRedline( aPam );
832 	}
833 
834 	SetModified();
835 	return sal_True;
836 }
837 
838 bool SwDoc::InsertString( const SwPaM &rRg, const String &rStr,
839         const enum InsertFlags nInsertMode )
840 {
841     if (GetIDocumentUndoRedo().DoesUndo())
842     {
843         GetIDocumentUndoRedo().ClearRedo(); // AppendUndo not always called!
844     }
845 
846     const SwPosition& rPos = *rRg.GetPoint();
847 
848 	if( pACEWord )					// Aufnahme in die Autokorrektur
849 	{
850 		if( 1 == rStr.Len() && pACEWord->IsDeleted() )
851         {
852             pACEWord->CheckChar( rPos, rStr.GetChar( 0 ) );
853         }
854 		delete pACEWord, pACEWord = 0;
855 	}
856 
857     SwTxtNode *const pNode = rPos.nNode.GetNode().GetTxtNode();
858 	if(!pNode)
859     {
860         return false;
861     }
862 
863 	SwDataChanged aTmp( rRg, 0 );
864 
865     if (!GetIDocumentUndoRedo().DoesUndo() ||
866         !GetIDocumentUndoRedo().DoesGroupUndo())
867     {
868         pNode->InsertText( rStr, rPos.nContent, nInsertMode );
869 
870         if (GetIDocumentUndoRedo().DoesUndo())
871         {
872             SwUndoInsert * const pUndo( new SwUndoInsert(
873                 rPos.nNode, rPos.nContent.GetIndex(), rStr.Len(), nInsertMode));
874             GetIDocumentUndoRedo().AppendUndo(pUndo);
875         }
876     }
877     else
878 	{			// ist Undo und Gruppierung eingeschaltet, ist alles anders !
879         SwUndoInsert * pUndo = NULL; // #111827#
880 
881         // don't group the start if hints at the start should be expanded
882         if (!(nInsertMode & IDocumentContentOperations::INS_FORCEHINTEXPAND))
883         // -> #111827#
884         {
885             SwUndo *const pLastUndo = GetUndoManager().GetLastUndo();
886             SwUndoInsert *const pUndoInsert(
887                 dynamic_cast<SwUndoInsert *>(pLastUndo) );
888             if (pUndoInsert && pUndoInsert->CanGrouping(rPos))
889             {
890                 pUndo = pUndoInsert;
891             }
892         }
893         // <- #111827#
894 
895         CharClass const& rCC = GetAppCharClass();
896         xub_StrLen nInsPos = rPos.nContent.GetIndex();
897 
898         if (!pUndo)
899 		{
900             pUndo = new SwUndoInsert( rPos.nNode, nInsPos, 0, nInsertMode,
901 							!rCC.isLetterNumeric( rStr, 0 ) );
902             GetIDocumentUndoRedo().AppendUndo( pUndo );
903         }
904 
905         pNode->InsertText( rStr, rPos.nContent, nInsertMode );
906 
907 		for( xub_StrLen i = 0; i < rStr.Len(); ++i )
908 		{
909 			nInsPos++;
910 			// wenn CanGrouping() sal_True returnt, ist schon alles erledigt
911 			if( !pUndo->CanGrouping( rStr.GetChar( i ) ))
912 			{
913                 pUndo = new SwUndoInsert( rPos.nNode, nInsPos, 1, nInsertMode,
914 							!rCC.isLetterNumeric( rStr, i ) );
915                 GetIDocumentUndoRedo().AppendUndo( pUndo );
916             }
917         }
918     }
919 
920 	if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() ))
921 	{
922         SwPaM aPam( rPos.nNode, aTmp.GetCntnt(),
923                     rPos.nNode, rPos.nContent.GetIndex());
924 		if( IsRedlineOn() )
925         {
926             AppendRedline(
927                 new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
928         }
929         else
930         {
931 			SplitRedline( aPam );
932         }
933 	}
934 
935 	SetModified();
936     return true;
937 }
938 
939 SwFlyFrmFmt* SwDoc::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode,
940 									const SfxItemSet* pFlyAttrSet,
941 									const SfxItemSet* pGrfAttrSet,
942 									SwFrmFmt* pFrmFmt)
943 {
944 	SwFlyFrmFmt *pFmt = 0;
945 	if( pNode )
946 	{
947         pFmt = _MakeFlySection( rPos, *pNode, FLY_AT_PARA,
948 								pFlyAttrSet, pFrmFmt );
949 		if( pGrfAttrSet )
950 			pNode->SetAttr( *pGrfAttrSet );
951 	}
952 	return pFmt;
953 }
954 
955 SwFlyFrmFmt* SwDoc::Insert( const SwPaM &rRg,
956 							const String& rGrfName,
957 							const String& rFltName,
958 							const Graphic* pGraphic,
959 							const SfxItemSet* pFlyAttrSet,
960 							const SfxItemSet* pGrfAttrSet,
961 							SwFrmFmt* pFrmFmt )
962 {
963 	if( !pFrmFmt )
964 		pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
965     SwGrfNode* pSwGrfNode = GetNodes().MakeGrfNode(
966 							SwNodeIndex( GetNodes().GetEndOfAutotext() ),
967 							rGrfName, rFltName, pGraphic,
968 							pDfltGrfFmtColl );
969     SwFlyFrmFmt* pSwFlyFrmFmt = _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode,
970 							pFlyAttrSet, pGrfAttrSet, pFrmFmt );
971     pSwGrfNode->onGraphicChanged();
972     return pSwFlyFrmFmt;
973 }
974 SwFlyFrmFmt* SwDoc::Insert( const SwPaM &rRg, const GraphicObject& rGrfObj,
975 							const SfxItemSet* pFlyAttrSet,
976 							const SfxItemSet* pGrfAttrSet,
977 							SwFrmFmt* pFrmFmt )
978 {
979 	if( !pFrmFmt )
980 		pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
981     SwGrfNode* pSwGrfNode = GetNodes().MakeGrfNode(
982 							SwNodeIndex( GetNodes().GetEndOfAutotext() ),
983 							rGrfObj, pDfltGrfFmtColl );
984 	SwFlyFrmFmt* pSwFlyFrmFmt = _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode,
985 							pFlyAttrSet, pGrfAttrSet, pFrmFmt );
986     pSwGrfNode->onGraphicChanged();
987     return pSwFlyFrmFmt;
988 }
989 
990 SwFlyFrmFmt* SwDoc::Insert(const SwPaM &rRg, const svt::EmbeddedObjectRef& xObj,
991 						const SfxItemSet* pFlyAttrSet,
992 						const SfxItemSet* pGrfAttrSet,
993 						SwFrmFmt* pFrmFmt )
994 {
995 	if( !pFrmFmt )
996 	{
997 		sal_uInt16 nId = RES_POOLFRM_OLE;
998         SvGlobalName aClassName( xObj->getClassID() );
999         if (SotExchange::IsMath(aClassName))
1000             nId = RES_POOLFRM_FORMEL;
1001 
1002 		pFrmFmt = GetFrmFmtFromPool( nId );
1003 	}
1004 	return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeOLENode(
1005 							SwNodeIndex( GetNodes().GetEndOfAutotext() ),
1006                             xObj,
1007 							pDfltGrfFmtColl ),
1008 							pFlyAttrSet, pGrfAttrSet,
1009 							pFrmFmt );
1010 }
1011 
1012 SwFlyFrmFmt* SwDoc::InsertOLE(const SwPaM &rRg, const String& rObjName,
1013 						sal_Int64 nAspect,
1014 						const SfxItemSet* pFlyAttrSet,
1015 						const SfxItemSet* pGrfAttrSet,
1016 						SwFrmFmt* pFrmFmt )
1017 {
1018 	if( !pFrmFmt )
1019 		pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_OLE );
1020 
1021 	return _InsNoTxtNode( *rRg.GetPoint(),
1022 							GetNodes().MakeOLENode(
1023 								SwNodeIndex( GetNodes().GetEndOfAutotext() ),
1024 								rObjName,
1025 								nAspect,
1026 								pDfltGrfFmtColl,
1027 								0 ),
1028 							pFlyAttrSet, pGrfAttrSet,
1029 							pFrmFmt );
1030 }
1031 
1032 /*************************************************************************
1033 |*				  SwDoc::GetFldType()
1034 |*	  Beschreibung: liefert den am Doc eingerichteten Feldtypen zurueck
1035 *************************************************************************/
1036 
1037 SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const
1038 {
1039 	for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
1040 		if( eWhich == (*pFldTypes)[i]->Which() )
1041 			return (*pFldTypes)[i];
1042 	return 0;
1043 }
1044 /*************************************************************************
1045  *			   void SetDocStat( const SwDocStat& rStat );
1046  *************************************************************************/
1047 
1048 void SwDoc::SetDocStat( const SwDocStat& rStat )
1049 {
1050 	*pDocStat = rStat;
1051 }
1052 
1053 const SwDocStat& SwDoc::GetDocStat() const
1054 {
1055 	return *pDocStat;
1056 }
1057 
1058 /*************************************************************************/
1059 
1060 
1061 struct _PostItFld : public _SetGetExpFld
1062 {
1063     _PostItFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld,  const SwIndex* pIdx = 0 )
1064         : _SetGetExpFld( rNdIdx, pFld, pIdx ) {}
1065 
1066     sal_uInt16 GetPageNo( const StringRangeEnumerator &rRangeEnum,
1067             const std::set< sal_Int32 > &rPossiblePages,
1068             sal_uInt16& rVirtPgNo, sal_uInt16& rLineNo );
1069 
1070     SwPostItField* GetPostIt() const
1071     {
1072         return (SwPostItField*) GetTxtFld()->GetFmtFld().GetField();
1073     }
1074 };
1075 
1076 
1077 sal_uInt16 _PostItFld::GetPageNo(
1078     const StringRangeEnumerator &rRangeEnum,
1079     const std::set< sal_Int32 > &rPossiblePages,
1080     /* out */ sal_uInt16& rVirtPgNo, /* out */ sal_uInt16& rLineNo )
1081 {
1082     //Problem: Wenn ein PostItFld in einem Node steht, der von mehr als
1083     //einer Layout-Instanz repraesentiert wird, steht die Frage im Raum,
1084     //ob das PostIt nur ein- oder n-mal gedruck werden soll.
1085     //Wahrscheinlich nur einmal, als Seitennummer soll hier keine Zufaellige
1086     //sondern die des ersten Auftretens des PostIts innerhalb des selektierten
1087     //Bereichs ermittelt werden.
1088     rVirtPgNo = 0;
1089     sal_uInt16 nPos = GetCntnt();
1090     SwIterator<SwTxtFrm,SwTxtNode> aIter( GetTxtFld()->GetTxtNode() );
1091     for( SwTxtFrm* pFrm = aIter.First(); pFrm;  pFrm = aIter.Next() )
1092     {
1093         if( pFrm->GetOfst() > nPos ||
1094             (pFrm->HasFollow() && pFrm->GetFollow()->GetOfst() <= nPos) )
1095             continue;
1096         sal_uInt16 nPgNo = pFrm->GetPhyPageNum();
1097         if( rRangeEnum.hasValue( nPgNo, &rPossiblePages ))
1098         {
1099             rLineNo = (sal_uInt16)(pFrm->GetLineCount( nPos ) +
1100                       pFrm->GetAllLines() - pFrm->GetThisLines());
1101             rVirtPgNo = pFrm->GetVirtPageNum();
1102             return nPgNo;
1103         }
1104     }
1105     return 0;
1106 }
1107 
1108 
1109 bool lcl_GetPostIts(
1110     IDocumentFieldsAccess* pIDFA,
1111     _SetGetExpFlds * pSrtLst )
1112 {
1113     bool bHasPostIts = false;
1114 
1115     SwFieldType* pFldType = pIDFA->GetSysFldType( RES_POSTITFLD );
1116     DBG_ASSERT( pFldType, "kein PostItType ? ");
1117 
1118     if( pFldType->GetDepends() )
1119     {
1120         // Modify-Object gefunden, trage alle Felder ins Array ein
1121         SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
1122         const SwTxtFld* pTxtFld;
1123         for( SwFmtFld* pFld = aIter.First(); pFld;  pFld = aIter.Next() )
1124         {
1125             if( 0 != ( pTxtFld = pFld->GetTxtFld() ) &&
1126                 pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
1127             {
1128                 bHasPostIts = true;
1129                 if (pSrtLst)
1130                 {
1131                     SwNodeIndex aIdx( pTxtFld->GetTxtNode() );
1132                     _PostItFld* pNew = new _PostItFld( aIdx, pTxtFld );
1133                     pSrtLst->Insert( pNew );
1134                 }
1135                 else
1136                     break;  // we just wanted to check for the existence of postits ...
1137             }
1138         }
1139     }
1140 
1141     return bHasPostIts;
1142 }
1143 
1144 
1145 static void lcl_FormatPostIt(
1146     IDocumentContentOperations* pIDCO,
1147     SwPaM& aPam,
1148     SwPostItField* pField,
1149     bool bNewPage, bool bIsFirstPostIt,
1150     sal_uInt16 nPageNo, sal_uInt16 nLineNo )
1151 {
1152     static char __READONLY_DATA sTmp[] = " : ";
1153 
1154     DBG_ASSERT( ViewShell::GetShellRes(), "missing ShellRes" );
1155 
1156     if (bNewPage)
1157     {
1158         pIDCO->InsertPoolItem( aPam, SvxFmtBreakItem( SVX_BREAK_PAGE_AFTER, RES_BREAK ), 0 );
1159         pIDCO->SplitNode( *aPam.GetPoint(), false );
1160     }
1161     else if (!bIsFirstPostIt)
1162     {
1163         // add an empty line between different notes
1164         pIDCO->SplitNode( *aPam.GetPoint(), false );
1165         pIDCO->SplitNode( *aPam.GetPoint(), false );
1166     }
1167 
1168     String aStr( ViewShell::GetShellRes()->aPostItPage );
1169     aStr.AppendAscii(sTmp);
1170 
1171     aStr += XubString::CreateFromInt32( nPageNo );
1172     aStr += ' ';
1173     if( nLineNo )
1174     {
1175         aStr += ViewShell::GetShellRes()->aPostItLine;
1176         aStr.AppendAscii(sTmp);
1177         aStr += XubString::CreateFromInt32( nLineNo );
1178         aStr += ' ';
1179     }
1180     aStr += ViewShell::GetShellRes()->aPostItAuthor;
1181     aStr.AppendAscii(sTmp);
1182     aStr += pField->GetPar1();
1183     aStr += ' ';
1184 	SvtSysLocale aSysLocale;
1185     aStr += /*(LocaleDataWrapper&)*/aSysLocale.GetLocaleData().getDate( pField->GetDate() );
1186     pIDCO->InsertString( aPam, aStr );
1187 
1188     pIDCO->SplitNode( *aPam.GetPoint(), false );
1189     aStr = pField->GetPar2();
1190 #if defined( WNT ) || defined( PM2 )
1191     // Bei Windows und Co alle CR rausschmeissen
1192     aStr.EraseAllChars( '\r' );
1193 #endif
1194     pIDCO->InsertString( aPam, aStr );
1195 }
1196 
1197 
1198 // provide the paper tray to use according to the page style in use,
1199 // but do that only if the respective item is NOT just the default item
1200 static sal_Int32 lcl_GetPaperBin( const SwPageFrm *pStartFrm )
1201 {
1202     sal_Int32 nRes = -1;
1203 
1204     const SwFrmFmt &rFmt = pStartFrm->GetPageDesc()->GetMaster();
1205     const SfxPoolItem *pItem = NULL;
1206     SfxItemState eState = rFmt.GetItemState( RES_PAPER_BIN, sal_False, &pItem );
1207     const SvxPaperBinItem *pPaperBinItem = dynamic_cast< const SvxPaperBinItem * >(pItem);
1208     if (eState > SFX_ITEM_DEFAULT && pPaperBinItem)
1209         nRes = pPaperBinItem->GetValue();
1210 
1211     return nRes;
1212 }
1213 
1214 
1215 void SwDoc::CalculatePagesForPrinting(
1216     const SwRootFrm& rLayout,
1217     /* out */ SwRenderData &rData,
1218     const SwPrintUIOptions &rOptions,
1219     bool bIsPDFExport,
1220     sal_Int32 nDocPageCount )
1221 {
1222     const sal_Int64 nContent = rOptions.getIntValue( "PrintContent", 0 );
1223     const bool bPrintSelection = nContent == 2;
1224 
1225     // properties to take into account when calcualting the set of pages
1226     // (PDF export UI does not allow for selecting left or right pages only)
1227     bool bPrintLeftPages    = bIsPDFExport ? true : rOptions.IsPrintLeftPages();
1228     bool bPrintRightPages   = bIsPDFExport ? true : rOptions.IsPrintRightPages();
1229     // #i103700# printing selections should not allow for automatic inserting empty pages
1230     bool bPrintEmptyPages   = bPrintSelection ? false : rOptions.IsPrintEmptyPages( bIsPDFExport );
1231 
1232     Range aPages( 1, nDocPageCount );
1233 
1234     MultiSelection aMulti( aPages );
1235     aMulti.SetTotalRange( Range( 0, RANGE_MAX ) );
1236     aMulti.Select( aPages );
1237 
1238     const SwPageFrm *pStPage  = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1239     const SwFrm     *pEndPage = pStPage;
1240 
1241     sal_uInt16 nFirstPageNo = 0;
1242     sal_uInt16 nLastPageNo  = 0;
1243     sal_uInt16 nPageNo      = 1;
1244 
1245     for( sal_uInt16 i = 1; i <= (sal_uInt16)aPages.Max(); ++i )
1246     {
1247         if( i < (sal_uInt16)aPages.Min() )
1248         {
1249             if( !pStPage->GetNext() )
1250                 break;
1251             pStPage = (SwPageFrm*)pStPage->GetNext();
1252             pEndPage= pStPage;
1253         }
1254         else if( i == (sal_uInt16)aPages.Min() )
1255         {
1256             nFirstPageNo = i;
1257             nLastPageNo = nFirstPageNo;
1258             if( !pStPage->GetNext() || (i == (sal_uInt16)aPages.Max()) )
1259                 break;
1260             pEndPage = pStPage->GetNext();
1261         }
1262         else if( i > (sal_uInt16)aPages.Min() )
1263         {
1264             nLastPageNo = i;
1265             if( !pEndPage->GetNext() || (i == (sal_uInt16)aPages.Max()) )
1266                 break;
1267             pEndPage = pEndPage->GetNext();
1268         }
1269     }
1270 
1271     DBG_ASSERT( nFirstPageNo, "first page not found!  Should not happen!" );
1272     if (nFirstPageNo)
1273     {
1274 // HACK: Hier muss von der MultiSelection noch eine akzeptable Moeglichkeit
1275 // geschaffen werden, alle Seiten von Seite x an zu deselektieren.
1276 // Z.B. durch SetTotalRange ....
1277 
1278 //              aMulti.Select( Range( nLastPageNo+1, SELECTION_MAX ), sal_False );
1279         MultiSelection aTmpMulti( Range( 1, nLastPageNo ) );
1280         long nTmpIdx = aMulti.FirstSelected();
1281         static long nEndOfSelection = SFX_ENDOFSELECTION;
1282         while ( nEndOfSelection != nTmpIdx && nTmpIdx <= long(nLastPageNo) )
1283         {
1284             aTmpMulti.Select( nTmpIdx );
1285             nTmpIdx = aMulti.NextSelected();
1286         }
1287         aMulti = aTmpMulti;
1288 // Ende des HACKs
1289 
1290         nPageNo = nFirstPageNo;
1291 
1292         std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays();
1293         std::set< sal_Int32 > &rValidPages = rData.GetValidPagesSet();
1294         std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames();
1295         rValidPages.clear();
1296         rValidStartFrms.clear();
1297         while ( pStPage )
1298         {
1299             const sal_Bool bRightPg = pStPage->OnRightPage();
1300             if ( aMulti.IsSelected( nPageNo ) &&
1301                 ( (bRightPg && bPrintRightPages) ||
1302                     (!bRightPg && bPrintLeftPages) ) )
1303             {
1304                 // --> FME 2005-12-12 #b6354161# Feature - Print empty pages
1305                 if ( bPrintEmptyPages || pStPage->Frm().Height() )
1306                 // <--
1307                 {
1308                     rValidPages.insert( nPageNo );
1309                     rValidStartFrms[ nPageNo ] = pStPage;
1310 
1311                     rPrinterPaperTrays[ nPageNo ] = lcl_GetPaperBin( pStPage );
1312                 }
1313             }
1314 
1315             if ( pStPage == pEndPage )
1316             {
1317                 pStPage = 0;
1318             }
1319             else
1320             {   ++nPageNo;
1321                 pStPage = (SwPageFrm*)pStPage->GetNext();
1322             }
1323         }
1324     }
1325 
1326 
1327     //
1328     // now that we have identified the valid pages for printing according
1329     // to the print settings we need to get the PageRange to use and
1330     // use both results to get the actual pages to be printed
1331     // (post-it settings need to be taken into account later on!)
1332     //
1333 
1334     // get PageRange value to use
1335     OUString aPageRange;
1336     // --> PL, OD #i116085# - adjusting fix for i113919
1337 //    if (bIsPDFExport)
1338 //    {
1339 //        aPageRange = rOptions.getStringValue( "PageRange", OUString() );
1340 //    }
1341 //    else
1342     if ( !bIsPDFExport )
1343     // <--
1344     {
1345         // PageContent :
1346         // 0 -> print all pages (default if aPageRange is empty)
1347         // 1 -> print range according to PageRange
1348         // 2 -> print selection
1349         if (1 == nContent)
1350             aPageRange = rOptions.getStringValue( "PageRange", OUString() );
1351         if (2 == nContent)
1352         {
1353             // note that printing selections is actually implemented by copying
1354             // the selection to a new temporary document and printing all of that one.
1355             // Thus for Writer "PrintContent" must never be 2.
1356             // See SwXTextDocument::GetRenderDoc for evaluating if a selection is to be
1357             // printed and for creating the temporary document.
1358         }
1359 
1360         // please note
1361     }
1362     if (aPageRange.getLength() == 0)    // empty string -> print all
1363     {
1364         // set page range to print to 'all pages'
1365         aPageRange = OUString::valueOf( (sal_Int32)1 );
1366         aPageRange += OUString::valueOf( (sal_Unicode)'-');
1367         aPageRange += OUString::valueOf( nDocPageCount );
1368     }
1369     rData.SetPageRange( aPageRange );
1370 
1371     // get vector of pages to print according to PageRange and valid pages set from above
1372     // (result may be an empty vector, for example if the range string is not correct)
1373     StringRangeEnumerator::getRangesFromString(
1374             aPageRange, rData.GetPagesToPrint(),
1375             1, nDocPageCount, 0, &rData.GetValidPagesSet() );
1376 }
1377 
1378 
1379 void SwDoc::UpdatePagesForPrintingWithPostItData(
1380     /* out */ SwRenderData &rData,
1381     const SwPrintUIOptions &rOptions,
1382     bool /*bIsPDFExport*/,
1383     sal_Int32 nDocPageCount )
1384 {
1385 
1386     sal_Int16 nPostItMode = (sal_Int16) rOptions.getIntValue( "PrintAnnotationMode", 0 );
1387     DBG_ASSERT(nPostItMode == POSTITS_NONE || rData.HasPostItData(),
1388             "print post-its without post-it data?" );
1389     const sal_uInt16 nPostItCount = rData.HasPostItData() ? rData.m_pPostItFields->Count() : 0;
1390     if (nPostItMode != POSTITS_NONE && nPostItCount > 0)
1391     {
1392         SET_CURR_SHELL( rData.m_pPostItShell );
1393 
1394         // clear document and move to end of it
1395         SwPaM aPam( rData.m_pPostItDoc->GetNodes().GetEndOfContent() );
1396         aPam.Move( fnMoveBackward, fnGoDoc );
1397         aPam.SetMark();
1398         aPam.Move( fnMoveForward, fnGoDoc );
1399         rData.m_pPostItDoc->DeleteRange( aPam );
1400 
1401         const StringRangeEnumerator aRangeEnum( rData.GetPageRange(), 1, nDocPageCount, 0 );
1402 
1403         // For mode POSTITS_ENDPAGE:
1404         // maps a physical page number to the page number in post-it document that holds
1405         // the first post-it for that physical page . Needed to relate the correct start frames
1406         // from the post-it doc to the physical page of the document
1407         std::map< sal_Int32, sal_Int32 >  aPostItLastStartPageNum;
1408 
1409         // add all post-its on valid pages within the the page range to the
1410         // temporary post-it document.
1411         // Since the array of post-it fileds is sorted by page and line number we will
1412         // already get them in the correct order
1413         sal_uInt16 nVirtPg = 0, nLineNo = 0, nLastPageNum = 0, nPhyPageNum = 0;
1414         bool bIsFirstPostIt = true;
1415         for (sal_uInt16 i = 0; i < nPostItCount; ++i)
1416         {
1417             _PostItFld& rPostIt = (_PostItFld&)*(*rData.m_pPostItFields)[ i ];
1418             nLastPageNum = nPhyPageNum;
1419             nPhyPageNum = rPostIt.GetPageNo(
1420                     aRangeEnum, rData.GetValidPagesSet(), nVirtPg, nLineNo );
1421             if (nPhyPageNum)
1422             {
1423                 // need to insert a page break?
1424                 // In POSTITS_ENDPAGE mode for each document page the following
1425                 // post-it page needs to start on a new page
1426                 const bool bNewPage = nPostItMode == POSTITS_ENDPAGE &&
1427                         !bIsFirstPostIt && nPhyPageNum != nLastPageNum;
1428 
1429                 lcl_FormatPostIt( rData.m_pPostItShell->GetDoc(), aPam,
1430                         rPostIt.GetPostIt(), bNewPage, bIsFirstPostIt, nVirtPg, nLineNo );
1431                 bIsFirstPostIt = false;
1432 
1433                 if (nPostItMode == POSTITS_ENDPAGE)
1434                 {
1435                     // get the correct number of current pages for the post-it document
1436                     rData.m_pPostItShell->CalcLayout();
1437                     const sal_Int32 nPages = rData.m_pPostItShell->GetPageCount();
1438                     aPostItLastStartPageNum[ nPhyPageNum ] = nPages;
1439                 }
1440             }
1441         }
1442 
1443         // format post-it doc to get correct number of pages
1444         rData.m_pPostItShell->CalcLayout();
1445         const sal_Int32 nPostItDocPageCount = rData.m_pPostItShell->GetPageCount();
1446 
1447         if (nPostItMode == POSTITS_ONLY || nPostItMode == POSTITS_ENDDOC)
1448         {
1449             // now add those post-it pages to the vector of pages to print
1450             // or replace them if only post-its should be printed
1451 
1452             rData.GetPostItStartFrames().clear();
1453             if (nPostItMode == POSTITS_ENDDOC)
1454             {
1455                 // set all values up to number of pages to print currently known to NULL,
1456                 // meaning none of the pages currently in the vector is from the
1457                 // post-it document, they are the documents pages.
1458                 rData.GetPostItStartFrames().resize( rData.GetPagesToPrint().size() );
1459             }
1460             else if (nPostItMode == POSTITS_ONLY)
1461             {
1462                 // no document page to be printed
1463                 rData.GetPagesToPrint().clear();
1464             }
1465 
1466             // now we just need to add the post-it pages to be printed to the end
1467             // of the vector of pages to print and keep the GetValidStartFrames
1468             // data conform with it
1469             sal_Int32 nPageNum = 0;
1470             const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower();
1471             while( pPageFrm && nPageNum < nPostItDocPageCount )
1472             {
1473                 DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1474                 ++nPageNum;
1475                 rData.GetPagesToPrint().push_back( 0 );  // a page number of 0 indicates this page is from the post-it doc
1476                 DBG_ASSERT( pPageFrm, "pPageFrm is NULL!" );
1477                 rData.GetPostItStartFrames().push_back( pPageFrm );
1478                 pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1479             }
1480             DBG_ASSERT( nPageNum == nPostItDocPageCount, "unexpected number of pages" );
1481         }
1482         else if (nPostItMode == POSTITS_ENDPAGE)
1483         {
1484             // the next step is to find all the start frames from the post-it
1485             // document that should be printed for a given physical page of the document
1486             std::map< sal_Int32, std::vector< const SwPageFrm * > > aPhysPageToPostItFrames;
1487 
1488             // ... thus, first collect all post-it doc start frames in a vector
1489             sal_Int32 nPostItPageNum = 0;
1490             std::vector< const SwPageFrm * > aAllPostItStartFrames;
1491             const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower();
1492             while( pPageFrm && sal_Int32(aAllPostItStartFrames.size()) < nPostItDocPageCount )
1493             {
1494                 DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1495                 ++nPostItPageNum;
1496                 aAllPostItStartFrames.push_back( pPageFrm );
1497                 pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1498             }
1499             DBG_ASSERT( sal_Int32(aAllPostItStartFrames.size()) == nPostItDocPageCount,
1500                     "unexpected number of frames; does not match number of pages" );
1501 
1502             // get a map that holds all post-it frames to be printed for a
1503             // given physical page from the document
1504             sal_Int32 nLastStartPageNum = 0;
1505             std::map< sal_Int32, sal_Int32 >::const_iterator  aIt;
1506             for (aIt = aPostItLastStartPageNum.begin();  aIt != aPostItLastStartPageNum.end();  ++aIt)
1507             {
1508                 const sal_Int32 nFrames = aIt->second - nLastStartPageNum;
1509                 const sal_Int32 nFirstStartPageNum = aIt == aPostItLastStartPageNum.begin() ?
1510                         1 : aIt->second - nFrames + 1;
1511                 DBG_ASSERT( 1 <= nFirstStartPageNum && nFirstStartPageNum <= nPostItDocPageCount,
1512                         "page number for first frame out of range" );
1513                 std::vector<  const SwPageFrm * > aStartFrames;
1514                 for (sal_Int32 i = 0; i < nFrames; ++i)
1515                 {
1516                     const sal_Int32 nIdx = nFirstStartPageNum - 1 + i;   // -1 because lowest page num is 1
1517                     DBG_ASSERT( 0 <= nIdx && nIdx < sal_Int32(aAllPostItStartFrames.size()),
1518                             "index out of range" );
1519                     aStartFrames.push_back( aAllPostItStartFrames[ nIdx ] );
1520                 }
1521                 aPhysPageToPostItFrames[ aIt->first /* phys page num */ ] = aStartFrames;
1522                 nLastStartPageNum = aIt->second;
1523             }
1524 
1525 
1526             // ok, now that aPhysPageToPostItFrames can give the start frames for all
1527             // post-it pages to be printed we need to merge those at the correct
1528             // position into the GetPagesToPrint vector and build and maintain the
1529             // GetValidStartFrames vector as well.
1530             // Since inserting a larger number of entries in the middle of a vector
1531             // isn't that efficient we will create new vectors by copying the required data
1532             std::vector< sal_Int32 >            aTmpPagesToPrint;
1533             std::vector< const SwPageFrm * >    aTmpPostItStartFrames;
1534             const size_t nNum = rData.GetPagesToPrint().size();
1535             for (size_t i = 0 ;  i < nNum;  ++i)
1536             {
1537                 // add the physical page to print from the document
1538                 const sal_Int32 nPhysPage = rData.GetPagesToPrint()[i];
1539                 aTmpPagesToPrint.push_back( nPhysPage );
1540                 aTmpPostItStartFrames.push_back( NULL );
1541 
1542                 // add the post-it document pages to print, i.e those
1543                 // post-it pages that have the data for the above physical page
1544                 const std::vector< const SwPageFrm * > &rPostItFrames = aPhysPageToPostItFrames[ nPhysPage ];
1545                 const size_t nPostItFrames = rPostItFrames.size();
1546                 for (size_t k = 0;  k < nPostItFrames;  ++k)
1547                 {
1548                     aTmpPagesToPrint.push_back( 0 );
1549                     aTmpPostItStartFrames.push_back( rPostItFrames[k] );
1550                 }
1551             }
1552 
1553             // finally we need to assign those vectors to the resulting ones.
1554             // swapping the data should be more efficient than assigning since
1555             // we won't need the temporary vectors anymore
1556             rData.GetPagesToPrint().swap( aTmpPagesToPrint );
1557             rData.GetPostItStartFrames().swap( aTmpPostItStartFrames );
1558         }
1559     }
1560 }
1561 
1562 
1563 void SwDoc::CalculatePagePairsForProspectPrinting(
1564     const SwRootFrm& rLayout,
1565     /* out */ SwRenderData &rData,
1566     const SwPrintUIOptions &rOptions,
1567     sal_Int32 nDocPageCount )
1568 {
1569     std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays();
1570     std::set< sal_Int32 > &rValidPagesSet = rData.GetValidPagesSet();
1571     std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames();
1572     std::vector< std::pair< sal_Int32, sal_Int32 > > &rPagePairs = rData.GetPagePairsForProspectPrinting();
1573 
1574     rPagePairs.clear();
1575     rValidPagesSet.clear();
1576     rValidStartFrms.clear();
1577 
1578     rtl::OUString aPageRange = rOptions.getStringValue( "PageRange", rtl::OUString() );
1579     // PageContent :
1580     // 0 -> print all pages (default if aPageRange is empty)
1581     // 1 -> print range according to PageRange
1582     // 2 -> print selection
1583     const sal_Int64 nContent = rOptions.getIntValue( "PrintContent", 0 );
1584     if (0 == nContent)
1585     {
1586         // set page range to print to 'all pages'
1587         aPageRange = OUString::valueOf( (sal_Int32)1 );
1588         aPageRange += OUString::valueOf( (sal_Unicode)'-');
1589         aPageRange += OUString::valueOf( nDocPageCount );
1590     }
1591     StringRangeEnumerator aRange( aPageRange, 1, nDocPageCount, 0 );
1592 
1593     if ( aRange.size() <= 0)
1594         return;
1595 
1596     const SwPageFrm *pStPage  = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1597     sal_Int32 i = 0;
1598     for ( i = 1; pStPage && i < nDocPageCount; ++i )
1599         pStPage = (SwPageFrm*)pStPage->GetNext();
1600     if ( !pStPage )          // dann wars das
1601         return;
1602 
1603     // currently for prospect printing all pages are valid to be printed
1604     // thus we add them all to the respective map and set for later use
1605     sal_Int32 nPageNum = 0;
1606     const SwPageFrm *pPageFrm  = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1607     while( pPageFrm && nPageNum < nDocPageCount )
1608     {
1609         DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1610         ++nPageNum;
1611         rValidPagesSet.insert( nPageNum );
1612         rValidStartFrms[ nPageNum ] = pPageFrm;
1613         pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1614 
1615         rPrinterPaperTrays[ nPageNum ] = lcl_GetPaperBin( pStPage );
1616     }
1617     DBG_ASSERT( nPageNum == nDocPageCount, "unexpected number of pages" );
1618 
1619     // properties to take into account when calcualting the set of pages
1620     // Note: here bPrintLeftPages and bPrintRightPages refer to the (virtual) resulting pages
1621     //      of the prospect!
1622     bool bPrintLeftPages     = rOptions.IsPrintLeftPages();
1623     bool bPrintRightPages    = rOptions.IsPrintRightPages();
1624     bool bPrintProspectRTL = rOptions.getIntValue( "PrintProspectRTL",  0 ) ? true : false;
1625 
1626     // get pages for prospect printing according to the 'PageRange'
1627     // (duplicates and any order allowed!)
1628     std::vector< sal_Int32 > aPagesToPrint;
1629     StringRangeEnumerator::getRangesFromString(
1630             aPageRange, aPagesToPrint, 1, nDocPageCount, 0 );
1631 
1632     // now fill the vector for calculating the page pairs with the start frames
1633     // from the above obtained vector
1634     std::vector< const SwPageFrm * > aVec;
1635     for ( i = 0; i < sal_Int32(aPagesToPrint.size()); ++i)
1636     {
1637         const sal_Int32 nPage = aPagesToPrint[i];
1638         const SwPageFrm *pFrm = rValidStartFrms[ nPage ];
1639         aVec.push_back( pFrm );
1640     }
1641 
1642     // just one page is special ...
1643     if ( 1 == aVec.size() )
1644         aVec.insert( aVec.begin() + 1, 0 ); // insert a second empty page
1645     else
1646     {
1647         // now extend the number of pages to fit a multiple of 4
1648         // (4 'normal' pages are needed for a single prospect paper
1649         //  with back and front)
1650         while( aVec.size() & 3 )
1651             aVec.push_back( 0 );
1652     }
1653 
1654     // dann sorge mal dafuer, das alle Seiten in der richtigen
1655     // Reihenfolge stehen:
1656     sal_uInt16 nSPg = 0;
1657     sal_uInt32 nEPg = aVec.size();
1658     sal_uInt16 nStep = 1;
1659     if ( 0 == (nEPg & 1 ))      // ungerade gibt es nicht!
1660         --nEPg;
1661 
1662     if ( !bPrintLeftPages )
1663         ++nStep;
1664     else if ( !bPrintRightPages )
1665     {
1666         ++nStep;
1667         ++nSPg, --nEPg;
1668     }
1669 
1670     // the number of 'virtual' pages to be printed
1671     sal_Int32 nCntPage = (( nEPg - nSPg ) / ( 2 * nStep )) + 1;
1672 
1673     for ( sal_uInt16 nPrintCount = 0; nSPg < nEPg &&
1674             nPrintCount < nCntPage; ++nPrintCount )
1675     {
1676         pStPage = aVec[ nSPg ];
1677         const SwPageFrm* pNxtPage = nEPg < aVec.size() ? aVec[ nEPg ] : 0;
1678 
1679         short nRtlOfs = bPrintProspectRTL ? 1 : 0;
1680         if ( 0 == (( nSPg + nRtlOfs) & 1 ) )     // switch for odd number in LTR, even number in RTL
1681         {
1682             const SwPageFrm* pTmp = pStPage;
1683             pStPage = pNxtPage;
1684             pNxtPage = pTmp;
1685         }
1686 
1687         sal_Int32 nFirst = -1, nSecond = -1;
1688         for ( int nC = 0; nC < 2; ++nC )
1689         {
1690             sal_Int32 nPage = -1;
1691             if ( pStPage )
1692                 nPage = pStPage->GetPhyPageNum();
1693             if (nC == 0)
1694                 nFirst  = nPage;
1695             else
1696                 nSecond = nPage;
1697 
1698             pStPage = pNxtPage;
1699         }
1700         rPagePairs.push_back( std::pair< sal_Int32, sal_Int32 >(nFirst, nSecond) );
1701 
1702         nSPg = nSPg + nStep;
1703         nEPg = nEPg - nStep;
1704     }
1705     DBG_ASSERT( size_t(nCntPage) == rPagePairs.size(), "size mismatch for number of page pairs" );
1706 
1707     // luckily prospect printing does not make use of post-its so far,
1708     // thus we are done here.
1709 }
1710 
1711 /*************************************************************************
1712  *			  void UpdateDocStat( const SwDocStat& rStat );
1713  *************************************************************************/
1714 
1715 void SwDoc::UpdateDocStat( SwDocStat& rStat )
1716 {
1717 	if( rStat.bModified )
1718 	{
1719 		rStat.Reset();
1720 		rStat.nPara = 0;        // Default ist auf 1 !!
1721 		SwNode* pNd;
1722 
1723         for( sal_uLong i = GetNodes().Count(); i; )
1724         {
1725             switch( ( pNd = GetNodes()[ --i ])->GetNodeType() )
1726 			{
1727             case ND_TEXTNODE:
1728                 ((SwTxtNode*)pNd)->CountWords( rStat, 0, ((SwTxtNode*)pNd)->GetTxt().Len() );
1729                 break;
1730 			case ND_TABLENODE:		++rStat.nTbl;	break;
1731 			case ND_GRFNODE:		++rStat.nGrf;	break;
1732 			case ND_OLENODE:		++rStat.nOLE;	break;
1733 			case ND_SECTIONNODE:	break;
1734 			}
1735         }
1736 
1737         // #i93174#: notes contain paragraphs that are not nodes
1738         {
1739             SwFieldType * const pPostits( GetSysFldType(RES_POSTITFLD) );
1740             SwIterator<SwFmtFld,SwFieldType> aIter( *pPostits );
1741             for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld;  pFmtFld = aIter.Next() )
1742             {
1743                 if (pFmtFld->IsFldInDoc())
1744                 {
1745                     SwPostItField const * const pField(
1746                         static_cast<SwPostItField const*>(pFmtFld->GetField()));
1747                     rStat.nAllPara += pField->GetNumberOfParagraphs();
1748                 }
1749             }
1750         }
1751 
1752 		rStat.nPage 	= GetCurrentLayout() ? GetCurrentLayout()->GetPageNum() : 0;	//swmod 080218
1753 		rStat.bModified = sal_False;
1754 		SetDocStat( rStat );
1755 
1756 		com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aStat( rStat.nPage ? 7 : 6);
1757 		sal_Int32 n=0;
1758 		aStat[n].Name = ::rtl::OUString::createFromAscii("TableCount");
1759 		aStat[n++].Value <<= (sal_Int32)rStat.nTbl;
1760 		aStat[n].Name = ::rtl::OUString::createFromAscii("ImageCount");
1761 		aStat[n++].Value <<= (sal_Int32)rStat.nGrf;
1762 		aStat[n].Name = ::rtl::OUString::createFromAscii("ObjectCount");
1763 		aStat[n++].Value <<= (sal_Int32)rStat.nOLE;
1764 		if ( rStat.nPage )
1765 		{
1766 			aStat[n].Name = ::rtl::OUString::createFromAscii("PageCount");
1767 			aStat[n++].Value <<= (sal_Int32)rStat.nPage;
1768 		}
1769 		aStat[n].Name = ::rtl::OUString::createFromAscii("ParagraphCount");
1770 		aStat[n++].Value <<= (sal_Int32)rStat.nPara;
1771 		aStat[n].Name = ::rtl::OUString::createFromAscii("WordCount");
1772 		aStat[n++].Value <<= (sal_Int32)rStat.nWord;
1773 		aStat[n].Name = ::rtl::OUString::createFromAscii("CharacterCount");
1774 		aStat[n++].Value <<= (sal_Int32)rStat.nChar;
1775 
1776 		// For e.g. autotext documents there is no pSwgInfo (#i79945)
1777         SfxObjectShell * const pObjShell( GetDocShell() );
1778         if (pObjShell)
1779         {
1780             const uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1781                 pObjShell->GetModel(), uno::UNO_QUERY_THROW);
1782             const uno::Reference<document::XDocumentProperties> xDocProps(
1783                 xDPS->getDocumentProperties());
1784             // #i96786#: do not set modified flag when updating statistics
1785             const bool bDocWasModified( IsModified() );
1786             const ModifyBlocker_Impl b(pObjShell);
1787             xDocProps->setDocumentStatistics(aStat);
1788             if (!bDocWasModified)
1789             {
1790                 ResetModified();
1791             }
1792         }
1793 
1794 		// event. Stat. Felder Updaten
1795 		SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD);
1796 		pType->UpdateFlds();
1797 	}
1798 }
1799 
1800 
1801 // Dokument - Info
1802 
1803 void SwDoc::DocInfoChgd( )
1804 {
1805 	GetSysFldType( RES_DOCINFOFLD )->UpdateFlds();
1806 	GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds();
1807 	SetModified();
1808 }
1809 
1810 	// returne zum Namen die im Doc gesetzte Referenz
1811 const SwFmtRefMark* SwDoc::GetRefMark( const String& rName ) const
1812 {
1813 	const SfxPoolItem* pItem;
1814 	sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
1815 	for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1816 	{
1817 		if( 0 == (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n ) ))
1818 			continue;
1819 
1820 		const SwFmtRefMark* pFmtRef = (SwFmtRefMark*)pItem;
1821 		const SwTxtRefMark* pTxtRef = pFmtRef->GetTxtRefMark();
1822 		if( pTxtRef && &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() &&
1823 			rName.Equals( pFmtRef->GetRefName() ) )
1824 			return pFmtRef;
1825 	}
1826 	return 0;
1827 }
1828 
1829 	// returne die RefMark per Index - fuer Uno
1830 const SwFmtRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const
1831 {
1832 	const SfxPoolItem* pItem;
1833 	const SwTxtRefMark* pTxtRef;
1834 	const SwFmtRefMark* pRet = 0;
1835 
1836 	sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
1837 	sal_uInt32 nCount = 0;
1838 	for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1839 		if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) &&
1840 			0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) &&
1841 			&pTxtRef->GetTxtNode().GetNodes() == &GetNodes() )
1842 		{
1843 			if(nCount == nIndex)
1844 			{
1845 				pRet = (SwFmtRefMark*)pItem;
1846 				break;
1847 			}
1848 			nCount++;
1849 		}
1850    return pRet;
1851 }
1852 
1853 	// returne die Namen aller im Doc gesetzten Referenzen
1854 	//JP 24.06.96: Ist der ArrayPointer 0 dann returne nur, ob im Doc. eine
1855 	//				RefMark gesetzt ist
1856 	// OS 25.06.96: ab jetzt wird immer die Anzahl der Referenzen returnt
1857 sal_uInt16 SwDoc::GetRefMarks( SvStringsDtor* pNames ) const
1858 {
1859     const SfxPoolItem* pItem;
1860     const SwTxtRefMark* pTxtRef;
1861 
1862     const sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
1863     sal_uInt16 nCount = 0;
1864     for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1865         if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) &&
1866             0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) &&
1867             &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() )
1868         {
1869             if( pNames )
1870             {
1871                 String* pTmp = new String( ((SwFmtRefMark*)pItem)->GetRefName() );
1872                 pNames->Insert( pTmp, nCount );
1873             }
1874             ++nCount;
1875         }
1876 
1877     return nCount;
1878 }
1879 
1880 bool SwDoc::IsLoaded() const
1881 {
1882 	return mbLoaded;
1883 }
1884 
1885 bool SwDoc::IsUpdateExpFld() const
1886 {
1887 	return mbUpdateExpFld;
1888 }
1889 
1890 bool SwDoc::IsNewDoc() const
1891 {
1892 	return mbNewDoc;
1893 }
1894 
1895 bool SwDoc::IsPageNums() const
1896 {
1897   return mbPageNums;
1898 }
1899 
1900 void SwDoc::SetPageNums(bool b)
1901 {
1902 	mbPageNums = b;
1903 }
1904 
1905 void SwDoc::SetNewDoc(bool b)
1906 {
1907 	mbNewDoc = b;
1908 }
1909 
1910 void SwDoc::SetUpdateExpFldStat(bool b)
1911 {
1912 	mbUpdateExpFld = b;
1913 }
1914 
1915 void SwDoc::SetLoaded(bool b)
1916 {
1917 	mbLoaded = b;
1918 }
1919 
1920 bool SwDoc::IsModified() const
1921 {
1922 	return mbModified;
1923 }
1924 
1925 void SwDoc::SetModified()
1926 {
1927     // --> OD 2005-08-29 #125370#
1928     SwLayouter::ClearMovedFwdFrms( *this );
1929     SwLayouter::ClearObjsTmpConsiderWrapInfluence( *this );
1930     SwLayouter::ClearFrmsNotToWrap( *this );
1931     // <--
1932     // --> OD 2006-05-10 #i65250#
1933     SwLayouter::ClearMoveBwdLayoutInfo( *this );
1934     // <--
1935 	// dem Link wird der Status returnt, wie die Flags waren und werden
1936 	// 	Bit 0:	-> alter Zustand
1937 	//	Bit 1: 	-> neuer Zustand
1938 	long nCall = mbModified ? 3 : 2;
1939 	mbModified = sal_True;
1940 	pDocStat->bModified = sal_True;
1941 	if( aOle2Link.IsSet() )
1942 	{
1943 		mbInCallModified = sal_True;
1944 		aOle2Link.Call( (void*)nCall );
1945 		mbInCallModified = sal_False;
1946 	}
1947 
1948 	if( pACEWord && !pACEWord->IsDeleted() )
1949 		delete pACEWord, pACEWord = 0;
1950 }
1951 
1952 void SwDoc::ResetModified()
1953 {
1954 	// dem Link wird der Status returnt, wie die Flags waren und werden
1955 	// 	Bit 0:	-> alter Zustand
1956 	//	Bit 1: 	-> neuer Zustand
1957     long nCall = mbModified ? 1 : 0;
1958 	mbModified = sal_False;
1959     // If there is already a document statistic, we assume that
1960     // it is correct. In this case we reset the modified flag.
1961     if ( 0 != pDocStat->nChar )
1962         pDocStat->bModified = sal_False;
1963     GetIDocumentUndoRedo().SetUndoNoModifiedPosition();
1964 	if( nCall && aOle2Link.IsSet() )
1965 	{
1966 		mbInCallModified = sal_True;
1967 		aOle2Link.Call( (void*)nCall );
1968 		mbInCallModified = sal_False;
1969 	}
1970 }
1971 
1972 
1973 void SwDoc::ReRead( SwPaM& rPam, const String& rGrfName,
1974 					const String& rFltName, const Graphic* pGraphic,
1975 					const GraphicObject* pGrafObj )
1976 {
1977 	SwGrfNode *pGrfNd;
1978 	if( ( !rPam.HasMark()
1979 		 || rPam.GetPoint()->nNode.GetIndex() == rPam.GetMark()->nNode.GetIndex() )
1980 		 && 0 != ( pGrfNd = rPam.GetPoint()->nNode.GetNode().GetGrfNode() ) )
1981     {
1982         if (GetIDocumentUndoRedo().DoesUndo())
1983         {
1984             GetIDocumentUndoRedo().AppendUndo(new SwUndoReRead(rPam, *pGrfNd));
1985         }
1986 
1987 		// Weil nicht bekannt ist, ob sich die Grafik spiegeln laesst,
1988 		// immer das SpiegelungsAttribut zuruecksetzen
1989         if( RES_MIRROR_GRAPH_DONT != pGrfNd->GetSwAttrSet().
1990 												GetMirrorGrf().GetValue() )
1991 			pGrfNd->SetAttr( SwMirrorGrf() );
1992 
1993 		pGrfNd->ReRead( rGrfName, rFltName, pGraphic, pGrafObj, sal_True );
1994 		SetModified();
1995 	}
1996 }
1997 
1998 sal_Bool lcl_SpellAndGrammarAgain( const SwNodePtr& rpNd, void* pArgs )
1999 {
2000 	SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
2001 	sal_Bool bOnlyWrong = *(sal_Bool*)pArgs;
2002 	if( pTxtNode )
2003 	{
2004 		if( bOnlyWrong )
2005 		{
2006 			if( pTxtNode->GetWrong() &&
2007 				pTxtNode->GetWrong()->InvalidateWrong() )
2008                 pTxtNode->SetWrongDirty( true );
2009             if( pTxtNode->GetGrammarCheck() &&
2010                 pTxtNode->GetGrammarCheck()->InvalidateWrong() )
2011                 pTxtNode->SetGrammarCheckDirty( true );
2012 		}
2013 		else
2014 		{
2015             pTxtNode->SetWrongDirty( true );
2016 			if( pTxtNode->GetWrong() )
2017 				pTxtNode->GetWrong()->SetInvalid( 0, STRING_LEN );
2018             pTxtNode->SetGrammarCheckDirty( true );
2019             if( pTxtNode->GetGrammarCheck() )
2020                 pTxtNode->GetGrammarCheck()->SetInvalid( 0, STRING_LEN );
2021 		}
2022 	}
2023 	return sal_True;
2024 }
2025 
2026 sal_Bool lcl_CheckSmartTagsAgain( const SwNodePtr& rpNd, void*  )
2027 {
2028 	SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
2029 //	sal_Bool bOnlyWrong = *(sal_Bool*)pArgs;
2030 	if( pTxtNode )
2031 	{
2032         pTxtNode->SetSmartTagDirty( true );
2033         if( pTxtNode->GetSmartTags() )
2034         {
2035 //            if ( bOnlyWrong ) // only some smart tag types have been enabled or disabled
2036 //				pTxtNode->GetSmartTags()->SetInvalid( 0, STRING_LEN );
2037 //            else // smart tags all have been enabled or disabled
2038 				pTxtNode->SetSmartTags( NULL );
2039         }
2040 	}
2041 	return sal_True;
2042 }
2043 
2044 
2045 /*************************************************************************
2046  * 		SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong )
2047  *
2048  * stoesst das Spelling im Idle-Handler wieder an.
2049  * Wird bInvalid als sal_True uebergeben, so werden zusaetzlich die WrongListen
2050  * an allen Nodes invalidiert und auf allen Seiten das SpellInvalid-Flag
2051  * gesetzt.
2052  * Mit bOnlyWrong kann man dann steuern, ob nur die Bereiche mit falschen
2053  * Woertern oder die kompletten Bereiche neu ueberprueft werden muessen.
2054  ************************************************************************/
2055 
2056 void SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong, sal_Bool bSmartTags )
2057 {
2058 	std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080307
2059 	ASSERT( GetCurrentLayout(), "SpellAgain: Where's my RootFrm?" );
2060 	if( bInvalid )
2061 	{
2062 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::AllInvalidateSmartTagsOrSpelling),bSmartTags));//swmod 080305
2063 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::SetNeedGrammarCheck), true) );
2064     	if ( bSmartTags )
2065             GetNodes().ForEach( lcl_CheckSmartTagsAgain, &bOnlyWrong );
2066         GetNodes().ForEach( lcl_SpellAndGrammarAgain, &bOnlyWrong );
2067 	}
2068 
2069 	std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080307
2070 }
2071 
2072 void SwDoc::InvalidateAutoCompleteFlag()
2073 {
2074 	SwRootFrm* pTmpRoot = GetCurrentLayout();
2075 	if( pTmpRoot )
2076 	{
2077 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
2078 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllInvalidateAutoCompleteWords));//swmod 080305
2079 		for( sal_uLong nNd = 1, nCnt = GetNodes().Count(); nNd < nCnt; ++nNd )
2080         {
2081             SwTxtNode* pTxtNode = GetNodes()[ nNd ]->GetTxtNode();
2082             if ( pTxtNode ) pTxtNode->SetAutoCompleteWordDirty( true );
2083         }
2084 
2085 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080228
2086 	}	//swmod 080219
2087 }
2088 
2089 const SwFmtINetFmt* SwDoc::FindINetAttr( const String& rName ) const
2090 {
2091 	const SwFmtINetFmt* pItem;
2092 	const SwTxtINetFmt* pTxtAttr;
2093 	const SwTxtNode* pTxtNd;
2094 	sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
2095 	for( n = 0; n < nMaxItems; ++n )
2096 		if( 0 != (pItem = (SwFmtINetFmt*)GetAttrPool().GetItem2(
2097 			RES_TXTATR_INETFMT, n ) ) &&
2098 			pItem->GetName().Equals( rName ) &&
2099 			0 != ( pTxtAttr = pItem->GetTxtINetFmt()) &&
2100 			0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
2101 			&pTxtNd->GetNodes() == &GetNodes() )
2102 		{
2103 			return pItem;
2104 		}
2105 
2106 	return 0;
2107 }
2108 
2109 void SwDoc::Summary( SwDoc* pExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, sal_Bool bImpress )
2110 {
2111 	const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds();
2112 	if( pExtDoc && rOutNds.Count() )
2113 	{
2114 		sal_uInt16 i;
2115 		::StartProgress( STR_STATSTR_SUMMARY, 0, rOutNds.Count(), GetDocShell() );
2116 		SwNodeIndex aEndOfDoc( pExtDoc->GetNodes().GetEndOfContent(), -1 );
2117 		for( i = 0; i < rOutNds.Count(); ++i )
2118 		{
2119 			::SetProgressState( i, GetDocShell() );
2120             const sal_uLong nIndex = rOutNds[ i ]->GetIndex();
2121 			//sal_uInt8 nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetTxtColl()//#outline level,zhaojianwei
2122 						// ->GetOutlineLevel();
2123             const int nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetAttrOutlineLevel()-1;//<-end,zhaojianwei
2124 			if( nLvl > nLevel )
2125 				continue;
2126 			sal_uInt16 nEndOfs = 1;
2127 			sal_uInt8 nWish = nPara;
2128 			sal_uLong nNextOutNd = i + 1 < rOutNds.Count() ?
2129 				rOutNds[ i + 1 ]->GetIndex() : GetNodes().Count();
2130 			sal_Bool bKeep = sal_False;
2131 			while( ( nWish || bKeep ) && nIndex + nEndOfs < nNextOutNd &&
2132 				   GetNodes()[ nIndex + nEndOfs ]->IsTxtNode() )
2133 			{
2134 				SwTxtNode* pTxtNode = (SwTxtNode*)GetNodes()[ nIndex+nEndOfs ];
2135 				if( pTxtNode->GetTxt().Len() && nWish )
2136 					--nWish;
2137 				bKeep = pTxtNode->GetSwAttrSet().GetKeep().GetValue();
2138 				++nEndOfs;
2139 			}
2140 
2141 			SwNodeRange aRange( *rOutNds[ i ], 0, *rOutNds[ i ], nEndOfs );
2142 			GetNodes()._Copy( aRange, aEndOfDoc );
2143 		}
2144 		const SwTxtFmtColls *pColl = pExtDoc->GetTxtFmtColls();
2145 		for( i = 0; i < pColl->Count(); ++i )
2146             (*pColl)[ i ]->ResetFmtAttr( RES_PAGEDESC, RES_BREAK );
2147 		SwNodeIndex aIndx( pExtDoc->GetNodes().GetEndOfExtras() );
2148 		++aEndOfDoc;
2149 		while( aIndx < aEndOfDoc )
2150 		{
2151 			SwNode *pNode;
2152 			sal_Bool bDelete = sal_False;
2153 			if(	(pNode = &aIndx.GetNode())->IsTxtNode() )
2154 			{
2155 				SwTxtNode *pNd = (SwTxtNode*)pNode;
2156 				if( pNd->HasSwAttrSet() )
2157 					pNd->ResetAttr( RES_PAGEDESC, RES_BREAK );
2158 				if( bImpress )
2159 				{
2160 					SwTxtFmtColl* pMyColl = pNd->GetTxtColl();
2161 					//sal_uInt16 nHeadLine = static_cast<sal_uInt16>(pMyColl->GetOutlineLevel()==NO_NUMBERING ?//#outlinelevel,zhaojianwei
2162                     const sal_uInt16 nHeadLine = static_cast<sal_uInt16>(
2163                                 !pMyColl->IsAssignedToListLevelOfOutlineStyle() //<-end,zhaojianwei
2164                                 ? RES_POOLCOLL_HEADLINE2
2165                                 : RES_POOLCOLL_HEADLINE1 );
2166 					pMyColl = pExtDoc->GetTxtCollFromPool( nHeadLine );
2167 					pNd->ChgFmtColl( pMyColl );
2168 				}
2169 				if( !pNd->Len() &&
2170 					pNd->StartOfSectionIndex()+2 < pNd->EndOfSectionIndex() )
2171 				{
2172 					bDelete = sal_True;
2173 					pExtDoc->GetNodes().Delete( aIndx );
2174 				}
2175 			}
2176 			if( !bDelete )
2177 				++aIndx;
2178 		}
2179 		::EndProgress( GetDocShell() );
2180 	}
2181 }
2182 
2183 	// loesche den nicht sichtbaren Content aus dem Document, wie z.B.:
2184 	// versteckte Bereiche, versteckte Absaetze
2185 bool SwDoc::RemoveInvisibleContent()
2186 {
2187 	sal_Bool bRet = sal_False;
2188     GetIDocumentUndoRedo().StartUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL );
2189 
2190 	{
2191 		SwTxtNode* pTxtNd;
2192         SwIterator<SwFmtFld,SwFieldType> aIter( *GetSysFldType( RES_HIDDENPARAFLD )  );
2193         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld;  pFmtFld = aIter.Next() )
2194         {
2195 			if( pFmtFld->GetTxtFld() &&
2196 				0 != ( pTxtNd = (SwTxtNode*)pFmtFld->GetTxtFld()->GetpTxtNode() ) &&
2197                 pTxtNd->GetpSwpHints() && pTxtNd->HasHiddenParaField() &&
2198 				&pTxtNd->GetNodes() == &GetNodes() )
2199 			{
2200 				bRet = sal_True;
2201                 SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2202 
2203                 // Remove hidden paragraph or delete contents:
2204                 // Delete contents if
2205                 // 1. removing the paragraph would result in an empty section or
2206                 // 2. if the paragraph is the last paragraph in the section and
2207                 //    there is no paragraph in front of the paragraph:
2208                 if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) ||
2209                      ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() &&
2210                        !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) )
2211                 {
2212                     DeleteRange( aPam );
2213                 }
2214                 else
2215                 {
2216                     aPam.DeleteMark();
2217                     DelFullPara( aPam );
2218                 }
2219             }
2220         }
2221 	}
2222 
2223     //
2224     // Remove any hidden paragraph (hidden text attribute)
2225     //
2226     for( sal_uLong n = GetNodes().Count(); n; )
2227     {
2228         SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode();
2229         if ( pTxtNd )
2230         {
2231             bool bRemoved = false;
2232             SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2233             if ( pTxtNd->HasHiddenCharAttribute( true ) )
2234             {
2235                 bRemoved = sal_True;
2236                 bRet = sal_True;
2237 
2238                 // Remove hidden paragraph or delete contents:
2239                 // Delete contents if
2240                 // 1. removing the paragraph would result in an empty section or
2241                 // 2. if the paragraph is the last paragraph in the section and
2242                 //    there is no paragraph in front of the paragraph:
2243 
2244                 if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) ||
2245                      ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() &&
2246                        !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) )
2247                 {
2248                     DeleteRange( aPam );
2249                 }
2250                 else
2251                 {
2252                     aPam.DeleteMark();
2253 					DelFullPara( aPam );
2254 				}
2255             }
2256             else if ( pTxtNd->HasHiddenCharAttribute( false ) )
2257             {
2258                 bRemoved = sal_True;
2259                 bRet = sal_True;
2260                 SwScriptInfo::DeleteHiddenRanges( *pTxtNd );
2261             }
2262 
2263             // --> FME 2006-01-11 #120473#
2264             // Footnotes/Frames may have been removed, therefore we have
2265             // to reset n:
2266             if ( bRemoved )
2267                 n = aPam.GetPoint()->nNode.GetIndex();
2268             // <--
2269         }
2270     }
2271 
2272 	{
2273 		// dann noch alle versteckten Bereiche loeschen/leeren
2274 		SwSectionFmts aSectFmts;
2275 		SwSectionFmts& rSectFmts = GetSections();
2276 		sal_uInt16 n;
2277 
2278 		for( n = rSectFmts.Count(); n; )
2279 		{
2280 			SwSectionFmt* pSectFmt = rSectFmts[ --n ];
2281 		    // don't add sections in Undo/Redo
2282             if( !pSectFmt->IsInNodesArr())
2283                 continue;
2284 			SwSection* pSect = pSectFmt->GetSection();
2285 			if( pSect->CalcHiddenFlag() )
2286 			{
2287 				SwSection* pParent = pSect, *pTmp;
2288 				while( 0 != (pTmp = pParent->GetParent() ))
2289 				{
2290 					if( pTmp->IsHiddenFlag() )
2291 						pSect = pTmp;
2292 					pParent = pTmp;
2293 				}
2294 
2295 				if( USHRT_MAX == aSectFmts.GetPos( pSect->GetFmt() ) )
2296 					aSectFmts.Insert( pSect->GetFmt(), 0 );
2297 			}
2298 			if( pSect->GetCondition().Len() )
2299             {
2300                 SwSectionData aSectionData( *pSect );
2301                 aSectionData.SetCondition( aEmptyStr );
2302                 aSectionData.SetHidden( false );
2303                 UpdateSection( n, aSectionData );
2304             }
2305         }
2306 
2307 		if( 0 != ( n = aSectFmts.Count() ))
2308 		{
2309 			while( n )
2310 			{
2311 				SwSectionFmt* pSectFmt = aSectFmts[ --n ];
2312 				SwSectionNode* pSectNd = pSectFmt->GetSectionNode();
2313 				if( pSectNd )
2314 				{
2315 					bRet = sal_True;
2316 					SwPaM aPam( *pSectNd );
2317 
2318                     if( pSectNd->StartOfSectionNode()->StartOfSectionIndex() ==
2319 						pSectNd->GetIndex() - 1 &&
2320                         pSectNd->StartOfSectionNode()->EndOfSectionIndex() ==
2321 						pSectNd->EndOfSectionIndex() + 1 )
2322 					{
2323 						// nur den Inhalt loeschen
2324 						SwCntntNode* pCNd = GetNodes().GoNext(
2325 												&aPam.GetPoint()->nNode );
2326 						aPam.GetPoint()->nContent.Assign( pCNd, 0 );
2327 						aPam.SetMark();
2328 						aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode();
2329 						pCNd = GetNodes().GoPrevious(
2330 												&aPam.GetPoint()->nNode );
2331 						aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
2332 
2333                         DeleteRange( aPam );
2334                     }
2335 					else
2336 					{
2337 						// die gesamte Section loeschen
2338 						aPam.SetMark();
2339 						aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode();
2340 						DelFullPara( aPam );
2341 					}
2342 
2343 				}
2344 			}
2345 			aSectFmts.Remove( 0, aSectFmts.Count() );
2346 		}
2347 	}
2348 
2349 	if( bRet )
2350 		SetModified();
2351     GetIDocumentUndoRedo().EndUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL );
2352 	return bRet;
2353 }
2354 /*-- 25.08.2010 14:18:12---------------------------------------------------
2355 
2356   -----------------------------------------------------------------------*/
2357 bool SwDoc::HasInvisibleContent() const
2358 {
2359     sal_Bool bRet = sal_False;
2360 
2361     SwClientIter aIter( *GetSysFldType( RES_HIDDENPARAFLD ) );
2362     if( aIter.First( TYPE( SwFmtFld ) ) )
2363         bRet = sal_True;
2364 
2365     //
2366     // Search for any hidden paragraph (hidden text attribute)
2367     //
2368     if( ! bRet )
2369     {
2370         for( sal_uLong n = GetNodes().Count(); !bRet && (n > 0); )
2371         {
2372             SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode();
2373             if ( pTxtNd )
2374             {
2375                 SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2376                 if( pTxtNd->HasHiddenCharAttribute( true ) ||  ( pTxtNd->HasHiddenCharAttribute( false ) ) )
2377                 {
2378                     bRet = sal_True;
2379                 }
2380             }
2381         }
2382     }
2383 
2384     if( ! bRet )
2385     {
2386         const SwSectionFmts& rSectFmts = GetSections();
2387         sal_uInt16 n;
2388 
2389         for( n = rSectFmts.Count(); !bRet && (n > 0); )
2390         {
2391             SwSectionFmt* pSectFmt = rSectFmts[ --n ];
2392             // don't add sections in Undo/Redo
2393             if( !pSectFmt->IsInNodesArr())
2394                 continue;
2395             SwSection* pSect = pSectFmt->GetSection();
2396             if( pSect->IsHidden() )
2397                 bRet = sal_True;
2398         }
2399     }
2400     return bRet;
2401 }
2402 
2403 bool SwDoc::RestoreInvisibleContent()
2404 {
2405     bool bRet = false;
2406     SwUndoId nLastUndoId(UNDO_EMPTY);
2407     if (GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId)
2408         && (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId))
2409     {
2410         GetIDocumentUndoRedo().Undo();
2411         GetIDocumentUndoRedo().ClearRedo();
2412         bRet = true;
2413     }
2414     return bRet;
2415 }
2416 
2417 /*-- 11.06.2004 08:34:04---------------------------------------------------
2418 
2419   -----------------------------------------------------------------------*/
2420 sal_Bool SwDoc::ConvertFieldsToText()
2421 {
2422     sal_Bool bRet = sal_False;
2423     LockExpFlds();
2424     GetIDocumentUndoRedo().StartUndo( UNDO_UI_REPLACE, NULL );
2425 
2426     const SwFldTypes* pMyFldTypes = GetFldTypes();
2427     sal_uInt16 nCount = pMyFldTypes->Count();
2428     //go backward, field types are removed
2429     for(sal_uInt16 nType = nCount;  nType > 0;  --nType)
2430     {
2431         const SwFieldType *pCurType = pMyFldTypes->GetObject(nType - 1);
2432 
2433         if ( RES_POSTITFLD == pCurType->Which() )
2434             continue;
2435 
2436         SwIterator<SwFmtFld,SwFieldType> aIter( *pCurType );
2437         ::std::vector<const SwFmtFld*> aFieldFmts;
2438         for( SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next() )
2439             aFieldFmts.push_back(pCurFldFmt);
2440 
2441         ::std::vector<const SwFmtFld*>::iterator aBegin = aFieldFmts.begin();
2442         ::std::vector<const SwFmtFld*>::iterator aEnd = aFieldFmts.end();
2443         while(aBegin != aEnd)
2444         {
2445             const SwTxtFld *pTxtFld = (*aBegin)->GetTxtFld();
2446             // skip fields that are currently not in the document
2447             // e.g. fields in undo or redo array
2448 
2449             sal_Bool bSkip = !pTxtFld ||
2450                          !pTxtFld->GetpTxtNode()->GetNodes().IsDocNodes();
2451 
2452             if (!bSkip)
2453             {
2454                 sal_Bool bInHeaderFooter = IsInHeaderFooter(SwNodeIndex(*pTxtFld->GetpTxtNode()));
2455                 const SwFmtFld& rFmtFld = pTxtFld->GetFmtFld();
2456                 const SwField*  pField = rFmtFld.GetField();
2457 
2458                 //#i55595# some fields have to be excluded in headers/footers
2459                 sal_uInt16 nWhich = pField->GetTyp()->Which();
2460                 if(!bInHeaderFooter ||
2461                         (nWhich != RES_PAGENUMBERFLD &&
2462                         nWhich != RES_CHAPTERFLD &&
2463                         nWhich != RES_GETEXPFLD&&
2464                         nWhich != RES_SETEXPFLD&&
2465                         nWhich != RES_INPUTFLD&&
2466                         nWhich != RES_REFPAGEGETFLD&&
2467                         nWhich != RES_REFPAGESETFLD))
2468                 {
2469                     String sText = pField->ExpandField(true);
2470                     //database fields should not convert their command into text
2471                     if( RES_DBFLD == pCurType->Which() && !static_cast<const SwDBField*>(pField)->IsInitialized())
2472                         sText.Erase();
2473 
2474                     //now remove the field and insert the string
2475                     SwPaM aPam1(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart());
2476                     aPam1.Move();
2477                     //insert first to keep the field's attributes
2478                     InsertString( aPam1, sText );
2479                     SwPaM aPam2(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart());
2480                     aPam2.SetMark();
2481                     aPam2.Move();
2482                     DeleteAndJoin(aPam2);//remove the field
2483                 }
2484             }
2485             ++aBegin;
2486         }
2487     }
2488 
2489     if( bRet )
2490         SetModified();
2491     GetIDocumentUndoRedo().EndUndo( UNDO_UI_REPLACE, NULL );
2492     UnlockExpFlds();
2493     return bRet;
2494 
2495 }
2496 
2497 bool SwDoc::IsVisibleLinks() const
2498 {
2499     return mbVisibleLinks;
2500 }
2501 
2502 void SwDoc::SetVisibleLinks(bool bFlag)
2503 {
2504     mbVisibleLinks = bFlag;
2505 }
2506 
2507 sfx2::LinkManager& SwDoc::GetLinkManager()
2508 {
2509     return *pLinkMgr;
2510 }
2511 
2512 const sfx2::LinkManager& SwDoc::GetLinkManager() const
2513 {
2514     return *pLinkMgr;
2515 }
2516 
2517 void SwDoc::SetLinksUpdated(const bool bNewLinksUpdated)
2518 {
2519     mbLinksUpdated = bNewLinksUpdated;
2520 }
2521 
2522 bool SwDoc::LinksUpdated() const
2523 {
2524     return mbLinksUpdated;
2525 }
2526 
2527 	// embedded alle lokalen Links (Bereiche/Grafiken)
2528 ::sfx2::SvBaseLink* lcl_FindNextRemovableLink( const ::sfx2::SvBaseLinks& rLinks, sfx2::LinkManager& rLnkMgr )
2529 {
2530     for( sal_uInt16 n = 0; n < rLinks.Count(); ++n )
2531     {
2532         ::sfx2::SvBaseLink* pLnk = &(*rLinks[ n ]);
2533         if( pLnk &&
2534             ( OBJECT_CLIENT_GRF == pLnk->GetObjType() ||
2535               OBJECT_CLIENT_FILE == pLnk->GetObjType() ) &&
2536             pLnk->ISA( SwBaseLink ) )
2537         {
2538                 ::sfx2::SvBaseLinkRef xLink = pLnk;
2539 
2540                 String sFName;
2541                 rLnkMgr.GetDisplayNames( xLink, 0, &sFName, 0, 0 );
2542 
2543                 INetURLObject aURL( sFName );
2544                 if( INET_PROT_FILE == aURL.GetProtocol() ||
2545                     INET_PROT_CID == aURL.GetProtocol() )
2546                     return pLnk;
2547         }
2548     }
2549     return 0;
2550 }
2551 bool SwDoc::EmbedAllLinks()
2552 {
2553 	sal_Bool bRet = sal_False;
2554 	sfx2::LinkManager& rLnkMgr = GetLinkManager();
2555     const ::sfx2::SvBaseLinks& rLinks = rLnkMgr.GetLinks();
2556     if( rLinks.Count() )
2557 	{
2558         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2559 
2560         ::sfx2::SvBaseLink* pLnk = 0;
2561         while( 0 != (pLnk = lcl_FindNextRemovableLink( rLinks, rLnkMgr ) ) )
2562 		{
2563             ::sfx2::SvBaseLinkRef xLink = pLnk;
2564             // dem Link sagen, das er aufgeloest wird!
2565             xLink->Closed();
2566 
2567             // falls einer vergessen hat sich auszutragen
2568             if( xLink.Is() )
2569                 rLnkMgr.Remove( xLink );
2570 
2571             bRet = sal_True;
2572 		}
2573 
2574         GetIDocumentUndoRedo().DelAllUndoObj();
2575 		SetModified();
2576 	}
2577 	return bRet;
2578 }
2579 
2580 /*--------------------------------------------------------------------
2581 	Beschreibung:
2582  --------------------------------------------------------------------*/
2583 
2584 sal_Bool SwDoc::IsInsTblFormatNum() const
2585 {
2586 	return SW_MOD()->IsInsTblFormatNum(get(IDocumentSettingAccess::HTML_MODE));
2587 }
2588 
2589 sal_Bool SwDoc::IsInsTblChangeNumFormat() const
2590 {
2591 	return SW_MOD()->IsInsTblChangeNumFormat(get(IDocumentSettingAccess::HTML_MODE));
2592 }
2593 
2594 /*--------------------------------------------------------------------
2595 	Beschreibung:
2596  --------------------------------------------------------------------*/
2597 
2598 sal_Bool SwDoc::IsInsTblAlignNum() const
2599 {
2600 	return SW_MOD()->IsInsTblAlignNum(get(IDocumentSettingAccess::HTML_MODE));
2601 }
2602 
2603         // setze das InsertDB als Tabelle Undo auf:
2604 void SwDoc::AppendUndoForInsertFromDB( const SwPaM& rPam, sal_Bool bIsTable )
2605 {
2606 	if( bIsTable )
2607 	{
2608 		const SwTableNode* pTblNd = rPam.GetPoint()->nNode.GetNode().FindTableNode();
2609 		if( pTblNd )
2610 		{
2611 			SwUndoCpyTbl* pUndo = new SwUndoCpyTbl;
2612 			pUndo->SetTableSttIdx( pTblNd->GetIndex() );
2613             GetIDocumentUndoRedo().AppendUndo( pUndo );
2614         }
2615     }
2616 	else if( rPam.HasMark() )
2617 	{
2618 		SwUndoCpyDoc* pUndo = new SwUndoCpyDoc( rPam );
2619 		pUndo->SetInsertRange( rPam, sal_False );
2620         GetIDocumentUndoRedo().AppendUndo( pUndo );
2621     }
2622 }
2623 
2624 void SwDoc::ChgTOX(SwTOXBase & rTOX, const SwTOXBase & rNew)
2625 {
2626     if (GetIDocumentUndoRedo().DoesUndo())
2627     {
2628         GetIDocumentUndoRedo().DelAllUndoObj();
2629 
2630         SwUndo * pUndo = new SwUndoTOXChange(&rTOX, rNew);
2631 
2632         GetIDocumentUndoRedo().AppendUndo(pUndo);
2633     }
2634 
2635     rTOX = rNew;
2636 
2637     if (rTOX.ISA(SwTOXBaseSection))
2638     {
2639         static_cast<SwTOXBaseSection &>(rTOX).Update();
2640         static_cast<SwTOXBaseSection &>(rTOX).UpdatePageNum();
2641     }
2642 }
2643 
2644 // #111827#
2645 String SwDoc::GetPaMDescr(const SwPaM & rPam) const
2646 {
2647     String aResult;
2648     bool bOK = false;
2649 
2650     if (rPam.GetNode(sal_True) == rPam.GetNode(sal_False))
2651     {
2652         SwTxtNode * pTxtNode = rPam.GetNode(sal_True)->GetTxtNode();
2653 
2654         if (0 != pTxtNode)
2655         {
2656             xub_StrLen nStart = rPam.Start()->nContent.GetIndex();
2657             xub_StrLen nEnd = rPam.End()->nContent.GetIndex();
2658 
2659             aResult += String(SW_RES(STR_START_QUOTE));
2660             aResult += ShortenString(pTxtNode->GetTxt().
2661                                      Copy(nStart, nEnd - nStart),
2662                                      nUndoStringLength,
2663                                      String(SW_RES(STR_LDOTS)));
2664             aResult += String(SW_RES(STR_END_QUOTE));
2665 
2666             bOK = true;
2667         }
2668     }
2669     else if (0 != rPam.GetNode(sal_True))
2670     {
2671         if (0 != rPam.GetNode(sal_False))
2672             aResult += String(SW_RES(STR_PARAGRAPHS));
2673 
2674         bOK = true;
2675     }
2676 
2677     if (! bOK)
2678         aResult += String("??", RTL_TEXTENCODING_ASCII_US);
2679 
2680     return aResult;
2681 }
2682 
2683 SwField * SwDoc::GetFieldAtPos(const SwPosition & rPos)
2684 {
2685     SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
2686 
2687     return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
2688 }
2689 
2690 SwTxtFld * SwDoc::GetTxtFldAtPos(const SwPosition & rPos)
2691 {
2692     SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
2693 
2694     return (pNode != NULL)
2695         ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
2696         : 0;
2697 }
2698 
2699 bool SwDoc::ContainsHiddenChars() const
2700 {
2701     for( sal_uLong n = GetNodes().Count(); n; )
2702     {
2703         SwNode* pNd = GetNodes()[ --n ];
2704         if ( ND_TEXTNODE == pNd->GetNodeType() &&
2705              ((SwTxtNode*)pNd)->HasHiddenCharAttribute( false ) )
2706             return true;
2707     }
2708 
2709     return false;
2710 }
2711 
2712 SwUnoCrsr* SwDoc::CreateUnoCrsr( const SwPosition& rPos, sal_Bool bTblCrsr )
2713 {
2714 	SwUnoCrsr* pNew;
2715 	if( bTblCrsr )
2716 		pNew = new SwUnoTableCrsr( rPos );
2717 	else
2718 		pNew = new SwUnoCrsr( rPos );
2719 
2720 	pUnoCrsrTbl->Insert( pNew, pUnoCrsrTbl->Count() );
2721 	return pNew;
2722 }
2723 
2724 void SwDoc::ChkCondColls()
2725 {
2726      for (sal_uInt16 n = 0; n < pTxtFmtCollTbl->Count(); n++)
2727      {
2728         SwTxtFmtColl *pColl = (*pTxtFmtCollTbl)[n];
2729         if (RES_CONDTXTFMTCOLL == pColl->Which())
2730             pColl->CallSwClientNotify( SwAttrHint(RES_CONDTXTFMTCOLL) );
2731      }
2732 }
2733 
2734 #ifdef FUTURE_VBA
2735 uno::Reference< script::vba::XVBAEventProcessor >
2736 SwDoc::GetVbaEventProcessor()
2737 {
2738 	if( !mxVbaEvents.is() && pDocShell && ooo::vba::isAlienWordDoc( *pDocShell ) )
2739 	{
2740         try
2741         {
2742             uno::Reference< frame::XModel > xModel( pDocShell->GetModel(), uno::UNO_SET_THROW );
2743             uno::Sequence< uno::Any > aArgs(1);
2744             aArgs[0] <<= xModel;
2745             mxVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( pDocShell, "com.sun.star.script.vba.VBATextEventProcessor" , aArgs ), uno::UNO_QUERY_THROW );
2746         }
2747         catch( uno::Exception& )
2748         {
2749         }
2750 	}
2751 	return mxVbaEvents;
2752 }
2753 #endif
2754 
2755 void SwDoc::setExternalData(::sw::tExternalDataType eType,
2756                             ::sw::tExternalDataPointer pPayload)
2757 {
2758     m_externalData[eType] = pPayload;
2759 }
2760 
2761 ::sw::tExternalDataPointer SwDoc::getExternalData(::sw::tExternalDataType eType)
2762 {
2763     return m_externalData[eType];
2764 }
2765